diff options
-rw-r--r-- | llvm/include/llvm/ProfileData/SampleProf.h | 17 | ||||
-rw-r--r-- | llvm/lib/ProfileData/SampleProf.cpp | 27 | ||||
-rw-r--r-- | llvm/lib/Transforms/IPO/SampleProfile.cpp | 38 |
3 files changed, 53 insertions, 29 deletions
diff --git a/llvm/include/llvm/ProfileData/SampleProf.h b/llvm/include/llvm/ProfileData/SampleProf.h index 641631cc4ec..d0a49a0264c 100644 --- a/llvm/include/llvm/ProfileData/SampleProf.h +++ b/llvm/include/llvm/ProfileData/SampleProf.h @@ -383,6 +383,23 @@ public: /// 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; diff --git a/llvm/lib/ProfileData/SampleProf.cpp b/llvm/lib/ProfileData/SampleProf.cpp index eafdd2154b7..85a4197c10a 100644 --- a/llvm/lib/ProfileData/SampleProf.cpp +++ b/llvm/lib/ProfileData/SampleProf.cpp @@ -12,6 +12,7 @@ // //===----------------------------------------------------------------------===// +#include "llvm/IR/DebugInfoMetadata.h" #include "llvm/ProfileData/SampleProf.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/Debug.h" @@ -150,6 +151,32 @@ raw_ostream &llvm::sampleprof::operator<<(raw_ostream &OS, 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 diff --git a/llvm/lib/Transforms/IPO/SampleProfile.cpp b/llvm/lib/Transforms/IPO/SampleProfile.cpp index a8d1be7a583..1cb61ffcfab 100644 --- a/llvm/lib/Transforms/IPO/SampleProfile.cpp +++ b/llvm/lib/Transforms/IPO/SampleProfile.cpp @@ -217,7 +217,6 @@ protected: 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. @@ -473,13 +472,6 @@ void SampleProfileLoader::clearFunctionData() { 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. /// @@ -549,7 +541,7 @@ ErrorOr<uint64_t> SampleProfileLoader::getInstWeight(const Instruction &Inst) { 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) { @@ -649,8 +641,9 @@ SampleProfileLoader::findCalleeFunctionSamples(const Instruction &Inst) const { 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 @@ -670,7 +663,7 @@ SampleProfileLoader::findIndirectCallFunctionSamples( 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); @@ -678,8 +671,8 @@ SampleProfileLoader::findIndirectCallFunctionSamples( 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) { @@ -710,20 +703,7 @@ SampleProfileLoader::findFunctionSamples(const Instruction &Inst) const { 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) { @@ -1281,7 +1261,7 @@ void SampleProfileLoader::propagateWeights(Function &F) { 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); |