[llvm-branch-commits] [llvm-profgen] Support [buildid:]0xaddr format in perfscript input (PR #190863)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue Apr 7 15:29:00 PDT 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-pgo
Author: Amir Ayupov (aaupov)
<details>
<summary>Changes</summary>
Add support for optional build ID prefix in perfscript addresses,
following the format buildid:0xhexaddr. This enables multi-DSO profiling
with a single input file: each address optionally carries a build ID,
and profgen filters addresses by matching the binary's build ID.
Parsing changes:
- parseAddressWithBuildID: parses [buildid:]0xhexaddr, handles 0x prefix
- extractLBRStack: handles buildid:0xaddr/buildid:0xaddr LBR entries
- extractCallstack: handles buildid:0xaddr callstack frames
- looksLikeLBRLine: replaces starts_with(" 0x") for LBR line detection
to support buildid-prefixed lines
- isLBRSample: also accepts buildid:0xaddr/ pattern
- checkPerfScriptType: strips buildid prefix and 0x for format detection
Filtering: only addresses with a non-empty buildid prefix that doesn't
match the binary's FilterBuildID are marked as external. Addresses
without a prefix use existing addressIsCode check (backward compatible).
--filter-build-id=<hex> CLI option overrides auto-detected build ID.
---
Full diff: https://github.com/llvm/llvm-project/pull/190863.diff
4 Files Affected:
- (added) llvm/test/tools/llvm-profgen/Inputs/buildid-cs-noprobe.aggperfscript (+11)
- (added) llvm/test/tools/llvm-profgen/Inputs/buildid-noprobe.perfscript (+5)
- (added) llvm/test/tools/llvm-profgen/filter-build-id.test (+53)
- (modified) llvm/tools/llvm-profgen/PerfReader.cpp (+88-16)
``````````diff
diff --git a/llvm/test/tools/llvm-profgen/Inputs/buildid-cs-noprobe.aggperfscript b/llvm/test/tools/llvm-profgen/Inputs/buildid-cs-noprobe.aggperfscript
new file mode 100644
index 0000000000000..accd8fb5c57a0
--- /dev/null
+++ b/llvm/test/tools/llvm-profgen/Inputs/buildid-cs-noprobe.aggperfscript
@@ -0,0 +1,11 @@
+2
+ aabb1122:0x4005dc
+ aabb1122:0x400634
+ aabb1122:0x400684
+ 7f68c5788793
+ aabb1122:0x4005c8/aabb1122:0x4005dc aabb1122:0x40062f/aabb1122:0x4005b0 aabb1122:0x400645/aabb1122:0x4005ff aabb1122:0x400637/aabb1122:0x400645 aabb1122:0x4005e9/aabb1122:0x400634 aabb1122:0x4005d7/aabb1122:0x4005e5 aabb1122:0x40062f/aabb1122:0x4005b0 aabb1122:0x400645/aabb1122:0x4005ff aabb1122:0x400637/aabb1122:0x400645 aabb1122:0x4005e9/aabb1122:0x400634 aabb1122:0x4005d7/aabb1122:0x4005e5 aabb1122:0x40062f/aabb1122:0x4005b0 aabb1122:0x400645/aabb1122:0x4005ff aabb1122:0x400637/aabb1122:0x400645 aabb1122:0x4005e9/aabb1122:0x400634 aabb1122:0x4005c8/aabb1122:0x4005dc
+2
+ aabb1122:0x4005b0
+ aabb1122:0x400684
+ 7f68c5788793
+ aabb1122:0x40062f/aabb1122:0x4005b0 aabb1122:0x400645/aabb1122:0x4005ff aabb1122:0x400637/aabb1122:0x400645 aabb1122:0x4005e9/aabb1122:0x400634 aabb1122:0x4005c8/aabb1122:0x4005dc aabb1122:0x40062f/aabb1122:0x4005b0 aabb1122:0x400645/aabb1122:0x4005ff aabb1122:0x400637/aabb1122:0x400645 aabb1122:0x4005e9/aabb1122:0x400634 aabb1122:0x4005d7/aabb1122:0x4005e5 aabb1122:0x40062f/aabb1122:0x4005b0 aabb1122:0x400645/aabb1122:0x4005ff aabb1122:0x400637/aabb1122:0x400645 aabb1122:0x4005e9/aabb1122:0x400634 aabb1122:0x4005d7/aabb1122:0x4005e5 aabb1122:0x40062f/aabb1122:0x4005b0
diff --git a/llvm/test/tools/llvm-profgen/Inputs/buildid-noprobe.perfscript b/llvm/test/tools/llvm-profgen/Inputs/buildid-noprobe.perfscript
new file mode 100644
index 0000000000000..5acff939e8a01
--- /dev/null
+++ b/llvm/test/tools/llvm-profgen/Inputs/buildid-noprobe.perfscript
@@ -0,0 +1,5 @@
+// LBR-only perfscript with [buildid:]0xaddr format.
+// Same as noprobe.perfscript but with "aabb1122" buildid prefix on all addresses.
+ aabb1122:0x40062f aabb1122:0x40062f/aabb1122:0x4005b0/P/-/-/9 aabb1122:0x400645/aabb1122:0x4005ff/P/-/-/1 aabb1122:0x400637/aabb1122:0x400645/P/-/-/1 aabb1122:0x4005e9/aabb1122:0x400634/P/-/-/1 aabb1122:0x4005d7/aabb1122:0x4005e5/P/-/-/6 aabb1122:0x40062f/aabb1122:0x4005b0/P/-/-/16 aabb1122:0x400645/aabb1122:0x4005ff/P/-/-/1 aabb1122:0x400637/aabb1122:0x400645/P/-/-/1 aabb1122:0x4005e9/aabb1122:0x400634/P/-/-/1 aabb1122:0x4005d7/aabb1122:0x4005e5/P/-/-/6 aabb1122:0x40062f/aabb1122:0x4005b0/P/-/-/6 aabb1122:0x400645/aabb1122:0x4005ff/P/-/-/1 aabb1122:0x400637/aabb1122:0x400645/P/-/-/1 aabb1122:0x4005e9/aabb1122:0x400634/P/-/-/1 aabb1122:0x4005c8/aabb1122:0x4005dc/P/-/-/8 aabb1122:0x40062f/aabb1122:0x4005b0/P/-/-/9 aabb1122:0x400645/aabb1122:0x4005ff/P/-/-/1 aabb1122:0x400637/aabb1122:0x400645/P/-/-/1 aabb1122:0x4005e9/aabb1122:0x400634/P/-/-/1 aabb1122:0x4005d7/aabb1122:0x4005e5/P/-/-/10 aabb1122:0x40062f/aabb1122:0x4005b0/P/-/-/14 aabb1122:0x400645/aabb1122:0x4005ff/P/-/-/1 aabb1122:0x400637/aabb1122:0x400645/P/-/-/1 aabb1122:0x4005e9/aabb1122:0x400634/P/-/-/1 aabb1122:0x4005d7/aabb1122:0x4005e5/P/-/-/7 aabb1122:0x40062f/aabb1122:0x4005b0/P/-/-/8 aabb1122:0x400645/aabb1122:0x4005ff/P/-/-/1 aabb1122:0x400637/aabb1122:0x400645/P/-/-/1 aabb1122:0x4005e9/aabb1122:0x400634/P/-/-/1 aabb1122:0x4005c8/aabb1122:0x4005dc/P/-/-/7 aabb1122:0x40062f/aabb1122:0x4005b0/P/-/-/15 aabb1122:0x400645/aabb1122:0x4005ff/P/-/-/1
+ aabb1122:0x4005d7 aabb1122:0x4005d7/aabb1122:0x4005e5/P/-/-/8 aabb1122:0x40062f/aabb1122:0x4005b0/P/-/-/6 aabb1122:0x400645/aabb1122:0x4005ff/P/-/-/1 aabb1122:0x400637/aabb1122:0x400645/P/-/-/1 aabb1122:0x4005e9/aabb1122:0x400634/P/-/-/2 aabb1122:0x4005c8/aabb1122:0x4005dc/P/-/-/7 aabb1122:0x40062f/aabb1122:0x4005b0/P/-/-/11 aabb1122:0x400645/aabb1122:0x4005ff/P/-/-/1 aabb1122:0x400637/aabb1122:0x400645/P/-/-/1 aabb1122:0x4005e9/aabb1122:0x400634/P/-/-/1 aabb1122:0x4005d7/aabb1122:0x4005e5/P/-/-/8 aabb1122:0x40062f/aabb1122:0x4005b0/P/-/-/9 aabb1122:0x400645/aabb1122:0x4005ff/P/-/-/1 aabb1122:0x400637/aabb1122:0x400645/P/-/-/1 aabb1122:0x4005e9/aabb1122:0x400634/P/-/-/1 aabb1122:0x4005d7/aabb1122:0x4005e5/P/-/-/5 aabb1122:0x40062f/aabb1122:0x4005b0/P/-/-/11 aabb1122:0x400645/aabb1122:0x4005ff/P/-/-/1 aabb1122:0x400637/aabb1122:0x400645/P/-/-/1 aabb1122:0x4005e9/aabb1122:0x400634/P/-/-/2 aabb1122:0x4005c8/aabb1122:0x4005dc/P/-/-/7 aabb1122:0x40062f/aabb1122:0x4005b0/P/-/-/10 aabb1122:0x400645/aabb1122:0x4005ff/P/-/-/1 aabb1122:0x400637/aabb1122:0x400645/P/-/-/1 aabb1122:0x4005e9/aabb1122:0x400634/P/-/-/1 aabb1122:0x4005d7/aabb1122:0x4005e5/P/-/-/8 aabb1122:0x40062f/aabb1122:0x4005b0/P/-/-/9 aabb1122:0x400645/aabb1122:0x4005ff/P/-/-/1 aabb1122:0x400637/aabb1122:0x400645/P/-/-/1 aabb1122:0x4005e9/aabb1122:0x400634/P/-/-/1 aabb1122:0x4005d7/aabb1122:0x4005e5/P/-/-/13 aabb1122:0x40062f/aabb1122:0x4005b0/P/-/-/9
+ aabb1122:0x4005c8 aabb1122:0x4005c8/aabb1122:0x4005dc/P/-/-/11 aabb1122:0x40062f/aabb1122:0x4005b0/P/-/-/8 aabb1122:0x400645/aabb1122:0x4005ff/P/-/-/1 aabb1122:0x400637/aabb1122:0x400645/P/-/-/1 aabb1122:0x4005e9/aabb1122:0x400634/P/-/-/1 aabb1122:0x4005d7/aabb1122:0x4005e5/P/-/-/5 aabb1122:0x40062f/aabb1122:0x4005b0/P/-/-/6 aabb1122:0x400645/aabb1122:0x4005ff/P/-/-/1 aabb1122:0x400637/aabb1122:0x400645/P/-/-/1 aabb1122:0x4005e9/aabb1122:0x400634/P/-/-/1 aabb1122:0x4005d7/aabb1122:0x4005e5/P/-/-/12 aabb1122:0x40062f/aabb1122:0x4005b0/P/-/-/6 aabb1122:0x400645/aabb1122:0x4005ff/P/-/-/1 aabb1122:0x400637/aabb1122:0x400645/P/-/-/1 aabb1122:0x4005e9/aabb1122:0x400634/P/-/-/2 aabb1122:0x4005c8/aabb1122:0x4005dc/P/-/-/7 aabb1122:0x40062f/aabb1122:0x4005b0/P/-/-/10 aabb1122:0x400645/aabb1122:0x4005ff/P/-/-/1 aabb1122:0x400637/aabb1122:0x400645/P/-/-/1 aabb1122:0x4005e9/aabb1122:0x400634/P/-/-/1 aabb1122:0x4005d7/aabb1122:0x4005e5/P/-/-/8 aabb1122:0x40062f/aabb1122:0x4005b0/P/-/-/9 aabb1122:0x400645/aabb1122:0x4005ff/P/-/-/1 aabb1122:0x400637/aabb1122:0x400645/P/-/-/1 aabb1122:0x4005e9/aabb1122:0x400634/P/-/-/1 aabb1122:0x4005d7/aabb1122:0x4005e5/P/-/-/12 aabb1122:0x40062f/aabb1122:0x4005b0/P/-/-/6 aabb1122:0x400645/aabb1122:0x4005ff/P/-/-/1 aabb1122:0x400637/aabb1122:0x400645/P/-/-/1 aabb1122:0x4005e9/aabb1122:0x400634/P/-/-/2 aabb1122:0x4005c8/aabb1122:0x4005dc/P/-/-/8 aabb1122:0x40062f/aabb1122:0x4005b0/P/-/-/8
diff --git a/llvm/test/tools/llvm-profgen/filter-build-id.test b/llvm/test/tools/llvm-profgen/filter-build-id.test
new file mode 100644
index 0000000000000..2943c06b2b6ab
--- /dev/null
+++ b/llvm/test/tools/llvm-profgen/filter-build-id.test
@@ -0,0 +1,53 @@
+; REQUIRES: x86_64-linux
+; Test that [buildid:]0xaddr format is correctly parsed in perfscript input.
+
+;; Test 1: LBR-only perfscript with buildid prefix, using --filter-build-id
+;; to match "aabb1122". Output should match the original noprobe.perfscript.
+; RUN: llvm-profgen --format=text --perfscript=%S/Inputs/buildid-noprobe.perfscript --binary=%S/Inputs/noprobe.perfbin --output=%t --skip-symbolization --filter-build-id=aabb1122
+; RUN: FileCheck %s --input-file %t --check-prefix=CHECK-LBR
+
+; CHECK-LBR: 7
+; CHECK-LBR-NEXT: 5b0-5c8:7
+; CHECK-LBR-NEXT: 5b0-5d7:13
+; CHECK-LBR-NEXT: 5dc-5e9:6
+; CHECK-LBR-NEXT: 5e5-5e9:12
+; CHECK-LBR-NEXT: 5ff-62f:19
+; CHECK-LBR-NEXT: 634-637:18
+; CHECK-LBR-NEXT: 645-645:18
+; CHECK-LBR-NEXT: 6
+; CHECK-LBR-NEXT: 5c8->5dc:7
+; CHECK-LBR-NEXT: 5d7->5e5:13
+; CHECK-LBR-NEXT: 5e9->634:18
+; CHECK-LBR-NEXT: 62f->5b0:21
+; CHECK-LBR-NEXT: 637->645:18
+; CHECK-LBR-NEXT: 645->5ff:19
+
+;; Test 2: Hybrid perfscript with buildid prefix, using --filter-build-id
+;; to match "aabb1122". Output should match noinline-cs-noprobe.aggperfscript.
+; RUN: llvm-profgen --format=text --perfscript=%S/Inputs/buildid-cs-noprobe.aggperfscript --binary=%S/Inputs/noinline-cs-noprobe.perfbin --output=%t2 --skip-symbolization --profile-summary-cold-count=0 --filter-build-id=aabb1122
+; RUN: FileCheck %s --input-file %t2 --check-prefix=CHECK-HYBRID
+
+; CHECK-HYBRID: [foo]
+; CHECK-HYBRID-NEXT: 3
+; CHECK-HYBRID-NEXT: 5ff-62f:6
+; CHECK-HYBRID-NEXT: 634-637:6
+; CHECK-HYBRID-NEXT: 645-645:6
+; CHECK-HYBRID-NEXT: 3
+; CHECK-HYBRID-NEXT: 62f->5b0:6
+; CHECK-HYBRID-NEXT: 637->645:6
+; CHECK-HYBRID-NEXT: 645->5ff:6
+; CHECK-HYBRID-NEXT: [foo:3 @ bar]
+; CHECK-HYBRID-NEXT: 4
+; CHECK-HYBRID-NEXT: 5b0-5c8:2
+; CHECK-HYBRID-NEXT: 5b0-5d7:4
+; CHECK-HYBRID-NEXT: 5dc-5e9:2
+; CHECK-HYBRID-NEXT: 5e5-5e9:4
+; CHECK-HYBRID-NEXT: 3
+; CHECK-HYBRID-NEXT: 5c8->5dc:4
+; CHECK-HYBRID-NEXT: 5d7->5e5:4
+; CHECK-HYBRID-NEXT: 5e9->634:6
+
+;; Test 3: With non-matching filter, all addresses should be filtered out,
+;; resulting in no samples (empty output).
+; RUN: llvm-profgen --format=text --perfscript=%S/Inputs/buildid-noprobe.perfscript --binary=%S/Inputs/noprobe.perfbin --output=%t3 --skip-symbolization --filter-build-id=ccdd3344 2>&1 | FileCheck %s --check-prefix=CHECK-NOMATCH
+; CHECK-NOMATCH: warning: No samples in perf script!
diff --git a/llvm/tools/llvm-profgen/PerfReader.cpp b/llvm/tools/llvm-profgen/PerfReader.cpp
index 1dc59321fd91f..f9b91cbed259b 100644
--- a/llvm/tools/llvm-profgen/PerfReader.cpp
+++ b/llvm/tools/llvm-profgen/PerfReader.cpp
@@ -60,6 +60,13 @@ static cl::opt<int> CSProfMaxUnsymbolizedCtxDepth(
"means no depth limit."),
cl::cat(ProfGenCategory));
+static cl::opt<std::string> FilterBuildID(
+ "filter-build-id",
+ cl::desc("Override auto-detected build ID for filtering perfscript "
+ "addresses in [buildid:]addr format. When set, only addresses "
+ "with a matching build ID prefix are kept."),
+ cl::cat(ProfGenCategory));
+
namespace sampleprof {
void VirtualUnwinder::unwindCall(UnwindState &State) {
@@ -654,6 +661,43 @@ void HybridPerfReader::unwindSamples() {
"frame to match.");
}
+/// Parse an address that may optionally have a build ID prefix in
+/// [buildid:]addr format. Sets \p BuildID to the build ID prefix (empty if
+/// none) and \p Addr to the hex address. Returns true on success.
+/// Handles optional "0x" prefix on the address part.
+static bool parseAddressWithBuildID(StringRef Str, uint64_t &Addr,
+ StringRef &BuildID) {
+ BuildID = StringRef();
+ size_t ColonPos = Str.find(':');
+ if (ColonPos != StringRef::npos) {
+ BuildID = Str.substr(0, ColonPos);
+ Str = Str.substr(ColonPos + 1);
+ }
+ Str.consume_front("0x");
+ return !Str.getAsInteger(16, Addr);
+}
+
+/// Return the build ID to use for filtering perfscript addresses.
+/// If --filter-build-id is specified, use it as an override.
+/// Otherwise, use the auto-detected value from the binary.
+static StringRef getFilterBuildID(const ProfiledBinary *Binary) {
+ if (FilterBuildID.getNumOccurrences() > 0)
+ return FilterBuildID;
+ return Binary->getFilterBuildID();
+}
+
+/// Check if a line looks like an LBR sample line. LBR lines start with
+/// a space and the first whitespace-delimited token contains '/'.
+static bool looksLikeLBRLine(StringRef Line) {
+ if (!Line.starts_with(" "))
+ return false;
+ StringRef Trimmed = Line.ltrim();
+ size_t SpacePos = Trimmed.find(' ');
+ StringRef FirstToken =
+ (SpacePos != StringRef::npos) ? Trimmed.substr(0, SpacePos) : Trimmed;
+ return FirstToken.contains('/');
+}
+
bool PerfScriptReader::extractLBRStack(TraceStream &TraceIt,
SmallVectorImpl<LBREntry> &LBRStack) {
// The raw format of LBR stack is like:
@@ -671,8 +715,9 @@ bool PerfScriptReader::extractLBRStack(TraceStream &TraceIt,
// Skip the leading instruction pointer.
size_t Index = 0;
uint64_t LeadingAddr;
+ StringRef LeadingBuildID;
if (!Records.empty() && !Records[0].contains('/')) {
- if (Records[0].getAsInteger(16, LeadingAddr)) {
+ if (!parseAddressWithBuildID(Records[0], LeadingAddr, LeadingBuildID)) {
WarnInvalidLBR(TraceIt);
TraceIt.advance();
return false;
@@ -692,10 +737,13 @@ bool PerfScriptReader::extractLBRStack(TraceStream &TraceIt,
Token.split(Addresses, "/");
uint64_t Src;
uint64_t Dst;
+ StringRef SrcBuildID, DstBuildID;
// Stop at broken LBR records.
- if (Addresses.size() < 2 || Addresses[0].substr(2).getAsInteger(16, Src) ||
- Addresses[1].substr(2).getAsInteger(16, Dst)) {
+ // Parse [buildid:]0xhexaddr format.
+ if (Addresses.size() < 2 ||
+ !parseAddressWithBuildID(Addresses[0], Src, SrcBuildID) ||
+ !parseAddressWithBuildID(Addresses[1], Dst, DstBuildID)) {
WarnInvalidLBR(TraceIt);
break;
}
@@ -705,6 +753,13 @@ bool PerfScriptReader::extractLBRStack(TraceStream &TraceIt,
Dst = Binary->canonicalizeVirtualAddress(Dst);
bool SrcIsInternal = Binary->addressIsCode(Src);
bool DstIsInternal = Binary->addressIsCode(Dst);
+ // Filter by build ID: addresses with a non-matching buildid prefix
+ // are treated as external.
+ StringRef BinaryBuildID = getFilterBuildID(Binary);
+ if (!SrcBuildID.empty() && SrcBuildID != BinaryBuildID)
+ SrcIsInternal = false;
+ if (!DstBuildID.empty() && DstBuildID != BinaryBuildID)
+ DstIsInternal = false;
if (!SrcIsInternal)
Src = ExternalAddr;
if (!DstIsInternal)
@@ -722,16 +777,17 @@ bool PerfScriptReader::extractLBRStack(TraceStream &TraceIt,
bool PerfScriptReader::extractCallstack(TraceStream &TraceIt,
SmallVectorImpl<uint64_t> &CallStack) {
// The raw format of call stack is like:
- // 4005dc # leaf frame
+ // 4005dc # leaf frame (no buildid)
// 400634
- // 400684 # root frame
+ // deadbeef:0x400684 # frame with buildid prefix
// It's in bottom-up order with each frame in one line.
// Extract stack frames from sample
- while (!TraceIt.isAtEoF() && !TraceIt.getCurrentLine().starts_with(" 0x")) {
+ while (!TraceIt.isAtEoF() && !looksLikeLBRLine(TraceIt.getCurrentLine())) {
StringRef FrameStr = TraceIt.getCurrentLine().ltrim();
uint64_t FrameAddr = 0;
- if (FrameStr.getAsInteger(16, FrameAddr)) {
+ StringRef FrameBuildID;
+ if (!parseAddressWithBuildID(FrameStr, FrameAddr, FrameBuildID)) {
// We might parse a non-perf sample line like empty line and comments,
// skip it
TraceIt.advance();
@@ -741,7 +797,13 @@ bool PerfScriptReader::extractCallstack(TraceStream &TraceIt,
FrameAddr = Binary->canonicalizeVirtualAddress(FrameAddr);
// Currently intermixed frame from different binaries is not supported.
- if (!Binary->addressIsCode(FrameAddr)) {
+ bool IsExternal = !Binary->addressIsCode(FrameAddr);
+ // Filter by build ID: addresses with a non-matching buildid prefix
+ // are treated as external.
+ if (!IsExternal && !FrameBuildID.empty() &&
+ FrameBuildID != getFilterBuildID(Binary))
+ IsExternal = true;
+ if (IsExternal) {
if (CallStack.empty())
NumLeafExternalFrame++;
// Push a special value(ExternalAddr) for the external frames so that
@@ -776,7 +838,7 @@ bool PerfScriptReader::extractCallstack(TraceStream &TraceIt,
// Skip other unrelated line, find the next valid LBR line
// Note that even for empty call stack, we should skip the address at the
// bottom, otherwise the following pass may generate a truncated callstack
- while (!TraceIt.isAtEoF() && !TraceIt.getCurrentLine().starts_with(" 0x")) {
+ while (!TraceIt.isAtEoF() && !looksLikeLBRLine(TraceIt.getCurrentLine())) {
TraceIt.advance();
}
// Filter out broken stack sample. We may not have complete frame info
@@ -821,14 +883,14 @@ void HybridPerfReader::parseSample(TraceStream &TraceIt, uint64_t Count) {
// Parsing call stack and populate into PerfSample.CallStack
if (!extractCallstack(TraceIt, Sample->CallStack)) {
// Skip the next LBR line matched current call stack
- if (!TraceIt.isAtEoF() && TraceIt.getCurrentLine().starts_with(" 0x"))
+ if (!TraceIt.isAtEoF() && looksLikeLBRLine(TraceIt.getCurrentLine()))
TraceIt.advance();
return;
}
warnIfMissingMMap();
- if (!TraceIt.isAtEoF() && TraceIt.getCurrentLine().starts_with(" 0x")) {
+ if (!TraceIt.isAtEoF() && looksLikeLBRLine(TraceIt.getCurrentLine())) {
// Parsing LBR stack and populate into PerfSample.LBRStack
if (extractLBRStack(TraceIt, Sample->LBRStack)) {
if (IgnoreStackSamples) {
@@ -1151,15 +1213,18 @@ void PerfScriptReader::parseAndAggregateTrace() {
// A LBR sample is like:
// 40062f 0x5c6313f/0x5c63170/P/-/-/0 0x5c630e7/0x5c63130/P/-/-/0 ...
-// A heuristic for fast detection by checking whether a
-// leading " 0x" and the '/' exist.
+// Or with buildid prefix:
+// deadbeef:0x40062f deadbeef:0x5c6313f/deadbeef:0x5c63170/P/-/-/0 ...
+// A heuristic for fast detection by checking whether the second token
+// contains '/' and has an address (0x or buildid:0x prefix).
bool PerfScriptReader::isLBRSample(StringRef Line) {
// Skip the leading instruction pointer
SmallVector<StringRef, 32> Records;
Line.trim().split(Records, " ", 2, false);
if (Records.size() < 2)
return false;
- if (Records[1].starts_with("0x") && Records[1].contains('/'))
+ if (Records[1].contains('/') &&
+ (Records[1].starts_with("0x") || Records[1].contains(":0x")))
return true;
return false;
}
@@ -1197,8 +1262,15 @@ PerfContent PerfScriptReader::checkPerfScriptType(StringRef FileName) {
// Detect sample with call stack
int32_t Count = 0;
- while (!TraceIt.isAtEoF() &&
- !TraceIt.getCurrentLine().ltrim().getAsInteger(16, FrameAddr)) {
+ while (!TraceIt.isAtEoF()) {
+ StringRef FrameStr = TraceIt.getCurrentLine().ltrim();
+ // Strip optional buildid prefix for format detection.
+ size_t ColonPos = FrameStr.find(':');
+ if (ColonPos != StringRef::npos)
+ FrameStr = FrameStr.substr(ColonPos + 1);
+ FrameStr.consume_front("0x");
+ if (FrameStr.getAsInteger(16, FrameAddr))
+ break;
Count++;
TraceIt.advance();
}
``````````
</details>
https://github.com/llvm/llvm-project/pull/190863
More information about the llvm-branch-commits
mailing list