Skip to content

Commit 8652608

Browse files
authored
[BOLT] Fix counts aggregation in merge-fdata (#119652)
merge-fdata used to consider misprediction count as part of "signature", or the aggregation key. This prevented it from collapsing profile lines with different misprediction counts, which resulted in duplicate `(from, to)` pairs with different misprediction and execution counts. Fix that by splitting out misprediction count and accumulating it separately. Test Plan: updated bolt/test/merge-fdata-lbr-mode.test
1 parent 97f4336 commit 8652608

File tree

2 files changed

+33
-14
lines changed

2 files changed

+33
-14
lines changed

bolt/test/merge-fdata-lbr-mode.test

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77
# RUN: FileCheck %s --input-file %t/merged.fdata
88

99
# CHECK-NOT: no_lbr
10-
# CHECK: main 2
10+
# CHECK: 1 main 0 1 main 2 1 3
1111

1212
#--- a.fdata
13-
main 1
13+
1 main 0 1 main 2 0 1
1414
#--- b.fdata
15-
main 1
15+
1 main 0 1 main 2 1 2

bolt/tools/merge-fdata/merge-fdata.cpp

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,17 @@ void mergeLegacyProfiles(const SmallVectorImpl<std::string> &Filenames) {
268268
std::optional<bool> BoltedCollection;
269269
std::optional<bool> NoLBRCollection;
270270
std::mutex BoltedCollectionMutex;
271-
typedef StringMap<uint64_t> ProfileTy;
271+
struct CounterTy {
272+
uint64_t Exec{0};
273+
uint64_t Mispred{0};
274+
CounterTy &operator+=(const CounterTy &O) {
275+
Exec += O.Exec;
276+
Mispred += O.Mispred;
277+
return *this;
278+
}
279+
CounterTy operator+(const CounterTy &O) { return *this += O; }
280+
};
281+
typedef StringMap<CounterTy> ProfileTy;
272282

273283
auto ParseProfile = [&](const std::string &Filename, auto &Profiles) {
274284
const llvm::thread::id tid = llvm::this_thread::get_id();
@@ -305,13 +315,18 @@ void mergeLegacyProfiles(const SmallVectorImpl<std::string> &Filenames) {
305315

306316
do {
307317
StringRef Line(FdataLine);
308-
size_t Pos = Line.rfind(" ");
309-
if (Pos == StringRef::npos)
310-
report_error(Filename, "Malformed / corrupted profile");
311-
StringRef Signature = Line.substr(0, Pos);
312-
uint64_t Count;
313-
if (Line.substr(Pos + 1, Line.size() - Pos).getAsInteger(10, Count))
314-
report_error(Filename, "Malformed / corrupted profile counter");
318+
CounterTy Count;
319+
auto [Signature, ExecCount] = Line.rsplit(' ');
320+
if (ExecCount.getAsInteger(10, Count.Exec))
321+
report_error(Filename, "Malformed / corrupted execution count");
322+
// Only LBR profile has misprediction field
323+
if (!NoLBRCollection.value_or(false)) {
324+
auto [SignatureLBR, MispredCount] = Signature.rsplit(' ');
325+
Signature = SignatureLBR;
326+
if (MispredCount.getAsInteger(10, Count.Mispred))
327+
report_error(Filename, "Malformed / corrupted misprediction count");
328+
}
329+
315330
Count += Profile->lookup(Signature);
316331
Profile->insert_or_assign(Signature, Count);
317332
} while (std::getline(FdataFile, FdataLine));
@@ -331,16 +346,20 @@ void mergeLegacyProfiles(const SmallVectorImpl<std::string> &Filenames) {
331346
ProfileTy MergedProfile;
332347
for (const auto &[Thread, Profile] : ParsedProfiles)
333348
for (const auto &[Key, Value] : Profile) {
334-
uint64_t Count = MergedProfile.lookup(Key) + Value;
349+
CounterTy Count = MergedProfile.lookup(Key) + Value;
335350
MergedProfile.insert_or_assign(Key, Count);
336351
}
337352

338353
if (BoltedCollection.value_or(false))
339354
output() << "boltedcollection\n";
340355
if (NoLBRCollection.value_or(false))
341356
output() << "no_lbr\n";
342-
for (const auto &[Key, Value] : MergedProfile)
343-
output() << Key << " " << Value << "\n";
357+
for (const auto &[Key, Value] : MergedProfile) {
358+
output() << Key << " ";
359+
if (!NoLBRCollection.value_or(false))
360+
output() << Value.Mispred << " ";
361+
output() << Value.Exec << "\n";
362+
}
344363

345364
errs() << "Profile from " << Filenames.size() << " files merged.\n";
346365
}

0 commit comments

Comments
 (0)