/// \brief Get the FunctionSamples for an instruction. /// /// The FunctionSamples of an instruction \p Inst 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 * SampleProfileLoader::findFunctionSamples(const Instruction &Inst) const { SmallVector<CallsiteLocation, 10> S; const DILocation *DIL = Inst.getDebugLoc(); if (!DIL) { return Samples; } StringRef CalleeName; for (const DILocation *DIL = Inst.getDebugLoc(); DIL; DIL = DIL->getInlinedAt()) { DISubprogram *SP = DIL->getScope()->getSubprogram(); if (!SP || DIL->getLine() < SP->getLine()) return nullptr; if (!CalleeName.empty()) { S.push_back(CallsiteLocation(DIL->getLine() - SP->getLine(), DIL->getDiscriminator(), CalleeName)); } CalleeName = SP->getLinkageName(); } 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]); } return FS; }
/// \brief Get the FunctionSamples for a call instruction. /// /// The FunctionSamples of a call instruction \p Inst is the inlined /// instance in which that call instruction is calling to. It contains /// all samples that resides in the inlined instance. We first find the /// inlined instance in which the call instruction is from, then we /// traverse its children to find the callsite with the matching /// location and callee function name. /// /// \param Inst Call instruction to query. /// /// \returns The FunctionSamples pointer to the inlined instance. const FunctionSamples * SampleProfileLoader::findCalleeFunctionSamples(const CallInst &Inst) const { const DILocation *DIL = Inst.getDebugLoc(); if (!DIL) { return nullptr; } DISubprogram *SP = DIL->getScope()->getSubprogram(); if (!SP || DIL->getLine() < SP->getLine()) return nullptr; Function *CalleeFunc = Inst.getCalledFunction(); if (!CalleeFunc) { return nullptr; } StringRef CalleeName = CalleeFunc->getName(); const FunctionSamples *FS = findFunctionSamples(Inst); if (FS == nullptr) return nullptr; return FS->findFunctionSamplesAt(CallsiteLocation( DIL->getLine() - SP->getLine(), DIL->getDiscriminator(), CalleeName)); }
void LineNumberAnnotatedWriter::emitFunctionAnnot( const Function *F, formatted_raw_ostream &Out) { InstrLoc = nullptr; DISubprogram *FuncLoc = F->getSubprogram(); if (!FuncLoc) { auto SP = Subprogram.find(F); if (SP != Subprogram.end()) FuncLoc = SP->second; } if (!FuncLoc) return; std::vector<DILineInfo> DIvec(1); DILineInfo &DI = DIvec.back(); DI.FunctionName = FuncLoc->getName(); DI.FileName = FuncLoc->getFilename(); DI.Line = FuncLoc->getLine(); LinePrinter.emit_lineinfo(Out, DIvec); }