[llvm] [BOLT][Perf2bolt] Add support to generate pre-parsed perf data (PR #171144)
Ádám Kallai via llvm-commits
llvm-commits at lists.llvm.org
Mon Feb 9 05:12:13 PST 2026
https://github.com/kaadam updated https://github.com/llvm/llvm-project/pull/171144
>From 7666df5b3e9345fdb001eea3dbac041be6e7b99f Mon Sep 17 00:00:00 2001
From: Adam Kallai <kadam at inf.u-szeged.hu>
Date: Mon, 8 Dec 2025 11:28:43 +0100
Subject: [PATCH 1/5] Spawn buildid-list perf job at start
---
bolt/include/bolt/Profile/DataAggregator.h | 1 +
bolt/lib/Profile/DataAggregator.cpp | 4 ++--
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/bolt/include/bolt/Profile/DataAggregator.h b/bolt/include/bolt/Profile/DataAggregator.h
index 666df9eb18ed8..8bdb319748c61 100644
--- a/bolt/include/bolt/Profile/DataAggregator.h
+++ b/bolt/include/bolt/Profile/DataAggregator.h
@@ -163,6 +163,7 @@ class DataAggregator : public DataReader {
};
/// Process info for spawned processes
+ PerfProcessInfo BuildIDProcessInfo;
PerfProcessInfo MainEventsPPI;
PerfProcessInfo MemEventsPPI;
PerfProcessInfo MMapEventsPPI;
diff --git a/bolt/lib/Profile/DataAggregator.cpp b/bolt/lib/Profile/DataAggregator.cpp
index a616d9db9db0e..7c6abe435fa2e 100644
--- a/bolt/lib/Profile/DataAggregator.cpp
+++ b/bolt/lib/Profile/DataAggregator.cpp
@@ -233,6 +233,8 @@ void DataAggregator::start() {
launchPerfProcess("task events", TaskEventsPPI,
"script --show-task-events --no-itrace");
+
+ launchPerfProcess("buildid list", BuildIDProcessInfo, "buildid-list");
}
void DataAggregator::abort() {
@@ -303,8 +305,6 @@ void DataAggregator::processFileBuildID(StringRef FileBuildID) {
errs() << "PERF-ERROR: return code " << ReturnCode << "\n" << ErrBuf;
};
- PerfProcessInfo BuildIDProcessInfo;
- launchPerfProcess("buildid list", BuildIDProcessInfo, "buildid-list");
if (prepareToParse("buildid", BuildIDProcessInfo, WarningCallback))
return;
>From 0b15aad46d264c7ee50fb29ac368a72b7e3706e8 Mon Sep 17 00:00:00 2001
From: Adam Kallai <kadam at inf.u-szeged.hu>
Date: Mon, 8 Dec 2025 12:22:04 +0100
Subject: [PATCH 2/5] [BOLT][Perf2bolt] Add support to generate pre-parsed perf
data
The generator relies on the aggregator work to spawn the required
perf-script jobs based on the the aggregation type, and merges
the results of the pref-script jobs into a single file.
This hybrid profile will contain all required events such as BuildID,
MMAP, TASK, Branch/BrStack, or Memory event for the aggregation.
The generator also creates a file header, where these events
are listed along with the length information of their contents.
To generate a pre-parsed perf data as an input for BasicAggregation:
`perf2bolt -p perf.data -o perf.text --ba --generate-perf-text-data`
Or for Spe BranchAggregation:
`perf2bolt -p perf.data -o perf.text --spe --generate-perf-text-data`
The results place into the perf.text output file.
---
bolt/include/bolt/Profile/DataAggregator.h | 70 ++++++++++++++++++++++
bolt/lib/Profile/DataAggregator.cpp | 69 ++++++++++++++++++++-
2 files changed, 138 insertions(+), 1 deletion(-)
diff --git a/bolt/include/bolt/Profile/DataAggregator.h b/bolt/include/bolt/Profile/DataAggregator.h
index 8bdb319748c61..99d32d1abc3d3 100644
--- a/bolt/include/bolt/Profile/DataAggregator.h
+++ b/bolt/include/bolt/Profile/DataAggregator.h
@@ -154,8 +154,24 @@ class DataAggregator : public DataReader {
/// Perf utility full path name
std::string PerfPath;
+ enum PerfProcessType {
+ BUILDIDS = 0,
+ MAIN_EVENTS,
+ MEN_EVENTS,
+ MMAP_EVENTS,
+ TASK_EVENTS
+ };
+ friend raw_ostream &operator<<(raw_ostream &OS, const PerfProcessType &T);
+
/// Perf process spawning bookkeeping
struct PerfProcessInfo {
+ static constexpr StringLiteral BuildIDEventStr = "BUILDIDS";
+ static constexpr StringLiteral MainEventStr = "MAIN";
+ static constexpr StringLiteral MemEventStr = "MEM";
+ static constexpr StringLiteral MMapEventStr = "MMAP";
+ static constexpr StringLiteral TaskEventsStr = "TASK";
+
+ enum PerfProcessType Type;
bool IsFinished{false};
sys::ProcessInfo PI;
SmallVector<char, 256> StdoutPath;
@@ -244,6 +260,9 @@ class DataAggregator : public DataReader {
/// parsing.
void launchPerfProcess(StringRef Name, PerfProcessInfo &PPI, StringRef Args);
+ /// Helps to generate pre-parsed perf text profile.
+ uint64_t getFileSize(const StringRef File);
+
/// Delete all temporary files created to hold the output generated by spawned
/// subprocesses during the aggregation job
void deleteTempFiles();
@@ -450,6 +469,35 @@ class DataAggregator : public DataReader {
/// an external tool.
std::error_code parsePreAggregatedLBRSamples();
+ /// Dump pre-parsed perf profile data into a single file.
+ /// The generator relies on the aggregator work to spawn the required
+ /// perf-script jobs based on the the aggregation type, and merges
+ /// the results of the pref-script jobs into a single file.
+ /// This hybrid profile contains all required events such as BuildID,
+ /// MMAP, TASK, Branch/BrStack, or Memory for the aggregation.
+ /// The generator also creates a file header, where these events
+ /// are listed along with the length information of their contents.
+ /// This is how a pre-parsed profile data looks like for Basic Aggregation:
+ ///
+ /// perf2bolt -p perf.data -o perf.text --ba --generate-perf-text-data
+ ///
+ /// PERFTEXT BUILDIDS=55;MMAP=2523121;MAIN=6426;TASK=352203;
+ /// 68c3da33ca43d5a74d501b5ea0012f782e04096e /example/bin1
+ /// c3a8496f2347b468a54a21072dc6cde7f0d88c6c /example/bin2
+ /// ...
+ /// bin1 20470 ... PERF_RECORD_MMAP2 20470/20470: ... r-xp /example/bin1
+ /// bin1 20470 ... PERF_RECORD_MMAP2 20470/20470: ... r-xp [vdso]
+ /// ...
+ /// bin1 20470 ... PERF_RECORD_COMM exec: bin1:20470/20470
+ /// bin1 20470 ... PERF_RECORD_EXIT(20470:20470):(20469:20469)
+ /// ...
+ /// 20470 branch: ffffffd1a4764d04 ffffffd1a4764cfc
+ /// 20470 branch: ffffffd1a44777f4 ffffffd1a4fc8af0
+ /// 20470 branch: ffffffd1a477cd14 ffffffd1a477cd00
+ /// 20470 branch: ffffffd1a4400f58 ffffffd1a4400f7c
+ /// ...
+ void generatePerfTextData();
+
/// If \p Address falls into the binary address space based on memory
/// mapping info \p MMI, then adjust it for further processing by subtracting
/// the base load address. External addresses, i.e. addresses that do not
@@ -600,6 +648,28 @@ inline raw_ostream &operator<<(raw_ostream &OS,
OS << " ... " << Twine::utohexstr(T.To);
return OS;
}
+
+inline raw_ostream &operator<<(raw_ostream &OS,
+ const DataAggregator::PerfProcessType &T) {
+ switch (T) {
+ case DataAggregator::PerfProcessType::BUILDIDS:
+ OS << DataAggregator::PerfProcessInfo::BuildIDEventStr;
+ break;
+ case DataAggregator::PerfProcessType::MAIN_EVENTS:
+ OS << DataAggregator::PerfProcessInfo::MainEventStr;
+ break;
+ case DataAggregator::PerfProcessType::MEN_EVENTS:
+ OS << DataAggregator::PerfProcessInfo::MemEventStr;
+ break;
+ case DataAggregator::PerfProcessType::MMAP_EVENTS:
+ OS << DataAggregator::PerfProcessInfo::MMapEventStr;
+ break;
+ case DataAggregator::PerfProcessType::TASK_EVENTS:
+ OS << DataAggregator::PerfProcessInfo::TaskEventsStr;
+ break;
+ }
+ return OS;
+}
} // namespace bolt
} // namespace llvm
diff --git a/bolt/lib/Profile/DataAggregator.cpp b/bolt/lib/Profile/DataAggregator.cpp
index 7c6abe435fa2e..3d6c980f3cfd4 100644
--- a/bolt/lib/Profile/DataAggregator.cpp
+++ b/bolt/lib/Profile/DataAggregator.cpp
@@ -127,6 +127,11 @@ cl::opt<std::string>
"perf-script output in a textual format"),
cl::ReallyHidden, cl::init(""), cl::cat(AggregatorCategory));
+cl::opt<bool> GeneratePerfTextProfile(
+ "generate-perf-text-data",
+ cl::desc("Dump perf-script jobs' output into output file"), cl::Hidden,
+ cl::cat(AggregatorCategory));
+
static cl::opt<bool>
TimeAggregator("time-aggr",
cl::desc("time BOLT aggregator"),
@@ -141,6 +146,8 @@ namespace {
const char TimerGroupName[] = "aggregator";
const char TimerGroupDesc[] = "Aggregator";
+constexpr const StringLiteral PerfTextMagicStr = "PERFTEXT";
+
std::vector<SectionNameAndRange> getTextSections(const BinaryContext *BC) {
std::vector<SectionNameAndRange> sections;
for (BinarySection &Section : BC->sections()) {
@@ -169,6 +176,17 @@ void deleteTempFile(const std::string &FileName) {
}
}
+uint64_t DataAggregator::getFileSize(const StringRef File) {
+ uint64_t Size;
+ std::error_code EC = sys::fs::file_size(File, Size);
+ if (EC) {
+ errs() << "unable to obtain file size: " << EC.message() << "\n";
+ deleteTempFiles();
+ exit(1);
+ }
+ return Size;
+}
+
void DataAggregator::deleteTempFiles() {
for (std::string &FileName : TempFiles)
deleteTempFile(FileName);
@@ -382,6 +400,53 @@ void DataAggregator::parsePreAggregated() {
}
}
+void DataAggregator::generatePerfTextData() {
+ std::error_code EC;
+ raw_fd_ostream OutFile(opts::OutputFilename, EC, sys::fs::OpenFlags::OF_None);
+ if (EC) {
+ errs() << "error opening output file: " << EC.message() << "\n";
+ deleteTempFiles();
+ exit(1);
+ }
+
+ SmallVector<PerfProcessInfo *, 5> ProcessInfos = {
+ &BuildIDProcessInfo, &MMapEventsPPI, &MainEventsPPI, &TaskEventsPPI};
+ if (opts::ParseMemProfile)
+ ProcessInfos.push_back(&MemEventsPPI);
+
+ // Create a file header as a table of the contents
+ // PERFTEXT;EVENT1={$SIZE};EVENT2={$SIZE}...
+ OutFile << PerfTextMagicStr << ";";
+ for (const auto PPI : ProcessInfos) {
+ std::string Error;
+ sys::Wait(PPI->PI, std::nullopt, &Error);
+ if (!Error.empty()) {
+ errs() << "PERF-ERROR: " << PerfPath << ": " << Error << "\n";
+ deleteTempFiles();
+ exit(1);
+ }
+ uint64_t FS = getFileSize(PPI->StdoutPath.data());
+ OutFile << PPI->Type << "=" << FS << ";";
+ }
+ OutFile << "\n";
+
+ // Merge all perf-scripts jobs' output into the single OutputFile
+ for (const auto PPI : ProcessInfos) {
+ ErrorOr<std::unique_ptr<MemoryBuffer>> MB =
+ MemoryBuffer::getFileOrSTDIN(PPI->StdoutPath.data());
+ if (std::error_code EC = MB.getError()) {
+ errs() << "Cannot open " << PPI->StdoutPath.data() << ": " << EC.message()
+ << "\n";
+ deleteTempFiles();
+ exit(1);
+ }
+ OutFile << (*MB)->getBuffer();
+ }
+ OutFile.close();
+ deleteTempFiles();
+ exit(0);
+}
+
void DataAggregator::filterBinaryMMapInfo() {
if (opts::FilterPID) {
auto MMapInfoIter = BinaryMMapInfo.find(opts::FilterPID);
@@ -594,7 +659,9 @@ void DataAggregator::imputeFallThroughs() {
Error DataAggregator::preprocessProfile(BinaryContext &BC) {
this->BC = &BC;
- if (opts::ReadPreAggregated) {
+ if (opts::GeneratePerfTextProfile) {
+ generatePerfTextData();
+ } else if (opts::ReadPreAggregated) {
parsePreAggregated();
} else {
parsePerfData(BC);
>From cd5bdf40a345f73ca225ff01a712c4bcfc867fb6 Mon Sep 17 00:00:00 2001
From: Adam Kallai <kadam at inf.u-szeged.hu>
Date: Mon, 19 Jan 2026 16:25:07 +0100
Subject: [PATCH 3/5] Address reviewers 1
---
bolt/include/bolt/Profile/DataAggregator.h | 62 +++++++++++++---------
bolt/lib/Profile/DataAggregator.cpp | 37 ++++++++-----
2 files changed, 62 insertions(+), 37 deletions(-)
diff --git a/bolt/include/bolt/Profile/DataAggregator.h b/bolt/include/bolt/Profile/DataAggregator.h
index 99d32d1abc3d3..4510d7b85abe7 100644
--- a/bolt/include/bolt/Profile/DataAggregator.h
+++ b/bolt/include/bolt/Profile/DataAggregator.h
@@ -157,7 +157,7 @@ class DataAggregator : public DataReader {
enum PerfProcessType {
BUILDIDS = 0,
MAIN_EVENTS,
- MEN_EVENTS,
+ MEM_EVENTS,
MMAP_EVENTS,
TASK_EVENTS
};
@@ -173,17 +173,17 @@ class DataAggregator : public DataReader {
enum PerfProcessType Type;
bool IsFinished{false};
- sys::ProcessInfo PI;
- SmallVector<char, 256> StdoutPath;
- SmallVector<char, 256> StderrPath;
+ sys::ProcessInfo PI{};
+ SmallVector<char, 256> StdoutPath{};
+ SmallVector<char, 256> StderrPath{};
};
/// Process info for spawned processes
- PerfProcessInfo BuildIDProcessInfo;
- PerfProcessInfo MainEventsPPI;
- PerfProcessInfo MemEventsPPI;
- PerfProcessInfo MMapEventsPPI;
- PerfProcessInfo TaskEventsPPI;
+ PerfProcessInfo BuildIDProcessInfo = {PerfProcessType::BUILDIDS};
+ PerfProcessInfo MainEventsPPI = {PerfProcessType::MAIN_EVENTS};
+ PerfProcessInfo MemEventsPPI = {PerfProcessType::MEM_EVENTS};
+ PerfProcessInfo MMapEventsPPI = {PerfProcessType::MMAP_EVENTS};
+ PerfProcessInfo TaskEventsPPI = {PerfProcessType::TASK_EVENTS};
/// Kernel VM starts at fixed based address
/// https://www.kernel.org/doc/Documentation/x86/x86_64/mm.txt
@@ -472,29 +472,41 @@ class DataAggregator : public DataReader {
/// Dump pre-parsed perf profile data into a single file.
/// The generator relies on the aggregator work to spawn the required
/// perf-script jobs based on the the aggregation type, and merges
- /// the results of the pref-script jobs into a single file.
+ /// their results into a single file.
/// This hybrid profile contains all required events such as BuildID,
- /// MMAP, TASK, Branch/BrStack, or Memory for the aggregation.
+ /// MMAP, TASK, MAIN (brstack or basic samples), or MEM for the aggregation.
/// The generator also creates a file header, where these events
/// are listed along with the length information of their contents.
- /// This is how a pre-parsed profile data looks like for Basic Aggregation:
+ /// The given length numbers in the header are in bytes, they are used
+ /// as an offset int the pre-parsed profile.
+ /// Some of these events are essential to be presented in the file.
+ /// Please see a short summary below:
+ /// MEM: Optional. Parsing memory profile is enabled by default, unless
+ /// '--itrace' aggregation is set (like Arm SPE). In the latter case
+ /// MEM profile won't be added into the pre-parsed profile.
+ /// MMAP: Compulsory, the mmap data is required to be in the file.
+ /// BUILDID: Ignored (you should use --ignore-build-id),
+ /// if buildid information doesn't exist in the input profile.
+ /// TASK: When task related data exists in the input profile,
+ /// Perf2bolt will always parse it.
+ /// MAIN: Compulsory; the MAIN events always have to be represented in the
+ /// file. Main events could be either 'brstack' or 'basic' sample data
+ /// based on how it was collected by Linux Perf.
///
- /// perf2bolt -p perf.data -o perf.text --ba --generate-perf-text-data
+ /// Example how you can generate pre-parsed profile for 'basic' aggregation:
+ /// perf2bolt -p perf.data BINARY -o perf.text --ba --generate-perf-text-data
///
- /// PERFTEXT BUILDIDS=55;MMAP=2523121;MAIN=6426;TASK=352203;
- /// 68c3da33ca43d5a74d501b5ea0012f782e04096e /example/bin1
- /// c3a8496f2347b468a54a21072dc6cde7f0d88c6c /example/bin2
+ /// This is how a pre-parsed profile data looks like for Basic Aggregation:
+ /// PERFTEXT;BUILDIDS=50;MMAP=3000000;MAIN=5000;TASK=350000;
+ /// abcd1234 /example/bin1
/// ...
- /// bin1 20470 ... PERF_RECORD_MMAP2 20470/20470: ... r-xp /example/bin1
- /// bin1 20470 ... PERF_RECORD_MMAP2 20470/20470: ... r-xp [vdso]
+ /// bin1 1234 ... PERF_RECORD_MMAP2 1234/1234: ... r-xp /example/bin1
/// ...
- /// bin1 20470 ... PERF_RECORD_COMM exec: bin1:20470/20470
- /// bin1 20470 ... PERF_RECORD_EXIT(20470:20470):(20469:20469)
+ /// bin1 1234 ... PERF_RECORD_COMM exec: bin1:1234/1234
+ /// bin1 1234 ... PERF_RECORD_EXIT(1234:1234):(20469:20469)
/// ...
- /// 20470 branch: ffffffd1a4764d04 ffffffd1a4764cfc
- /// 20470 branch: ffffffd1a44777f4 ffffffd1a4fc8af0
- /// 20470 branch: ffffffd1a477cd14 ffffffd1a477cd00
- /// 20470 branch: ffffffd1a4400f58 ffffffd1a4400f7c
+ /// 1234 branch: ffffffd1a4764d04 ffffffd1a4764cfc
+ /// 1234 branch: ffffffd1a44777f4 ffffffd1a4fc8af0
/// ...
void generatePerfTextData();
@@ -658,7 +670,7 @@ inline raw_ostream &operator<<(raw_ostream &OS,
case DataAggregator::PerfProcessType::MAIN_EVENTS:
OS << DataAggregator::PerfProcessInfo::MainEventStr;
break;
- case DataAggregator::PerfProcessType::MEN_EVENTS:
+ case DataAggregator::PerfProcessType::MEM_EVENTS:
OS << DataAggregator::PerfProcessInfo::MemEventStr;
break;
case DataAggregator::PerfProcessType::MMAP_EVENTS:
diff --git a/bolt/lib/Profile/DataAggregator.cpp b/bolt/lib/Profile/DataAggregator.cpp
index 3d6c980f3cfd4..fbbb0c3e064d9 100644
--- a/bolt/lib/Profile/DataAggregator.cpp
+++ b/bolt/lib/Profile/DataAggregator.cpp
@@ -323,6 +323,7 @@ void DataAggregator::processFileBuildID(StringRef FileBuildID) {
errs() << "PERF-ERROR: return code " << ReturnCode << "\n" << ErrBuf;
};
+ // Extract buildid information from the input profile in the start() function.
if (prepareToParse("buildid", BuildIDProcessInfo, WarningCallback))
return;
@@ -414,35 +415,47 @@ void DataAggregator::generatePerfTextData() {
if (opts::ParseMemProfile)
ProcessInfos.push_back(&MemEventsPPI);
- // Create a file header as a table of the contents
- // PERFTEXT;EVENT1={$SIZE};EVENT2={$SIZE}...
- OutFile << PerfTextMagicStr << ";";
+ // Create a file header as a table of the contents.
+ // Initially pre-allocate enough space for the header at the beginning of
+ // the file.
+ // The header can be maximum 132 character, this number is pre-calculated,
+ // the sum of the length of the magic strings, event names, their sizes,
+ // and the field separators.
+ // PERFTEXT;EVENT1={0x$SIZE};EVENT2={0x$SIZE}...
+ // The size of the events are printed in hex format (16 width) in order to be
+ // predictable fixed length.
+ OutFile << std::string(132, ' ') << "\n";
+ std::string Header;
+ raw_string_ostream SS(Header);
+ SS << PerfTextMagicStr << ";";
for (const auto PPI : ProcessInfos) {
std::string Error;
+ auto PathData = PPI->StdoutPath.data();
sys::Wait(PPI->PI, std::nullopt, &Error);
if (!Error.empty()) {
errs() << "PERF-ERROR: " << PerfPath << ": " << Error << "\n";
deleteTempFiles();
exit(1);
}
- uint64_t FS = getFileSize(PPI->StdoutPath.data());
- OutFile << PPI->Type << "=" << FS << ";";
- }
- OutFile << "\n";
- // Merge all perf-scripts jobs' output into the single OutputFile
- for (const auto PPI : ProcessInfos) {
+ SS << PPI->Type << formatv("={0:x16};", getFileSize(PathData));
+
+ // Merge all perf-scripts jobs' output into the single OutputFile
ErrorOr<std::unique_ptr<MemoryBuffer>> MB =
- MemoryBuffer::getFileOrSTDIN(PPI->StdoutPath.data());
+ MemoryBuffer::getFileOrSTDIN(PathData);
if (std::error_code EC = MB.getError()) {
- errs() << "Cannot open " << PPI->StdoutPath.data() << ": " << EC.message()
- << "\n";
+ errs() << "Cannot open " << PathData << ": " << EC.message() << "\n";
deleteTempFiles();
exit(1);
}
OutFile << (*MB)->getBuffer();
}
+
+ OutFile.seek(0);
+ OutFile << Header;
OutFile.close();
+ outs() << "PERF2BOLT: Profile is saved to file " << opts::OutputFilename
+ << "\n";
deleteTempFiles();
exit(0);
}
>From 625f07aee1d76bbff2b85cf3bedc58098bbd1ada Mon Sep 17 00:00:00 2001
From: Adam Kallai <kadam at inf.u-szeged.hu>
Date: Wed, 21 Jan 2026 16:24:20 +0100
Subject: [PATCH 4/5] Update the description
---
bolt/include/bolt/Profile/DataAggregator.h | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/bolt/include/bolt/Profile/DataAggregator.h b/bolt/include/bolt/Profile/DataAggregator.h
index 4510d7b85abe7..b14cd67b86dcc 100644
--- a/bolt/include/bolt/Profile/DataAggregator.h
+++ b/bolt/include/bolt/Profile/DataAggregator.h
@@ -482,12 +482,13 @@ class DataAggregator : public DataReader {
/// Some of these events are essential to be presented in the file.
/// Please see a short summary below:
/// MEM: Optional. Parsing memory profile is enabled by default, unless
- /// '--itrace' aggregation is set (like Arm SPE). In the latter case
- /// MEM profile won't be added into the pre-parsed profile.
+ /// '--itrace' aggregation is set. In the latter case MEM profile
+ /// won't be added into the pre-parsed profile. Note that, currently
+ /// mem events only supported if they were gathered on X86_64.
/// MMAP: Compulsory, the mmap data is required to be in the file.
/// BUILDID: Ignored (you should use --ignore-build-id),
/// if buildid information doesn't exist in the input profile.
- /// TASK: When task related data exists in the input profile,
+ /// TASK: If task related data exists in the input profile,
/// Perf2bolt will always parse it.
/// MAIN: Compulsory; the MAIN events always have to be represented in the
/// file. Main events could be either 'brstack' or 'basic' sample data
@@ -497,7 +498,8 @@ class DataAggregator : public DataReader {
/// perf2bolt -p perf.data BINARY -o perf.text --ba --generate-perf-text-data
///
/// This is how a pre-parsed profile data looks like for Basic Aggregation:
- /// PERFTEXT;BUILDIDS=50;MMAP=3000000;MAIN=5000;TASK=350000;
+ /// PERFTEXT;BUILDIDS=0x0000000000000032;MMAP=0x000000000002DC6C0;MAIN=0x00000000000001388;
+ /// TASK=0x00000000000055730;MEM=0x0000000000000128;
/// abcd1234 /example/bin1
/// ...
/// bin1 1234 ... PERF_RECORD_MMAP2 1234/1234: ... r-xp /example/bin1
@@ -505,9 +507,11 @@ class DataAggregator : public DataReader {
/// bin1 1234 ... PERF_RECORD_COMM exec: bin1:1234/1234
/// bin1 1234 ... PERF_RECORD_EXIT(1234:1234):(20469:20469)
/// ...
- /// 1234 branch: ffffffd1a4764d04 ffffffd1a4764cfc
- /// 1234 branch: ffffffd1a44777f4 ffffffd1a4fc8af0
+ /// 1234 branch: abcd1234 abcd1237
+ /// 1234 branch: abcd5678 abce9876
/// ...
+ /// 1234 mem-loads: efgh1234 efgh1234
+ /// 1234 mem-loads: efgh4567 efgh8910
void generatePerfTextData();
/// If \p Address falls into the binary address space based on memory
>From c9167081fe68cc9240932a8ec0274fa958a4460a Mon Sep 17 00:00:00 2001
From: Adam Kallai <kadam at inf.u-szeged.hu>
Date: Mon, 26 Jan 2026 16:49:01 +0100
Subject: [PATCH 5/5] Print hex without 0x prefix
---
bolt/lib/Profile/DataAggregator.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/bolt/lib/Profile/DataAggregator.cpp b/bolt/lib/Profile/DataAggregator.cpp
index fbbb0c3e064d9..3c3da064769af 100644
--- a/bolt/lib/Profile/DataAggregator.cpp
+++ b/bolt/lib/Profile/DataAggregator.cpp
@@ -438,7 +438,7 @@ void DataAggregator::generatePerfTextData() {
exit(1);
}
- SS << PPI->Type << formatv("={0:x16};", getFileSize(PathData));
+ SS << PPI->Type << formatv("={0:x-16};", getFileSize(PathData));
// Merge all perf-scripts jobs' output into the single OutputFile
ErrorOr<std::unique_ptr<MemoryBuffer>> MB =
More information about the llvm-commits
mailing list