diff --git a/bolt/test/merge-fdata-bat-no-lbr.test b/bolt/test/merge-fdata-bat-no-lbr.test index fd5cd16263356..5176286bf24e6 100644 --- a/bolt/test/merge-fdata-bat-no-lbr.test +++ b/bolt/test/merge-fdata-bat-no-lbr.test @@ -8,13 +8,13 @@ # CHECK: boltedcollection # CHECK: no_lbr -# CHECK: main 2 +# CHECK: 1 main 2 #--- a.fdata boltedcollection no_lbr -main 1 +1 main 1 #--- b.fdata boltedcollection no_lbr -main 1 +1 main 1 diff --git a/bolt/test/merge-fdata-mem-prof.test b/bolt/test/merge-fdata-mem-prof.test new file mode 100644 index 0000000000000..eaa1d645974c5 --- /dev/null +++ b/bolt/test/merge-fdata-mem-prof.test @@ -0,0 +1,17 @@ +## Check that merge-fdata tool correctly handles memory profile, emitting it +## after branch profile. + +# 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: 1 main 5 1 main 10 0 1 +# CHECK-NEXT: 4 Curl_cf_def_query c 4 Curl_cft_h1_proxy 68 3 + +#--- a.fdata +4 Curl_cf_def_query c 4 Curl_cft_h1_proxy 68 1 +4 Curl_cf_def_query c 4 Curl_cft_h1_proxy 68 2 +#--- b.fdata +1 main 5 1 main 10 0 1 diff --git a/bolt/test/merge-fdata-mixed-bat-no-lbr.test b/bolt/test/merge-fdata-mixed-bat-no-lbr.test index eeb3a0e23b0cc..eb8c8114b41ba 100644 --- a/bolt/test/merge-fdata-mixed-bat-no-lbr.test +++ b/bolt/test/merge-fdata-mixed-bat-no-lbr.test @@ -10,7 +10,7 @@ #--- a.fdata boltedcollection no_lbr -main 1 +1 main 1 #--- b.fdata no_lbr -main 1 +1 main 1 diff --git a/bolt/test/merge-fdata-mixed-mode.test b/bolt/test/merge-fdata-mixed-mode.test index f897fec5d9db4..731e846647560 100644 --- a/bolt/test/merge-fdata-mixed-mode.test +++ b/bolt/test/merge-fdata-mixed-mode.test @@ -10,6 +10,6 @@ #--- a.fdata no_lbr -main 1 +1 main 1 #--- b.fdata -main 1 +1 main 1 diff --git a/bolt/test/merge-fdata-no-lbr-mode.test b/bolt/test/merge-fdata-no-lbr-mode.test index 9dfad99f79994..5b417e74ce94d 100644 --- a/bolt/test/merge-fdata-no-lbr-mode.test +++ b/bolt/test/merge-fdata-no-lbr-mode.test @@ -8,11 +8,11 @@ # RUN: FileCheck %s --input-file %t/merged.fdata # CHECK: no_lbr -# CHECK: main 2 +# CHECK: 1 main 2 #--- a.fdata no_lbr -main 1 +1 main 1 #--- b.fdata no_lbr -main 1 +1 main 1 diff --git a/bolt/tools/merge-fdata/merge-fdata.cpp b/bolt/tools/merge-fdata/merge-fdata.cpp index 74a5f8ca2d477..faf73fb9e1b35 100644 --- a/bolt/tools/merge-fdata/merge-fdata.cpp +++ b/bolt/tools/merge-fdata/merge-fdata.cpp @@ -278,7 +278,10 @@ void mergeLegacyProfiles(const SmallVectorImpl &Filenames) { } CounterTy operator+(const CounterTy &O) { return *this += O; } }; - typedef StringMap ProfileTy; + struct ProfileTy { + StringMap Branch; + StringMap Memory; + }; auto ParseProfile = [&](const std::string &Filename, auto &Profiles) { const llvm::thread::id tid = llvm::this_thread::get_id(); @@ -316,19 +319,23 @@ void mergeLegacyProfiles(const SmallVectorImpl &Filenames) { do { StringRef Line(FdataLine); CounterTy Count; + unsigned Type = 0; + if (Line.split(' ').first.getAsInteger(10, Type)) + report_error(Filename, "Malformed / corrupted entry type"); + bool IsBranchEntry = Type < 3; auto [Signature, ExecCount] = Line.rsplit(' '); if (ExecCount.getAsInteger(10, Count.Exec)) report_error(Filename, "Malformed / corrupted execution count"); // Only LBR profile has misprediction field - if (!NoLBRCollection.value_or(false)) { + if (!NoLBRCollection.value_or(false) && IsBranchEntry) { auto [SignatureLBR, MispredCount] = Signature.rsplit(' '); Signature = SignatureLBR; if (MispredCount.getAsInteger(10, Count.Mispred)) report_error(Filename, "Malformed / corrupted misprediction count"); } - Count += Profile->lookup(Signature); - Profile->insert_or_assign(Signature, Count); + auto &ProfileMap = IsBranchEntry ? Profile->Branch : Profile->Memory; + ProfileMap[Signature] += Count; } while (std::getline(FdataFile, FdataLine)); }; @@ -344,22 +351,25 @@ void mergeLegacyProfiles(const SmallVectorImpl &Filenames) { Pool.wait(); ProfileTy MergedProfile; - for (const auto &[Thread, Profile] : ParsedProfiles) - for (const auto &[Key, Value] : Profile) { - CounterTy Count = MergedProfile.lookup(Key) + Value; - MergedProfile.insert_or_assign(Key, Count); - } + for (const auto &[Thread, Profile] : ParsedProfiles) { + for (const auto &[Key, Value] : Profile.Branch) + MergedProfile.Branch[Key] += Value; + for (const auto &[Key, Value] : Profile.Memory) + MergedProfile.Memory[Key] += Value; + } if (BoltedCollection.value_or(false)) output() << "boltedcollection\n"; if (NoLBRCollection.value_or(false)) output() << "no_lbr\n"; - for (const auto &[Key, Value] : MergedProfile) { + for (const auto &[Key, Value] : MergedProfile.Branch) { output() << Key << " "; if (!NoLBRCollection.value_or(false)) output() << Value.Mispred << " "; output() << Value.Exec << "\n"; } + for (const auto &[Key, Value] : MergedProfile.Memory) + output() << Key << ' ' << Value.Exec << '\n'; errs() << "Profile from " << Filenames.size() << " files merged.\n"; }