diff --git a/llvm/lib/Transforms/IPO/SampleProfile.cpp b/llvm/lib/Transforms/IPO/SampleProfile.cpp --- a/llvm/lib/Transforms/IPO/SampleProfile.cpp +++ b/llvm/lib/Transforms/IPO/SampleProfile.cpp @@ -2111,57 +2111,60 @@ void SampleProfileMatcher::findIRAnchors( const Function &F, std::map &IRAnchors) { + auto FindTopLevelFrame = [](const DILocation *DIL) { + const DILocation *PrevDIL = DIL; + for (; DIL->getInlinedAt(); DIL = DIL->getInlinedAt()) + PrevDIL = DIL; + + LineLocation Callsite = FunctionSamples::getCallSiteIdentifier(DIL); + StringRef CalleeName = PrevDIL->getSubprogramLinkageName(); + return std::make_pair(Callsite, CalleeName); + }; + // Extract profile matching anchors in the IR. for (auto &BB : F) { for (auto &I : BB) { - // TODO: To support AutoFDO, we need to parse all the non-call - // instructions to extract the line-number based locations. For - // pseudo-probe mode, since each block is instrumented with one probe - // inst, parsing probe inst is enough. - if (isa(&I)) { - std::optional Probe = extractProbe(I); - assert(Probe && - "Probe should not be null for pseudo-probe instruction"); - // Flatten inlined IR for the matching. Recover the original callsite - // and call target by analyzing the inline frames from the debug info. - if (DILocation *DIL = I.getDebugLoc()) { - if (DIL->getInlinedAt()) { - // Find the top-level inline frame. - const DILocation *PrevDIL = DIL; - for (; DIL->getInlinedAt(); DIL = DIL->getInlinedAt()) - PrevDIL = DIL; - - LineLocation Callsite = FunctionSamples::getCallSiteIdentifier(DIL); - StringRef CalleeName = PrevDIL->getSubprogramLinkageName(); - IRAnchors.emplace(Callsite, CalleeName); - } else - IRAnchors.emplace(LineLocation(Probe->Id, 0), StringRef()); - } - } - - if (!isa(&I) || isa(&I)) + DILocation *DIL = I.getDebugLoc(); + if (!DIL) continue; - const auto *CB = dyn_cast(&I); - if (auto &DLoc = I.getDebugLoc()) { - // Skip the inlined callsite. For pseudo probe mode, extracting inline - // info from the probe inst is enough. - if (DLoc.getInlinedAt()) + if (FunctionSamples::ProfileIsProbeBased) { + if (auto Probe = extractProbe(I)) { + // Flatten inlined IR for the matching. Recover the original callsite + // and call target by analyzing the inline frames from the debug info. + if (DIL->getInlinedAt()) { + IRAnchors.emplace(FindTopLevelFrame(DIL)); + } else { + // Use empty StringRef for basic block probe. + StringRef CalleeName; + if (const auto *CB = dyn_cast(&I)) { + if (Function *Callee = CB->getCalledFunction()) + CalleeName = + FunctionSamples::getCanonicalFnName(Callee->getName()); + else + CalleeName = UnknownIndirectCallee; + } + IRAnchors.emplace(LineLocation(Probe->Id, 0), CalleeName); + } + } + } else { + // TODO: For line-number based profile(AutoFDO), currently only support + // find callsite anchors. In future, we need to parse all the non-call + // instructions to extract the IR anchors for profile matching. + if (!isa(&I) || isa(&I)) continue; - LineLocation IRCallsite = FunctionSamples::getCallSiteIdentifier(DLoc); - StringRef CalleeName = UnknownIndirectCallee; - if (Function *Callee = CB->getCalledFunction()) - CalleeName = FunctionSamples::getCanonicalFnName(Callee->getName()); - - // Force to overwrite the callee name in case any non-call location was - // written before. - auto R = IRAnchors.emplace(IRCallsite, CalleeName); - R.first->second = CalleeName; - assert((!FunctionSamples::ProfileIsProbeBased || R.second || - R.first->second == CalleeName) && - "Overwrite non-call or different callee name location for " - "pseudo probe callsite"); + if (DIL->getInlinedAt()) { + IRAnchors.emplace(FindTopLevelFrame(DIL)); + } else { + const auto *CB = dyn_cast(&I); + LineLocation IRCallsite = FunctionSamples::getCallSiteIdentifier(DIL); + StringRef CalleeName = UnknownIndirectCallee; + if (Function *Callee = CB->getCalledFunction()) + CalleeName = FunctionSamples::getCanonicalFnName(Callee->getName()); + + IRAnchors.emplace(IRCallsite, CalleeName); + } } } }