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 @@ -54,11 +54,13 @@ } else { // Unwind linear execution part uint64_t LeafAddr = State.CurrentLeafFrame->Address; - while (IP.Address >= Target) { + bool HasNext = true; + while (IP.Address >= Target && HasNext) { uint64_t PrevIP = IP.Address; - IP.backward(); + HasNext = IP.backward(); // Break into segments for implicit call/return due to inlining - bool SameInlinee = Binary->inlineContextEqual(PrevIP, IP.Address); + bool SameInlinee = + HasNext && Binary->inlineContextEqual(PrevIP, IP.Address); if (!SameInlinee || PrevIP == Target) { State.switchToFrame(LeafAddr); State.CurrentLeafFrame->recordRangeCount(PrevIP, End, Repeat); 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 @@ -245,7 +245,8 @@ // Recording body sample for this specific context updateBodySamplesforFunctionProfile(FunctionProfile, LeafLoc, Count); // Move to next IP within the range - IP.advance(); + if (!IP.advance()) + break; } } } @@ -467,8 +468,8 @@ ProbeCounter[&Probe] += Count; } } - - IP.advance(); + if (!IP.advance()) + break; } } } diff --git a/llvm/tools/llvm-profgen/ProfiledBinary.h b/llvm/tools/llvm-profgen/ProfiledBinary.h --- a/llvm/tools/llvm-profgen/ProfiledBinary.h +++ b/llvm/tools/llvm-profgen/ProfiledBinary.h @@ -56,8 +56,8 @@ uint64_t Index = 0; InstructionPointer(ProfiledBinary *Binary, uint64_t Address, bool RoundToNext = false); - void advance(); - void backward(); + bool advance(); + bool backward(); void update(uint64_t Addr); }; @@ -77,8 +77,8 @@ for (auto I : FuncStartAddrMap) { PrologEpilogSet.insert(I.first); InstructionPointer IP(Binary, I.first); - IP.advance(); - PrologEpilogSet.insert(IP.Offset); + if (IP.advance()) + PrologEpilogSet.insert(IP.Offset); } } @@ -87,8 +87,8 @@ for (auto Addr : RetAddrs) { PrologEpilogSet.insert(Addr); InstructionPointer IP(Binary, Addr); - IP.backward(); - PrologEpilogSet.insert(IP.Offset); + if (IP.backward()) + PrologEpilogSet.insert(IP.Offset); } } }; @@ -179,6 +179,7 @@ uint64_t offsetToVirtualAddr(uint64_t Offset) const { return Offset + BaseAddress; } + uint32_t codeAddrsSize() { return CodeAddrs.size(); } StringRef getPath() const { return Path; } StringRef getName() const { return llvm::sys::path::filename(Path); } uint64_t getBaseAddress() const { return BaseAddress; } 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 @@ -243,16 +243,23 @@ const MCInstrDesc &MCDesc = MII->get(Inst.getOpcode()); // Populate a vector of the symbolized callsite at this location - InstructionPointer IP(this, Offset); - Offset2LocStackMap[Offset] = symbolize(IP, true); - - // Populate address maps. - CodeAddrs.push_back(Offset); - if (MCDesc.isCall()) - CallAddrs.insert(Offset); - else if (MCDesc.isReturn()) - RetAddrs.insert(Offset); - + // We don't need symbolized info for probe-based profile + FrameLocationStack SymbolizedCallStack; + if (!UsePseudoProbes) { + InstructionPointer IP(this, Offset); + SymbolizedCallStack = symbolize(IP, true); + } + if (UsePseudoProbes || !SymbolizedCallStack.empty()) { + // For probe-based profile, just use an empty stack as an entry to + // indicate a valid binary offset + Offset2LocStackMap[Offset] = SymbolizedCallStack; + // Populate address maps. + CodeAddrs.push_back(Offset); + if (MCDesc.isCall()) + CallAddrs.insert(Offset); + else if (MCDesc.isReturn()) + RetAddrs.insert(Offset); + } Offset += Size; } @@ -418,14 +425,20 @@ } } -void InstructionPointer::advance() { +bool InstructionPointer::advance() { + if (Index + 1 >= Binary->codeAddrsSize()) + return false; Index++; Address = Binary->getAddressforIndex(Index); + return true; } -void InstructionPointer::backward() { +bool InstructionPointer::backward() { + if (Index == 0) + return false; Index--; Address = Binary->getAddressforIndex(Index); + return true; } void InstructionPointer::update(uint64_t Addr) {