Index: include/llvm/ProfileData/SampleProf.h =================================================================== --- include/llvm/ProfileData/SampleProf.h +++ include/llvm/ProfileData/SampleProf.h @@ -383,6 +383,23 @@ /// 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; Index: lib/ProfileData/SampleProf.cpp =================================================================== --- lib/ProfileData/SampleProf.cpp +++ 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 @@ 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, 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 Index: lib/Transforms/IPO/SampleProfile.cpp =================================================================== --- lib/Transforms/IPO/SampleProfile.cpp +++ lib/Transforms/IPO/SampleProfile.cpp @@ -217,7 +217,6 @@ 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 @@ 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 @@ return 0; const DILocation *DIL = DLoc; - uint32_t LineOffset = getOffset(DIL); + uint32_t LineOffset = FunctionSamples::getOffset(DIL); uint32_t Discriminator = DIL->getBaseDiscriminator(); ErrorOr R = FS->findSamplesAt(LineOffset, Discriminator); if (R) { @@ -649,8 +641,9 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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);