Index: llvm/trunk/include/llvm/ProfileData/SampleProf.h =================================================================== --- llvm/trunk/include/llvm/ProfileData/SampleProf.h +++ llvm/trunk/include/llvm/ProfileData/SampleProf.h @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -143,8 +144,18 @@ /// will be a list of one or more functions. class SampleRecord { public: - using CallTargetMap = StringMap; + using CallTarget = std::pair; + struct CallTargetComparator { + bool operator() (const CallTarget &LHS, const CallTarget &RHS) { + if (LHS.second != RHS.second) + return LHS.second > RHS.second; + + return LHS.first < RHS.first; + } + }; + using SortedCallTargetSet = std::set; + using CallTargetMap = StringMap; SampleRecord() = default; /// Increment the number of samples for this record by \p S. @@ -179,6 +190,18 @@ uint64_t getSamples() const { return NumSamples; } const CallTargetMap &getCallTargets() const { return CallTargets; } + const SortedCallTargetSet getSortedCallTargets() const { + return SortCallTargets(CallTargets); + } + + /// Sort call targets in descending order of call frequency. + static const SortedCallTargetSet SortCallTargets(const CallTargetMap &Targets) { + SortedCallTargetSet SortedTargets; + for (const auto &I : Targets) { + SortedTargets.emplace(I.first(), I.second); + } + return SortedTargets; + } /// Merge the samples in \p Other into this record. /// Optionally scale sample counts by \p Weight. Index: llvm/trunk/lib/ProfileData/SampleProf.cpp =================================================================== --- llvm/trunk/lib/ProfileData/SampleProf.cpp +++ llvm/trunk/lib/ProfileData/SampleProf.cpp @@ -100,8 +100,8 @@ OS << NumSamples; if (hasCalls()) { OS << ", calls:"; - for (const auto &I : getCallTargets()) - OS << " " << I.first() << ":" << I.second; + for (const auto &I : getSortedCallTargets()) + OS << " " << I.first << ":" << I.second; } OS << "\n"; } Index: llvm/trunk/lib/ProfileData/SampleProfWriter.cpp =================================================================== --- llvm/trunk/lib/ProfileData/SampleProfWriter.cpp +++ llvm/trunk/lib/ProfileData/SampleProfWriter.cpp @@ -100,8 +100,8 @@ OS << Sample.getSamples(); - for (const auto &J : Sample.getCallTargets()) - OS << " " << J.first() << ":" << J.second; + for (const auto &J : Sample.getSortedCallTargets()) + OS << " " << J.first << ":" << J.second; OS << "\n"; } @@ -294,8 +294,8 @@ encodeULEB128(Loc.Discriminator, OS); encodeULEB128(Sample.getSamples(), OS); encodeULEB128(Sample.getCallTargets().size(), OS); - for (const auto &J : Sample.getCallTargets()) { - StringRef Callee = J.first(); + for (const auto &J : Sample.getSortedCallTargets()) { + StringRef Callee = J.first; uint64_t CalleeSamples = J.second; if (std::error_code EC = writeNameIdx(Callee)) return EC; Index: llvm/trunk/lib/Transforms/IPO/SampleProfile.cpp =================================================================== --- llvm/trunk/lib/Transforms/IPO/SampleProfile.cpp +++ llvm/trunk/lib/Transforms/IPO/SampleProfile.cpp @@ -192,7 +192,7 @@ public: GUIDToFuncNameMapper(Module &M, SampleProfileReader &Reader, DenseMap &GUIDToFuncNameMap) - : CurrentReader(Reader), CurrentModule(M), + : CurrentReader(Reader), CurrentModule(M), CurrentGUIDToFuncNameMap(GUIDToFuncNameMap) { if (CurrentReader.getFormat() != SPF_Compact_Binary) return; @@ -1292,17 +1292,12 @@ } /// Returns the sorted CallTargetMap \p M by count in descending order. -static SmallVector SortCallTargets( - const SampleRecord::CallTargetMap &M) { +static SmallVector GetSortedValueDataFromCallTargets( + const SampleRecord::CallTargetMap & M) { SmallVector R; - for (auto I = M.begin(); I != M.end(); ++I) - R.push_back({FunctionSamples::getGUID(I->getKey()), I->getValue()}); - llvm::sort(R, [](const InstrProfValueData &L, const InstrProfValueData &R) { - if (L.Count == R.Count) - return L.Value > R.Value; - else - return L.Count > R.Count; - }); + for (const auto &I : SampleRecord::SortCallTargets(M)) { + R.emplace_back(InstrProfValueData{FunctionSamples::getGUID(I.first), I.second}); + } return R; } @@ -1397,7 +1392,7 @@ if (!T || T.get().empty()) continue; SmallVector SortedCallTargets = - SortCallTargets(T.get()); + GetSortedValueDataFromCallTargets(T.get()); uint64_t Sum; findIndirectCallFunctionSamples(I, Sum); annotateValueSite(*I.getParent()->getParent()->getParent(), I, @@ -1724,7 +1719,7 @@ } bool SampleProfileLoader::runOnFunction(Function &F, ModuleAnalysisManager *AM) { - + DILocation2SampleMap.clear(); // By default the entry count is initialized to -1, which will be treated // conservatively by getEntryCount as the same as unknown (None). This is Index: llvm/trunk/test/tools/llvm-profdata/Inputs/sample-profile.proftext =================================================================== --- llvm/trunk/test/tools/llvm-profdata/Inputs/sample-profile.proftext +++ llvm/trunk/test/tools/llvm-profdata/Inputs/sample-profile.proftext @@ -1,7 +1,3 @@ -_Z3bari:20301:1437 - 1: 1437 -_Z3fooi:7711:610 - 1: 610 main:184019:0 4: 534 4.2: 534 @@ -14,3 +10,7 @@ 1: 1000 10: inline2:2000 1: 2000 +_Z3bari:20301:1437 + 1: 1437 +_Z3fooi:7711:610 + 1: 610 Index: llvm/trunk/test/tools/llvm-profdata/roundtrip.test =================================================================== --- llvm/trunk/test/tools/llvm-profdata/roundtrip.test +++ llvm/trunk/test/tools/llvm-profdata/roundtrip.test @@ -4,3 +4,6 @@ RUN: llvm-profdata merge -o %t.1.profdata %t.0.proftext RUN: llvm-profdata show -o %t.1.proftext -all-functions -text %t.1.profdata RUN: diff %t.1.proftext %S/Inputs/IR_profile.proftext +RUN: llvm-profdata merge --sample --binary -output=%t.2.profdata %S/Inputs/sample-profile.proftext +RUN: llvm-profdata merge --sample --text -output=%t.2.proftext %t.2.profdata +RUN: diff %t.2.proftext %S/Inputs/sample-profile.proftext \ No newline at end of file Index: llvm/trunk/test/tools/llvm-profdata/sample-profile-basic.test =================================================================== --- llvm/trunk/test/tools/llvm-profdata/sample-profile-basic.test +++ llvm/trunk/test/tools/llvm-profdata/sample-profile-basic.test @@ -3,7 +3,7 @@ 1- Show all functions RUN: llvm-profdata show --sample %p/Inputs/sample-profile.proftext | FileCheck %s --check-prefix=SHOW1 SHOW1-DAG: Function: main: 184019, 0, 7 sampled lines -SHOW1-DAG: 9: 2064, calls: _Z3fooi:631 _Z3bari:1471 +SHOW1-DAG: 9: 2064, calls: _Z3bari:1471 _Z3fooi:631 SHOW1-DAG: Function: _Z3fooi: 7711, 610, 1 sampled lines SHOW1-DAG: Function: _Z3bari: 20301, 1437, 1 sampled lines SHOW1-DAG: 1: 1437 @@ -26,7 +26,7 @@ RUN: llvm-profdata merge --sample %p/Inputs/sample-profile.proftext -o %t-binprof RUN: llvm-profdata merge --sample --text %p/Inputs/sample-profile.proftext %t-binprof -o - | FileCheck %s --check-prefix=MERGE1 MERGE1: main:368038:0 -MERGE1: 9: 4128 _Z3fooi:1262 _Z3bari:2942 +MERGE1: 9: 4128 _Z3bari:2942 _Z3fooi:1262 MERGE1: _Z3bari:40602:2874 MERGE1: _Z3fooi:15422:1220