[llvm-branch-commits] [BOLT] Buffer DataAggregator diagnostics (PR #203464)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Thu Jun 11 23:23:35 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-bolt
Author: Amir Ayupov (aaupov)
<details>
<summary>Changes</summary>
To avoid mixed up error messages in multi-perf case, provide diagnostics
buffer and stream for each aggregator job.
Test Plan: updated pre-aggregated-perf.test
---
Full diff: https://github.com/llvm/llvm-project/pull/203464.diff
4 Files Affected:
- (modified) bolt/include/bolt/Profile/DataAggregator.h (+11-3)
- (modified) bolt/include/bolt/Profile/DataReader.h (+4-2)
- (modified) bolt/lib/Profile/DataAggregator.cpp (+53-29)
- (modified) bolt/test/X86/pre-aggregated-perf.test (+2-1)
``````````diff
diff --git a/bolt/include/bolt/Profile/DataAggregator.h b/bolt/include/bolt/Profile/DataAggregator.h
index 6f472f4084d50..fde7187973edd 100644
--- a/bolt/include/bolt/Profile/DataAggregator.h
+++ b/bolt/include/bolt/Profile/DataAggregator.h
@@ -51,7 +51,12 @@ class BoltAddressTranslation;
/// specified by the user.
class DataAggregator : public DataReader {
public:
- explicit DataAggregator(StringRef Filename) : DataReader(Filename) {}
+ explicit DataAggregator(StringRef Filename) : DataReader(Filename) {
+ InputFilenames.emplace_back(Filename);
+ }
+
+ DataAggregator(StringRef Filename, raw_ostream &Diag)
+ : DataReader(Filename, Diag) {}
~DataAggregator();
@@ -156,8 +161,8 @@ class DataAggregator : public DataReader {
std::vector<PerfMemSample> MemSamples;
/// Perf.data or pre-aggregated inputs to aggregate and merge into this
- /// reader.
- std::vector<std::string> InputFilenames;
+ /// reader. The first entry is the primary profile input.
+ SmallVector<std::string, 1> InputFilenames;
bool Parsed{false};
@@ -415,6 +420,9 @@ class DataAggregator : public DataReader {
/// Parse this aggregator's input file.
Error parseInput();
+ /// Parse all input files and merge successfully parsed profiles.
+ Error parseAllInputs(BinaryContext &BC);
+
/// Merge parsed profile data from another aggregation job.
void mergeFrom(const DataAggregator &Other);
diff --git a/bolt/include/bolt/Profile/DataReader.h b/bolt/include/bolt/Profile/DataReader.h
index 2661056772c0b..706de5a846df8 100644
--- a/bolt/include/bolt/Profile/DataReader.h
+++ b/bolt/include/bolt/Profile/DataReader.h
@@ -236,8 +236,10 @@ struct FuncBasicSampleData {
///
class DataReader : public ProfileReaderBase {
public:
- explicit DataReader(StringRef Filename)
- : ProfileReaderBase(Filename), Diag(errs()) {}
+ explicit DataReader(StringRef Filename) : DataReader(Filename, errs()) {}
+
+ DataReader(StringRef Filename, raw_ostream &Diag)
+ : ProfileReaderBase(Filename), Diag(Diag) {}
StringRef getReaderName() const override { return "branch profile reader"; }
diff --git a/bolt/lib/Profile/DataAggregator.cpp b/bolt/lib/Profile/DataAggregator.cpp
index dc716d15fb1e2..19bb63e88bdae 100644
--- a/bolt/lib/Profile/DataAggregator.cpp
+++ b/bolt/lib/Profile/DataAggregator.cpp
@@ -851,48 +851,49 @@ Error DataAggregator::parseInput() {
return errorCodeToError(parsePreAggregated());
}
-Error DataAggregator::preprocessProfile(BinaryContext &BC) {
- // Turn on heatmap building if requested by --heatmap flag.
- if (!opts::HeatmapMode && opts::HeatmapOutput.getNumOccurrences())
- opts::HeatmapMode = opts::HeatmapModeKind::HM_Optional;
-
- this->BC = &BC;
+Error DataAggregator::parseAllInputs(BinaryContext &BC) {
+ if (InputFilenames.size() == 1)
+ return parseInput();
- if (!opts::ReadPreAggregated)
- findPerfExecutable();
+ // Multiple inputs
- if (opts::ProfileFormat == opts::ProfileFormatKind::PF_PerfScript) {
- if (Error E = start())
- return E;
- if (Error E = generatePerfScriptData())
- return E;
- exit(0);
- }
+ // Struct keeping DataAggregator and its diagnostics buffer/stream.
+ struct AggregatorJob {
+ DataAggregator *DA{nullptr};
+ std::string DiagBuffer{};
+ raw_string_ostream DiagStream{DiagBuffer};
+ };
- SmallVector<DataAggregator *, 1> Aggregators(1, this);
+ // Create a job for each input file.
+ SmallVector<AggregatorJob *, 1> Jobs;
for (StringRef InputFilename : InputFilenames) {
- auto *DA = Aggregators.emplace_back(new DataAggregator(InputFilename));
- DA->BC = &BC;
- DA->PerfPath = PerfPath;
+ auto *Job = Jobs.emplace_back(new AggregatorJob());
+ Job->DA = new DataAggregator(InputFilename, Job->DiagStream);
+ Job->DA->BAT = BAT;
+ Job->DA->BC = &BC;
+ Job->DA->PerfPath = PerfPath;
}
ThreadPoolStrategy SavedStrategy = parallel::strategy;
parallel::strategy = hardware_concurrency(opts::PerfDataJobs);
Error ParseErrors =
- parallelForEachError(Aggregators, [](DataAggregator *DA) -> Error {
- if (Error E = DA->parseInput())
- return createStringError(inconvertibleErrorCode(), "%s: %s",
- DA->Filename.c_str(),
- toString(std::move(E)).c_str());
- DA->Parsed = true;
+ parallelForEachError(Jobs, [](AggregatorJob *Job) -> Error {
+ if (Error E = Job->DA->parseInput()) {
+ Job->DiagStream.flush();
+ return createStringError(
+ inconvertibleErrorCode(), "%s: %s%s", Job->DA->Filename.c_str(),
+ Job->DiagBuffer.c_str(), toString(std::move(E)).c_str());
+ }
+ Job->DA->Parsed = true;
return Error::success();
});
parallel::strategy = SavedStrategy;
- for (DataAggregator *DA : llvm::drop_begin(Aggregators)) {
- if (DA->Parsed)
- mergeFrom(*DA);
- delete DA;
+ for (AggregatorJob *Job : Jobs) {
+ if (Job->DA->Parsed)
+ mergeFrom(*Job->DA);
+ delete Job->DA;
+ delete Job;
}
if (!Parsed)
@@ -900,6 +901,29 @@ Error DataAggregator::preprocessProfile(BinaryContext &BC) {
handleAllErrors(std::move(ParseErrors), [](const ErrorInfoBase &EI) {
errs() << "PERF2BOLT-WARNING: " << EI.message() << "\n";
});
+ return Error::success();
+}
+
+Error DataAggregator::preprocessProfile(BinaryContext &BC) {
+ // Turn on heatmap building if requested by --heatmap flag.
+ if (!opts::HeatmapMode && opts::HeatmapOutput.getNumOccurrences())
+ opts::HeatmapMode = opts::HeatmapModeKind::HM_Optional;
+
+ this->BC = &BC;
+
+ if (!opts::ReadPreAggregated)
+ findPerfExecutable();
+
+ if (opts::ProfileFormat == opts::ProfileFormatKind::PF_PerfScript) {
+ if (Error E = start())
+ return E;
+ if (Error E = generatePerfScriptData())
+ return E;
+ exit(0);
+ }
+
+ if (Error E = parseAllInputs(BC))
+ return E;
markFunctionsWithProfile();
diff --git a/bolt/test/X86/pre-aggregated-perf.test b/bolt/test/X86/pre-aggregated-perf.test
index c2d5ea77f6703..06e57b475a4fd 100644
--- a/bolt/test/X86/pre-aggregated-perf.test
+++ b/bolt/test/X86/pre-aggregated-perf.test
@@ -37,11 +37,12 @@ RUN: llvm-bolt %t.exe --pa -perfdata %p/Inputs/pre-aggregated.txt -perfdata %p/I
RUN: llvm-bolt %t.exe --pa -p %p/Inputs/pre-aggregated.txt,%p/Inputs/pre-aggregated.txt -o %t.multi-perfdata-comma.null | FileCheck %s --check-prefix=CHECK-MULTI
RUN: not llvm-bolt %t.exe --pa -p %p/Inputs/pre-aggregated.txt -p %t.missing -o %t.multi-perfdata-missing.null 2>&1 | FileCheck %s --check-prefix=CHECK-MISSING
RUN: llvm-bolt %t.exe --pa -p %p/Inputs/pre-aggregated.txt -p %p/Inputs/pre-aggregated-bad-type.txt -o %t.multi-perfdata-bad-type.null 2>&1 | FileCheck %s --check-prefix=CHECK-BAD-TYPE-WARNING
+RUN: llvm-bolt %t.exe --pa -p %p/Inputs/pre-aggregated-bad-type.txt -p %p/Inputs/pre-aggregated.txt -o %t.multi-perfdata-bad-type.null 2>&1 | FileCheck %s --check-prefix=CHECK-BAD-TYPE-WARNING
CHECK: BOLT-INFO: 4 out of 7 functions in the binary (57.1%) have non-empty execution profile
CHECK-MULTI: BOLT-INFO: 4 out of 7 functions in the binary (57.1%) have non-empty execution profile
CHECK-MISSING: {{.*}}missing': No such file or directory.
-CHECK-BAD-TYPE-WARNING: PERF2BOLT-WARNING: {{.*}}pre-aggregated-bad-type.txt:
+CHECK-BAD-TYPE-WARNING: PERF2BOLT-WARNING: {{.*}}pre-aggregated-bad-type.txt: Error reading BOLT data input file: line 1, column 2: expected T, R, S, E, B, F, f or r
RUN: FileCheck %s -check-prefix=PERF2BOLT --input-file %t
RUN: FileCheck %s -check-prefix=NEWFORMAT --input-file %t.new
``````````
</details>
https://github.com/llvm/llvm-project/pull/203464
More information about the llvm-branch-commits
mailing list