From d63f99627b9b08d71595b1879be74a8225873e34 Mon Sep 17 00:00:00 2001 From: Amir Ayupov Date: Wed, 27 May 2026 00:38:55 -0700 Subject: [PATCH] [BOLT][merge-fdata] Preserve event names Test Plan: added merge-fdata-no-lbr-event*.test Reviewers: maksfb, paschalis-mpeis, yozhu, yota9, yavtuk, rafaelauler, ayermolo Reviewed By: rafaelauler Pull Request: https://github.com/llvm/llvm-project/pull/199323 --- bolt/test/merge-fdata-no-lbr-event-multi.test | 22 ++++++++++++++++++ bolt/test/merge-fdata-no-lbr-event.test | 18 +++++++++++++++ bolt/tools/merge-fdata/merge-fdata.cpp | 23 +++++++++++++++++-- 3 files changed, 61 insertions(+), 2 deletions(-) create mode 100644 bolt/test/merge-fdata-no-lbr-event-multi.test create mode 100644 bolt/test/merge-fdata-no-lbr-event.test diff --git a/bolt/test/merge-fdata-no-lbr-event-multi.test b/bolt/test/merge-fdata-no-lbr-event-multi.test new file mode 100644 index 000000000000..68707b6e5f15 --- /dev/null +++ b/bolt/test/merge-fdata-no-lbr-event-multi.test @@ -0,0 +1,22 @@ +## Check that merge-fdata preserves and propagates multiple event names from +## the "no_lbr" header line, deduplicating across input files, when combined +## with boltedcollection. + +# REQUIRES: system-linux + +# RUN: split-file %s %t +# RUN: merge-fdata %t/a.fdata %t/b.fdata -o %t/merged.fdata +# RUN: FileCheck %s --input-file %t/merged.fdata + +# CHECK: boltedcollection +# CHECK: no_lbr{{.*( cycles:u| instructions)( cycles:u| instructions)}} +# CHECK: 0 main 10 150 + +#--- a.fdata +boltedcollection +no_lbr cycles:u instructions +0 main 10 100 +#--- b.fdata +boltedcollection +no_lbr instructions cycles:u +0 main 10 50 diff --git a/bolt/test/merge-fdata-no-lbr-event.test b/bolt/test/merge-fdata-no-lbr-event.test new file mode 100644 index 000000000000..5a649178ae8f --- /dev/null +++ b/bolt/test/merge-fdata-no-lbr-event.test @@ -0,0 +1,18 @@ +## Check that merge-fdata preserves and propagates event names from the +## "no_lbr" header line to the merged output. + +# REQUIRES: system-linux + +# RUN: split-file %s %t +# RUN: merge-fdata %t/a.fdata %t/b.fdata -o %t/merged.fdata +# RUN: FileCheck %s --input-file %t/merged.fdata + +# CHECK: no_lbr cycles:u +# CHECK: 1 main 0 2 + +#--- a.fdata +no_lbr cycles:u +1 main 0 1 +#--- b.fdata +no_lbr cycles:u +1 main 0 1 diff --git a/bolt/tools/merge-fdata/merge-fdata.cpp b/bolt/tools/merge-fdata/merge-fdata.cpp index 23b178eee17b..79f0b574f639 100644 --- a/bolt/tools/merge-fdata/merge-fdata.cpp +++ b/bolt/tools/merge-fdata/merge-fdata.cpp @@ -15,6 +15,7 @@ #include "bolt/Profile/ProfileYAMLMapping.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringSet.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/ManagedStatic.h" @@ -268,6 +269,7 @@ void mergeLegacyProfiles(const SmallVectorImpl &Filenames) { std::optional BoltedCollection; std::optional NoLBRCollection; std::mutex BoltedCollectionMutex; + std::set EventNames; struct CounterTy { uint64_t Exec{0}; uint64_t Mispred{0}; @@ -312,7 +314,20 @@ void mergeLegacyProfiles(const SmallVectorImpl &Filenames) { checkMode("boltedcollection", BoltedCollection); // Check if the string "no_lbr" is in the first line // (or second line if BoltedCollection is true) + // The line may also contain space-separated event names following + // "no_lbr", e.g. "no_lbr cycles:u". Preserve and propagate them to + // the merged output. + std::string NoLBRLineCopy = FdataLine; checkMode("no_lbr", NoLBRCollection); + StringRef NoLBRLine(NoLBRLineCopy); + if (NoLBRCollection.value_or(false) && + NoLBRLine.consume_front("no_lbr")) { + SmallVector Events; + NoLBRLine.trim().split(Events, ' ', /*MaxSplit=*/-1, + /*KeepEmpty=*/false); + for (StringRef Event : Events) + EventNames.insert(Event.str()); + } Profile = &Profiles[tid]; } @@ -382,8 +397,12 @@ void mergeLegacyProfiles(const SmallVectorImpl &Filenames) { if (BoltedCollection.value_or(false)) output() << "boltedcollection\n"; - if (NoLBRCollection.value_or(false)) - output() << "no_lbr\n"; + if (NoLBRCollection.value_or(false)) { + output() << "no_lbr"; + for (StringRef Entry : EventNames) + output() << ' ' << Entry; + output() << '\n'; + } for (const auto &[Key, Value] : MergedProfile.Branch) { output() << Key << " "; if (!NoLBRCollection.value_or(false))