[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
This commit is contained in:
parent
97f43364cc
commit
8652608404
@ -7,9 +7,9 @@
|
|||||||
# RUN: FileCheck %s --input-file %t/merged.fdata
|
# RUN: FileCheck %s --input-file %t/merged.fdata
|
||||||
|
|
||||||
# CHECK-NOT: no_lbr
|
# CHECK-NOT: no_lbr
|
||||||
# CHECK: main 2
|
# CHECK: 1 main 0 1 main 2 1 3
|
||||||
|
|
||||||
#--- a.fdata
|
#--- a.fdata
|
||||||
main 1
|
1 main 0 1 main 2 0 1
|
||||||
#--- b.fdata
|
#--- b.fdata
|
||||||
main 1
|
1 main 0 1 main 2 1 2
|
||||||
|
@ -268,7 +268,17 @@ void mergeLegacyProfiles(const SmallVectorImpl<std::string> &Filenames) {
|
|||||||
std::optional<bool> BoltedCollection;
|
std::optional<bool> BoltedCollection;
|
||||||
std::optional<bool> NoLBRCollection;
|
std::optional<bool> NoLBRCollection;
|
||||||
std::mutex BoltedCollectionMutex;
|
std::mutex BoltedCollectionMutex;
|
||||||
typedef StringMap<uint64_t> ProfileTy;
|
struct CounterTy {
|
||||||
|
uint64_t Exec{0};
|
||||||
|
uint64_t Mispred{0};
|
||||||
|
CounterTy &operator+=(const CounterTy &O) {
|
||||||
|
Exec += O.Exec;
|
||||||
|
Mispred += O.Mispred;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
CounterTy operator+(const CounterTy &O) { return *this += O; }
|
||||||
|
};
|
||||||
|
typedef StringMap<CounterTy> ProfileTy;
|
||||||
|
|
||||||
auto ParseProfile = [&](const std::string &Filename, auto &Profiles) {
|
auto ParseProfile = [&](const std::string &Filename, auto &Profiles) {
|
||||||
const llvm::thread::id tid = llvm::this_thread::get_id();
|
const llvm::thread::id tid = llvm::this_thread::get_id();
|
||||||
@ -305,13 +315,18 @@ void mergeLegacyProfiles(const SmallVectorImpl<std::string> &Filenames) {
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
StringRef Line(FdataLine);
|
StringRef Line(FdataLine);
|
||||||
size_t Pos = Line.rfind(" ");
|
CounterTy Count;
|
||||||
if (Pos == StringRef::npos)
|
auto [Signature, ExecCount] = Line.rsplit(' ');
|
||||||
report_error(Filename, "Malformed / corrupted profile");
|
if (ExecCount.getAsInteger(10, Count.Exec))
|
||||||
StringRef Signature = Line.substr(0, Pos);
|
report_error(Filename, "Malformed / corrupted execution count");
|
||||||
uint64_t Count;
|
// Only LBR profile has misprediction field
|
||||||
if (Line.substr(Pos + 1, Line.size() - Pos).getAsInteger(10, Count))
|
if (!NoLBRCollection.value_or(false)) {
|
||||||
report_error(Filename, "Malformed / corrupted profile counter");
|
auto [SignatureLBR, MispredCount] = Signature.rsplit(' ');
|
||||||
|
Signature = SignatureLBR;
|
||||||
|
if (MispredCount.getAsInteger(10, Count.Mispred))
|
||||||
|
report_error(Filename, "Malformed / corrupted misprediction count");
|
||||||
|
}
|
||||||
|
|
||||||
Count += Profile->lookup(Signature);
|
Count += Profile->lookup(Signature);
|
||||||
Profile->insert_or_assign(Signature, Count);
|
Profile->insert_or_assign(Signature, Count);
|
||||||
} while (std::getline(FdataFile, FdataLine));
|
} while (std::getline(FdataFile, FdataLine));
|
||||||
@ -331,7 +346,7 @@ void mergeLegacyProfiles(const SmallVectorImpl<std::string> &Filenames) {
|
|||||||
ProfileTy MergedProfile;
|
ProfileTy MergedProfile;
|
||||||
for (const auto &[Thread, Profile] : ParsedProfiles)
|
for (const auto &[Thread, Profile] : ParsedProfiles)
|
||||||
for (const auto &[Key, Value] : Profile) {
|
for (const auto &[Key, Value] : Profile) {
|
||||||
uint64_t Count = MergedProfile.lookup(Key) + Value;
|
CounterTy Count = MergedProfile.lookup(Key) + Value;
|
||||||
MergedProfile.insert_or_assign(Key, Count);
|
MergedProfile.insert_or_assign(Key, Count);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -339,8 +354,12 @@ void mergeLegacyProfiles(const SmallVectorImpl<std::string> &Filenames) {
|
|||||||
output() << "boltedcollection\n";
|
output() << "boltedcollection\n";
|
||||||
if (NoLBRCollection.value_or(false))
|
if (NoLBRCollection.value_or(false))
|
||||||
output() << "no_lbr\n";
|
output() << "no_lbr\n";
|
||||||
for (const auto &[Key, Value] : MergedProfile)
|
for (const auto &[Key, Value] : MergedProfile) {
|
||||||
output() << Key << " " << Value << "\n";
|
output() << Key << " ";
|
||||||
|
if (!NoLBRCollection.value_or(false))
|
||||||
|
output() << Value.Mispred << " ";
|
||||||
|
output() << Value.Exec << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
errs() << "Profile from " << Filenames.size() << " files merged.\n";
|
errs() << "Profile from " << Filenames.size() << " files merged.\n";
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user