/// Return the function name.
const StringRef &getName() const { return Name; }
+ /// Returns the line offset to the start line of the subprogram.
+ /// We assume that a single function will not exceed 65535 LOC.
+ static unsigned getOffset(const DILocation *DIL);
+
+ /// \brief Get the FunctionSamples of the inline instance where DIL originates
+ /// from.
+ ///
+ /// The FunctionSamples of the instruction (Machine or IR) associated to
+ /// \p DIL is the inlined instance in which that instruction is coming from.
+ /// We traverse the inline stack of that instruction, and match it with the
+ /// tree nodes in the profile.
+ ///
+ /// \param Inst Instruction to query.
+ ///
+ /// \returns the FunctionSamples pointer to the inlined instance.
+ const FunctionSamples *findFunctionSamples(const DILocation *DIL) const;
+
private:
/// Mangled name of the function.
StringRef Name;
//
//===----------------------------------------------------------------------===//
+#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/ProfileData/SampleProf.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
return OS;
}
+unsigned FunctionSamples::getOffset(const DILocation *DIL) {
+ return (DIL->getLine() - DIL->getScope()->getSubprogram()->getLine()) &
+ 0xffff;
+}
+
+const FunctionSamples *
+FunctionSamples::findFunctionSamples(const DILocation *DIL) const {
+ assert(DIL);
+ SmallVector<std::pair<LineLocation, StringRef>, 10> S;
+
+ const DILocation *PrevDIL = DIL;
+ for (DIL = DIL->getInlinedAt(); DIL; DIL = DIL->getInlinedAt()) {
+ S.push_back(std::make_pair(
+ LineLocation(getOffset(DIL), DIL->getBaseDiscriminator()),
+ PrevDIL->getScope()->getSubprogram()->getLinkageName()));
+ PrevDIL = DIL;
+ }
+ if (S.size() == 0)
+ return this;
+ const FunctionSamples *FS = this;
+ for (int i = S.size() - 1; i >= 0 && FS != nullptr; i--) {
+ FS = FS->findFunctionSamplesAt(S[i].first, S[i].second);
+ }
+ return FS;
+}
+
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
LLVM_DUMP_METHOD void FunctionSamples::dump() const { print(dbgs(), 0); }
#endif
void buildEdges(Function &F);
bool propagateThroughEdges(Function &F, bool UpdateBlockCount);
void computeDominanceAndLoopInfo(Function &F);
- unsigned getOffset(const DILocation *DIL) const;
void clearFunctionData();
/// \brief Map basic blocks to their computed weights.
CoverageTracker.clear();
}
-/// Returns the line offset to the start line of the subprogram.
-/// We assume that a single function will not exceed 65535 LOC.
-unsigned SampleProfileLoader::getOffset(const DILocation *DIL) const {
- return (DIL->getLine() - DIL->getScope()->getSubprogram()->getLine()) &
- 0xffff;
-}
-
#ifndef NDEBUG
/// \brief Print the weight of edge \p E on stream \p OS.
///
return 0;
const DILocation *DIL = DLoc;
- uint32_t LineOffset = getOffset(DIL);
+ uint32_t LineOffset = FunctionSamples::getOffset(DIL);
uint32_t Discriminator = DIL->getBaseDiscriminator();
ErrorOr<uint64_t> R = FS->findSamplesAt(LineOffset, Discriminator);
if (R) {
if (FS == nullptr)
return nullptr;
- return FS->findFunctionSamplesAt(
- LineLocation(getOffset(DIL), DIL->getBaseDiscriminator()), CalleeName);
+ return FS->findFunctionSamplesAt(LineLocation(FunctionSamples::getOffset(DIL),
+ DIL->getBaseDiscriminator()),
+ CalleeName);
}
/// Returns a vector of FunctionSamples that are the indirect call targets
if (FS == nullptr)
return R;
- uint32_t LineOffset = getOffset(DIL);
+ uint32_t LineOffset = FunctionSamples::getOffset(DIL);
uint32_t Discriminator = DIL->getBaseDiscriminator();
auto T = FS->findCallTargetMapAt(LineOffset, Discriminator);
if (T)
for (const auto &T_C : T.get())
Sum += T_C.second;
- if (const FunctionSamplesMap *M = FS->findFunctionSamplesMapAt(
- LineLocation(getOffset(DIL), DIL->getBaseDiscriminator()))) {
+ if (const FunctionSamplesMap *M = FS->findFunctionSamplesMapAt(LineLocation(
+ FunctionSamples::getOffset(DIL), DIL->getBaseDiscriminator()))) {
if (M->empty())
return R;
for (const auto &NameFS : *M) {
if (!DIL)
return Samples;
- const DILocation *PrevDIL = DIL;
- for (DIL = DIL->getInlinedAt(); DIL; DIL = DIL->getInlinedAt()) {
- S.push_back(std::make_pair(
- LineLocation(getOffset(DIL), DIL->getBaseDiscriminator()),
- PrevDIL->getScope()->getSubprogram()->getLinkageName()));
- PrevDIL = DIL;
- }
- if (S.size() == 0)
- return Samples;
- const FunctionSamples *FS = Samples;
- for (int i = S.size() - 1; i >= 0 && FS != nullptr; i--) {
- FS = FS->findFunctionSamplesAt(S[i].first, S[i].second);
- }
- return FS;
+ return Samples->findFunctionSamples(DIL);
}
bool SampleProfileLoader::inlineCallInstruction(Instruction *I) {
if (!DLoc)
continue;
const DILocation *DIL = DLoc;
- uint32_t LineOffset = getOffset(DIL);
+ uint32_t LineOffset = FunctionSamples::getOffset(DIL);
uint32_t Discriminator = DIL->getBaseDiscriminator();
const FunctionSamples *FS = findFunctionSamples(I);