[llvm] [Bolt] Add a new hidden option to perf2bolt for testing purpose (PR #163785)
Ádám Kallai via llvm-commits
llvm-commits at lists.llvm.org
Mon Dec 8 08:31:31 PST 2025
https://github.com/kaadam updated https://github.com/llvm/llvm-project/pull/163785
>From 085edf79e29ef720fd77548ecd7a909028225edb 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/4] 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 db0f6903185b7..60f2962423e94 100644
--- a/bolt/include/bolt/Profile/DataAggregator.h
+++ b/bolt/include/bolt/Profile/DataAggregator.h
@@ -158,6 +158,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 6b969011df589..4d07e9fa0afa0 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 ee2f07471a334645622465accf0a1474f664e8d9 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/4] [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 60f2962423e94..ad965a39402a9 100644
--- a/bolt/include/bolt/Profile/DataAggregator.h
+++ b/bolt/include/bolt/Profile/DataAggregator.h
@@ -149,8 +149,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;
@@ -239,6 +255,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();
@@ -445,6 +464,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
@@ -595,6 +643,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 4d07e9fa0afa0..de03860b261bf 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 f3b8c176797e7874789c768dcae5215d5562805d Mon Sep 17 00:00:00 2001
From: Adam Kallai <kadam at inf.u-szeged.hu>
Date: Mon, 8 Dec 2025 16:47:24 +0100
Subject: [PATCH 3/4] [BOLT][Perf2bolt] Add support to read and parse
pre-aggregated profile
This PR implements the functionality to read and parse a pre-paresed
perf-script profile which was made by Perf2bolt's
'--generate-perf-text-data' option.
It helps to add support for large ARM Spe end-to-end tests.
Why does the test need to have a textual format Spe profile?
- To collect an Arm Spe profile by Linux Perf, it needs to have
an arm developer device which has Spe support.
- To decode Spe data, it also needs to have the proper version of
Linux Perf.
The minimum required version of Linux Perf is v6.15.
Bypassing these technical difficulties, that easier to prove
a pre-generated textual profile format.
How should generate this type of profile?
1) You can use Perf2bolt itself to generate a pre-parsed perf-script profile
in textual format.
$ perf2bolt BINARY -p perf.data -o test.text --spe --generate-perf-text-data
2) Perf2bolt is able to work with this type of profile:
$ perf2bolt BINARY -o test.fdata -p test.text --spe -perf-text-data
---
bolt/include/bolt/Profile/DataAggregator.h | 31 +++--
bolt/lib/Profile/DataAggregator.cpp | 133 +++++++++++++++++++--
2 files changed, 145 insertions(+), 19 deletions(-)
diff --git a/bolt/include/bolt/Profile/DataAggregator.h b/bolt/include/bolt/Profile/DataAggregator.h
index ad965a39402a9..1f34482ceac04 100644
--- a/bolt/include/bolt/Profile/DataAggregator.h
+++ b/bolt/include/bolt/Profile/DataAggregator.h
@@ -168,17 +168,19 @@ 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{};
+ uint64_t Length{0};
+ uint64_t Offset{0};
};
/// 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::MEN_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
@@ -464,6 +466,19 @@ class DataAggregator : public DataReader {
/// an external tool.
std::error_code parsePreAggregatedLBRSamples();
+ /// Coordinate reading and parsing pre-parsed perf-script trace created by
+ /// Perf2bolt's '--generate-perf-text-data' option.
+ ///
+ /// We process the special header of the pre-parsed profile first to
+ /// determine an offset/length pairs for each events.
+ /// Later based on these information we open only a slice of the pre-parsed file
+ /// which belongs to the required event.
+ /// After the preparation parsePerfData function is invoked.
+ void parsePerfTextData(BinaryContext &BC);
+
+ /// Parse the header of the perf text file.
+ std::error_code parsePerfTextFileHeader();
+
/// 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
diff --git a/bolt/lib/Profile/DataAggregator.cpp b/bolt/lib/Profile/DataAggregator.cpp
index de03860b261bf..91b8d0e335b0d 100644
--- a/bolt/lib/Profile/DataAggregator.cpp
+++ b/bolt/lib/Profile/DataAggregator.cpp
@@ -121,11 +121,11 @@ cl::opt<bool> ReadPreAggregated(
"pa", cl::desc("skip perf and read data from a pre-aggregated file format"),
cl::cat(AggregatorCategory));
-cl::opt<std::string>
- ReadPerfEvents("perf-script-events",
- cl::desc("skip perf event collection by supplying a "
- "perf-script output in a textual format"),
- cl::ReallyHidden, cl::init(""), cl::cat(AggregatorCategory));
+cl::opt<bool>
+ ReadPerfTextData("perf-text-data",
+ cl::desc("skip perf event collection by reading a "
+ "pre-parsed perf-script output in a textual format"),
+ cl::Hidden, cl::cat(AggregatorCategory));
cl::opt<bool> GeneratePerfTextProfile(
"generate-perf-text-data",
@@ -212,7 +212,7 @@ void DataAggregator::start() {
// Don't launch perf for pre-aggregated files or when perf input is specified
// by the user.
- if (opts::ReadPreAggregated || !opts::ReadPerfEvents.empty())
+ if (opts::ReadPreAggregated || !opts::ReadPerfTextData)
return;
findPerfExecutable();
@@ -400,6 +400,98 @@ void DataAggregator::parsePreAggregated() {
}
}
+std::error_code DataAggregator::parsePerfTextFileHeader() {
+ size_t LineEnd = ParsingBuf.find_first_of("\n");
+ if (LineEnd == StringRef::npos) {
+ reportError("expected rest of line");
+ Diag << "Found: " << ParsingBuf << "\n";
+ return make_error_code(llvm::errc::io_error);
+ }
+ StringRef HeaderLine = ParsingBuf.substr(0, LineEnd);
+ size_t HeaderLineSize = HeaderLine.size() + 1;
+
+ if (!HeaderLine.consume_front(PerfTextMagicStr)) {
+ reportError("expected 'PERFTEXT' magic string");
+ Diag << "Found: " << HeaderLine << "\n";
+ return make_error_code(llvm::errc::io_error);
+ }
+ Col += PerfTextMagicStr.size();
+
+ SmallVector<StringRef, 5> Events;
+ HeaderLine.ltrim().split(Events, ";", -1, false);
+
+ if (Events.empty()) {
+ reportError("missing events=sizes content");
+ Diag << "Found: " << HeaderLine << "\n";
+ return make_error_code(llvm::errc::io_error);
+ }
+
+ uint64_t Offset = HeaderLineSize;
+ uint64_t Length = 0;
+ for (StringRef EV : Events) {
+ StringRef EventStr, LengthStr;
+ std::tie(EventStr, LengthStr) = EV.split("=");
+
+ PerfProcessInfo *PPI =
+ StringSwitch<PerfProcessInfo *>(EventStr)
+ .Case(PerfProcessInfo::BuildIDEventStr, &BuildIDProcessInfo)
+ .Case(PerfProcessInfo::MainEventStr, &MainEventsPPI)
+ .Case(PerfProcessInfo::MemEventStr, &MemEventsPPI)
+ .Case(PerfProcessInfo::MMapEventStr, &MMapEventsPPI)
+ .Case(PerfProcessInfo::TaskEventsStr, &TaskEventsPPI)
+ .Default(nullptr);
+
+ if (!PPI) {
+ reportError("malformed text profile");
+ Diag << "Found: " << EV << "in " << HeaderLine << "\n";
+ return make_error_code(llvm::errc::io_error);
+ }
+
+ if (LengthStr.getAsInteger(10, Length)) {
+ reportError("corrupted decimal number");
+ Diag << "Found: " << LengthStr << "in" << HeaderLine << "\n";
+ return make_error_code(llvm::errc::io_error);
+ }
+ PPI->Offset = Offset;
+ PPI->Length = Length;
+ Offset = Offset + Length;
+ Col += EV.size();
+ }
+ uint64_t FS = getFileSize(Filename);
+ if (FS != Offset) {
+ reportError("corrupted perf text profile");
+ Diag << "Found: " << FS << "!=" << Offset << "\n";
+ return make_error_code(llvm::errc::io_error);
+ }
+ return std::error_code();
+}
+
+void DataAggregator::parsePerfTextData(BinaryContext &BC) {
+ outs() << "PERF2BOLT: parsing a hybrid perf-script events...\n";
+ NamedRegionTimer T("parsePerfTextData", "Parsing perf-script events",
+ TimerGroupName, TimerGroupDesc, opts::TimeAggregator);
+
+ ErrorOr<std::unique_ptr<MemoryBuffer>> MB =
+ MemoryBuffer::getFileOrSTDIN(Filename);
+ if (std::error_code EC = MB.getError()) {
+ errs() << "PERF2BOLT-ERROR: cannot open " << Filename << ": "
+ << EC.message() << "\n";
+ exit(1);
+ }
+
+ ParsingBuf = (*MB)->getBuffer();
+ Col = 0;
+ Line = 1;
+ if (std::error_code EC = parsePerfTextFileHeader()) {
+ errs() << "PERF2BOLT-ERROR: failed to parse text header" << EC.message()
+ << "\n";
+ exit(1);
+ }
+
+ parsePerfData(BC);
+}
+
+
void DataAggregator::generatePerfTextData() {
std::error_code EC;
raw_fd_ostream OutFile(opts::OutputFilename, EC, sys::fs::OpenFlags::OF_None);
@@ -476,13 +568,30 @@ void DataAggregator::filterBinaryMMapInfo() {
int DataAggregator::prepareToParse(StringRef Name, PerfProcessInfo &Process,
PerfProcessErrorCallbackTy Callback) {
- if (!opts::ReadPerfEvents.empty()) {
- outs() << "PERF2BOLT: using pre-processed perf events for '" << Name
- << "' (perf-script-events)\n";
- ParsingBuf = opts::ReadPerfEvents;
- return 0;
+ if (opts::ReadPerfTextData) {
+ if (Process.Length > 0) {
+ ErrorOr<std::unique_ptr<MemoryBuffer>> MB =
+ MemoryBuffer::getFileSlice(Filename, Process.Length, Process.Offset);
+ if (std::error_code EC = MB.getError()) {
+ errs() << "Cannot open " << Process.Type << ": " << EC.message() << "\n";
+ exit(1);
+ }
+
+ FileBuf = std::move(*MB);
+ ParsingBuf = FileBuf->getBuffer();
+ Col = 0;
+ Line = 1;
+ return 0;
+ }
+
+ errs() << "PERF2BOLT: missing pre-parsed data for " << Process.Type
+ << "\n";
+ errs() << "PERF2BOLT: please check whether your input file was generated "
+ "with --generate-perf-text-data option. \n";
+ exit(1);
}
+
std::string Error;
outs() << "PERF2BOLT: waiting for perf " << Name
<< " collection to finish...\n";
@@ -663,6 +772,8 @@ Error DataAggregator::preprocessProfile(BinaryContext &BC) {
generatePerfTextData();
} else if (opts::ReadPreAggregated) {
parsePreAggregated();
+ } else if (opts::ReadPerfTextData) {
+ parsePerfTextData(BC);
} else {
parsePerfData(BC);
}
>From 40ba64871100566f439785fb137221e7b73a8775 Mon Sep 17 00:00:00 2001
From: Adam Kallai <kadam at inf.u-szeged.hu>
Date: Mon, 8 Dec 2025 17:03:12 +0100
Subject: [PATCH 4/4] Update PerfSpeEvent unittest
---
bolt/unittests/Profile/PerfSpeEvents.cpp | 30 +++++++++++++-----------
1 file changed, 16 insertions(+), 14 deletions(-)
diff --git a/bolt/unittests/Profile/PerfSpeEvents.cpp b/bolt/unittests/Profile/PerfSpeEvents.cpp
index 4f060cd0aa7c8..b736c38f691c8 100644
--- a/bolt/unittests/Profile/PerfSpeEvents.cpp
+++ b/bolt/unittests/Profile/PerfSpeEvents.cpp
@@ -22,7 +22,7 @@ using namespace llvm::object;
using namespace llvm::ELF;
namespace opts {
-extern cl::opt<std::string> ReadPerfEvents;
+extern cl::opt<bool> ReadPerfTextData;
extern cl::opt<bool> ArmSPE;
} // namespace opts
@@ -92,10 +92,10 @@ struct PerfSpeEventsTestHelper : public testing::Test {
/// Parse and check SPE brstack as LBR.
void parseAndCheckBrstackEvents(
- uint64_t PID,
+ uint64_t PID, StringRef &Buffer,
const std::vector<std::pair<Trace, TakenBranchInfo>> &ExpectedSamples) {
DataAggregator DA("<pseudo input>");
- DA.ParsingBuf = opts::ReadPerfEvents;
+ DA.ParsingBuf = Buffer;
DA.BC = BC.get();
DataAggregator::MMapInfo MMap;
DA.BinaryMMapInfo.insert(std::make_pair(PID, MMap));
@@ -134,14 +134,15 @@ TEST_F(PerfSpeEventsTestHelper, SpeBranchesWithBrstack) {
// ```
opts::ArmSPE = true;
- opts::ReadPerfEvents = " 1234 0xa001/0xa002/PN/-/-/10/COND/-\n"
- " 1234 0xb001/0xb002/P/-/-/4/RET/-\n"
- " 1234 0xc456/0xc789/P/-/-/13/-/-\n"
- " 1234 0xd123/0xd456/M/-/-/7/RET/-\n"
- " 1234 0xe001/0xe002/P/-/-/14/RET/-\n"
- " 1234 0xd123/0xd456/M/-/-/7/RET/-\n"
- " 1234 0xf001/0xf002/MN/-/-/8/COND/-\n"
- " 1234 0xc456/0xc789/M/-/-/13/-/-\n";
+ opts::ReadPerfTextData = true;
+ StringRef Buffer = " 1234 0xa001/0xa002/PN/-/-/10/COND/-\n"
+ " 1234 0xb001/0xb002/P/-/-/4/RET/-\n"
+ " 1234 0xc456/0xc789/P/-/-/13/-/-\n"
+ " 1234 0xd123/0xd456/M/-/-/7/RET/-\n"
+ " 1234 0xe001/0xe002/P/-/-/14/RET/-\n"
+ " 1234 0xd123/0xd456/M/-/-/7/RET/-\n"
+ " 1234 0xf001/0xf002/MN/-/-/8/COND/-\n"
+ " 1234 0xc456/0xc789/M/-/-/13/-/-\n";
// ExpectedSamples contains the aggregated information about
// a branch {{Branch From, To}, {TakenCount, MispredCount}}.
@@ -158,7 +159,7 @@ TEST_F(PerfSpeEventsTestHelper, SpeBranchesWithBrstack) {
{{0xe001, 0xe002, Trace::BR_ONLY}, {1, 0}},
{{0xf001, 0xf002, Trace::BR_ONLY}, {1, 1}}};
- parseAndCheckBrstackEvents(1234, ExpectedSamples);
+ parseAndCheckBrstackEvents(1234, Buffer, ExpectedSamples);
}
TEST_F(PerfSpeEventsTestHelper, SpeBranchesWithBrstackAndPbt) {
@@ -174,7 +175,8 @@ TEST_F(PerfSpeEventsTestHelper, SpeBranchesWithBrstackAndPbt) {
// ```
opts::ArmSPE = true;
- opts::ReadPerfEvents =
+ opts::ReadPerfTextData = true;
+ StringRef Buffer =
// "<PID> <SRC>/<DEST>/PN/-/-/10/COND/- <NULL>/<PBT>/-/-/-/0//-\n"
" 4567 0xa002/0xa003/PN/-/-/10/COND/- 0x0/0xa001/-/-/-/0//-\n"
" 4567 0xb002/0xb003/P/-/-/4/RET/- 0x0/0xb001/-/-/-/0//-\n"
@@ -246,7 +248,7 @@ TEST_F(PerfSpeEventsTestHelper, SpeBranchesWithBrstackAndPbt) {
{{0xf002, 0xf003, Trace::BR_ONLY}, {1, 1}},
{{0x0, 0xf001, 0xf002}, {1, 0}}};
- parseAndCheckBrstackEvents(4567, ExpectedSamples);
+ parseAndCheckBrstackEvents(4567, Buffer, ExpectedSamples);
}
#endif
More information about the llvm-commits
mailing list