diff --git a/llvm/test/tools/llvm-profgen/Inputs/noinline-cs-pseudoprobe.perfscript b/llvm/test/tools/llvm-profgen/Inputs/noinline-cs-pseudoprobe.perfscript --- a/llvm/test/tools/llvm-profgen/Inputs/noinline-cs-pseudoprobe.perfscript +++ b/llvm/test/tools/llvm-profgen/Inputs/noinline-cs-pseudoprobe.perfscript @@ -1,19 +1,19 @@ -PERF_RECORD_MMAP2 1243676/1243676: [0x201000(0x1000) @ 0 00:1d 224517108 1044165]: r-xp /home/noinline-cs-pseudoprobe.perfbin +PERF_RECORD_MMAP2 1243676/1243676: [0x301000(0x1000) @ 0 00:1d 224517108 1044165]: r-xp /home/noinline-cs-pseudoprobe.perfbin - 20179e - 2017f9 + 30179e + 3017f9 7f83e84e7793 5541f689495641d7 - 0x2017cf/0x20179e/P/-/-/0 0x20177f/0x2017c4/P/-/-/0 0x2017bf/0x201760/P/-/-/0 0x2017cf/0x20179e/P/-/-/0 0x20177f/0x2017c4/P/-/-/0 0x2017bf/0x201760/P/-/-/0 0x2017cf/0x20179e/P/-/-/0 0x20177f/0x2017c4/P/-/-/0 0x2017bf/0x201760/P/-/-/0 0x2017cf/0x20179e/P/-/-/0 0x20177f/0x2017c4/P/-/-/0 0x2017bf/0x201760/P/-/-/0 0x2017cf/0x20179e/P/-/-/0 0x20177f/0x2017c4/P/-/-/0 0x2017bf/0x201760/P/-/-/0 0x2017cf/0x20179e/P/-/-/0 + 0x3017cf/0x30179e/P/-/-/0 0x30177f/0x3017c4/P/-/-/0 0x3017bf/0x301760/P/-/-/0 0x3017cf/0x30179e/P/-/-/0 0x30177f/0x3017c4/P/-/-/0 0x3017bf/0x301760/P/-/-/0 0x3017cf/0x30179e/P/-/-/0 0x30177f/0x3017c4/P/-/-/0 0x3017bf/0x301760/P/-/-/0 0x3017cf/0x30179e/P/-/-/0 0x30177f/0x3017c4/P/-/-/0 0x3017bf/0x301760/P/-/-/0 0x3017cf/0x30179e/P/-/-/0 0x30177f/0x3017c4/P/-/-/0 0x3017bf/0x301760/P/-/-/0 0x3017cf/0x30179e/P/-/-/0 - 2017c4 - 2017f9 + 3017c4 + 3017f9 7f83e84e7793 5541f689495641d7 - 0x20177f/0x2017c4/P/-/-/0 0x2017bf/0x201760/P/-/-/0 0x2017cf/0x20179e/P/-/-/0 0x20177f/0x2017c4/P/-/-/0 0x2017bf/0x201760/P/-/-/0 0x2017cf/0x20179e/P/-/-/0 0x20177f/0x2017c4/P/-/-/0 0x2017bf/0x201760/P/-/-/0 0x2017cf/0x20179e/P/-/-/0 0x20177f/0x2017c4/P/-/-/0 0x2017bf/0x201760/P/-/-/0 0x2017cf/0x20179e/P/-/-/0 0x20177f/0x2017c4/P/-/-/0 0x2017bf/0x201760/P/-/-/0 0x2017cf/0x20179e/P/-/-/0 0x20177f/0x2017c4/P/-/-/0 + 0x30177f/0x3017c4/P/-/-/0 0x3017bf/0x301760/P/-/-/0 0x3017cf/0x30179e/P/-/-/0 0x30177f/0x3017c4/P/-/-/0 0x3017bf/0x301760/P/-/-/0 0x3017cf/0x30179e/P/-/-/0 0x30177f/0x3017c4/P/-/-/0 0x3017bf/0x301760/P/-/-/0 0x3017cf/0x30179e/P/-/-/0 0x30177f/0x3017c4/P/-/-/0 0x3017bf/0x301760/P/-/-/0 0x3017cf/0x30179e/P/-/-/0 0x30177f/0x3017c4/P/-/-/0 0x3017bf/0x301760/P/-/-/0 0x3017cf/0x30179e/P/-/-/0 0x30177f/0x3017c4/P/-/-/0 - 2017c4 - 2017f9 + 3017c4 + 3017f9 7f83e84e7793 5541f689495641d7 - 0x20177f/0x2017c4/P/-/-/0 0x2017bf/0x201760/P/-/-/0 0x2017cf/0x20179e/P/-/-/0 0x20177f/0x2017c4/P/-/-/0 0x2017bf/0x201760/P/-/-/0 0x2017cf/0x20179e/P/-/-/0 0x20177f/0x2017c4/P/-/-/0 0x2017bf/0x201760/P/-/-/0 0x2017cf/0x20179e/P/-/-/0 0x20177f/0x2017c4/P/-/-/0 0x2017bf/0x201760/P/-/-/0 0x2017cf/0x20179e/P/-/-/0 0x20177f/0x2017c4/P/-/-/0 0x2017bf/0x201760/P/-/-/0 0x2017cf/0x20179e/P/-/-/0 0x20177f/0x2017c4/P/-/-/0 + 0x30177f/0x3017c4/P/-/-/0 0x3017bf/0x301760/P/-/-/0 0x3017cf/0x30179e/P/-/-/0 0x30177f/0x3017c4/P/-/-/0 0x3017bf/0x301760/P/-/-/0 0x3017cf/0x30179e/P/-/-/0 0x30177f/0x3017c4/P/-/-/0 0x3017bf/0x301760/P/-/-/0 0x3017cf/0x30179e/P/-/-/0 0x30177f/0x3017c4/P/-/-/0 0x3017bf/0x301760/P/-/-/0 0x3017cf/0x30179e/P/-/-/0 0x30177f/0x3017c4/P/-/-/0 0x3017bf/0x301760/P/-/-/0 0x3017cf/0x30179e/P/-/-/0 0x30177f/0x3017c4/P/-/-/0 diff --git a/llvm/tools/llvm-profgen/PerfReader.h b/llvm/tools/llvm-profgen/PerfReader.h --- a/llvm/tools/llvm-profgen/PerfReader.h +++ b/llvm/tools/llvm-profgen/PerfReader.h @@ -370,18 +370,18 @@ } }; -// Address-based context id -struct AddrBasedCtxKey : public ContextKey { +// Offset-based context id +struct OffsetBasedCtxKey : public ContextKey { SmallVector Context; bool WasLeafInlined; - AddrBasedCtxKey() : ContextKey(CK_AddrBased), WasLeafInlined(false){}; + OffsetBasedCtxKey() : ContextKey(CK_AddrBased), WasLeafInlined(false){}; static bool classof(const ContextKey *K) { return K->getKind() == CK_AddrBased; } bool isEqual(const ContextKey *K) const override { - const AddrBasedCtxKey *Other = dyn_cast(K); + const OffsetBasedCtxKey *Other = dyn_cast(K); return Context == Other->Context; } @@ -422,7 +422,7 @@ bool pushFrame(UnwindState::ProfiledFrame *Cur) { assert(!Cur->isExternalFrame() && "External frame's not expected for context stack."); - Stack.push_back(Cur->Address); + Stack.push_back(Binary->virtualAddrToOffset(Cur->Address)); return true; } @@ -440,7 +440,7 @@ bool pushFrame(UnwindState::ProfiledFrame *Cur) { assert(!Cur->isExternalFrame() && "External frame's not expected for context stack."); - Stack.push_back(Cur->Address); + Stack.push_back(Binary->virtualAddrToOffset(Cur->Address)); return true; } @@ -448,7 +448,7 @@ if (!Stack.empty()) Stack.pop_back(); } - std::shared_ptr getContextKey(); + std::shared_ptr getContextKey(); }; /* diff --git a/llvm/tools/llvm-profgen/PerfReader.cpp b/llvm/tools/llvm-profgen/PerfReader.cpp --- a/llvm/tools/llvm-profgen/PerfReader.cpp +++ b/llvm/tools/llvm-profgen/PerfReader.cpp @@ -170,8 +170,9 @@ return KeyStr; } -std::shared_ptr AddressStack::getContextKey() { - std::shared_ptr KeyStr = std::make_shared(); +std::shared_ptr AddressStack::getContextKey() { + std::shared_ptr KeyStr = + std::make_shared(); KeyStr->Context = Stack; CSProfileGenerator::compressRecursionContext(KeyStr->Context); CSProfileGenerator::trimContext(KeyStr->Context); @@ -464,15 +465,12 @@ const ProfiledBinary *Binary) { if (const auto *CtxKey = dyn_cast(K)) { return SampleContext::getContextString(CtxKey->Context); - } else if (const auto *CtxKey = dyn_cast(K)) { + } else if (const auto *CtxKey = dyn_cast(K)) { std::ostringstream OContextStr; for (uint32_t I = 0; I < CtxKey->Context.size(); I++) { if (OContextStr.str().size()) OContextStr << " @ "; - OContextStr << "0x" - << to_hexString( - Binary->virtualAddrToOffset(CtxKey->Context[I]), - false); + OContextStr << "0x" << to_hexString(CtxKey->Context[I], false); } return OContextStr.str(); } else { @@ -1191,6 +1189,11 @@ generateUnsymbolizedProfile(); AggregatedSamples.clear(); + // Base address can be loaded from MMP event, but pseudo probe address is + // always based on preferred loading address. Recover the base address to + // preferred loading address in order to match pseduo probe address correctly. + Binary->setBaseAddress(Binary->getPreferredBaseAddress()); + if (SkipSymbolization) writeUnsymbolizedProfile(OutputFilename); } diff --git a/llvm/tools/llvm-profgen/ProfileGenerator.cpp b/llvm/tools/llvm-profgen/ProfileGenerator.cpp --- a/llvm/tools/llvm-profgen/ProfileGenerator.cpp +++ b/llvm/tools/llvm-profgen/ProfileGenerator.cpp @@ -408,10 +408,9 @@ // the start of the range to look up the function it belongs and record the // function. for (const auto &CI : *SampleCounters) { - if (const auto *CtxKey = dyn_cast(CI.first.getPtr())) { - for (auto Addr : CtxKey->Context) { - if (FuncRange *FRange = Binary->findFuncRangeForOffset( - Binary->virtualAddrToOffset(Addr))) + if (const auto *CtxKey = dyn_cast(CI.first.getPtr())) { + for (auto Offset : CtxKey->Context) { + if (FuncRange *FRange = Binary->findFuncRangeForOffset(Offset)) ProfiledFunctions.insert(FRange->Func); } } @@ -1008,13 +1007,13 @@ } } -static void -extractPrefixContextStack(SampleContextFrameVector &ContextStack, - const SmallVectorImpl &Addresses, - ProfiledBinary *Binary) { +static void extractPrefixContextStack(SampleContextFrameVector &ContextStack, + const SmallVectorImpl &Offsets, + ProfiledBinary *Binary) { SmallVector Probes; - for (auto Addr : reverse(Addresses)) { - const MCDecodedPseudoProbe *CallProbe = Binary->getCallProbeForAddr(Addr); + for (auto Offset : reverse(Offsets)) { + const MCDecodedPseudoProbe *CallProbe = + Binary->getCallProbeForAddr(Binary->offsetToVirtualAddr(Offset)); // These could be the cases when a probe is not found at a calliste. Cutting // off the context from here since the inliner will not know how to consume // a context with unknown callsites. @@ -1041,8 +1040,8 @@ // Enable pseudo probe functionalities in SampleProf FunctionSamples::ProfileIsProbeBased = true; for (const auto &CI : *SampleCounters) { - const AddrBasedCtxKey *CtxKey = - dyn_cast(CI.first.getPtr()); + const OffsetBasedCtxKey *CtxKey = + dyn_cast(CI.first.getPtr()); SampleContextFrameVector ContextStack; extractPrefixContextStack(ContextStack, CtxKey->Context, Binary); // Fill in function body samples from probes, also infer caller's samples diff --git a/llvm/tools/llvm-profgen/ProfiledBinary.cpp b/llvm/tools/llvm-profgen/ProfiledBinary.cpp --- a/llvm/tools/llvm-profgen/ProfiledBinary.cpp +++ b/llvm/tools/llvm-profgen/ProfiledBinary.cpp @@ -259,8 +259,7 @@ if (Stack.empty()) return ContextVec; // Process from frame root to leaf - for (auto Address : Stack) { - uint64_t Offset = virtualAddrToOffset(Address); + for (auto Offset : Stack) { const SampleContextFrameVector &ExpandedContext = getFrameLocationStack(Offset); // An instruction without a valid debug line will be ignored by sample