diff --git a/llvm/include/llvm/Analysis/ProfileSummaryInfo.h b/llvm/include/llvm/Analysis/ProfileSummaryInfo.h --- a/llvm/include/llvm/Analysis/ProfileSummaryInfo.h +++ b/llvm/include/llvm/Analysis/ProfileSummaryInfo.h @@ -60,7 +60,9 @@ public: ProfileSummaryInfo(const Module &M) : M(&M) { refresh(); } ProfileSummaryInfo(std::unique_ptr PSI) - : M(nullptr), Summary(std::move(PSI)) {} + : M(nullptr), Summary(std::move(PSI)) { + computeThresholds(); + } ProfileSummaryInfo(ProfileSummaryInfo &&Arg) = default; diff --git a/llvm/test/tools/llvm-profdata/cs-sample-trimmer.test b/llvm/test/tools/llvm-profdata/cs-sample-trimmer.test new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-profdata/cs-sample-trimmer.test @@ -0,0 +1,42 @@ +RUN: llvm-profdata merge --sample --text -output=%t.proftext %S/Inputs/cs-sample.proftext +RUN: diff -b %t.proftext %S/Inputs/cs-sample.proftext + +RUN: llvm-profdata merge --sample --text -output=%t.proftext %S/Inputs/cs-sample.proftext -sample-merge-cold-context -profile-summary-cold-count=500 +RUN: FileCheck %s --input-file %t.proftext --check-prefixes=CHECK-TRIM,CHECK-MERGE +RUN: llvm-profdata merge --sample --text -output=%t.proftext %S/Inputs/cs-sample.proftext -sample-merge-cold-context -sample-trim-cold-context -profile-summary-cold-count=500 +RUN: FileCheck %s --input-file %t.proftext --check-prefixes=CHECK-TRIM,CHECK-END +RUN: llvm-profdata merge --sample --text -output=%t.proftext %S/Inputs/cs-sample.proftext -sample-merge-cold-context -sample-trim-cold-context -profile-summary-cutoff-cold=990000 +RUN: FileCheck %s --input-file %t.proftext --check-prefixes=CHECK-TRIM,CHECK-END + +CHECK-TRIM: [main:3 @ _Z5funcAi:1 @ _Z8funcLeafi]:1467299:11 +CHECK-TRIM-NEXT: 0: 6 +CHECK-TRIM-NEXT: 1: 6 +CHECK-TRIM-NEXT: 3: 287884 +CHECK-TRIM-NEXT: 4: 287864 _Z3fibi:315608 +CHECK-TRIM-NEXT: 15: 23 +CHECK-TRIM-NEXT: !Attributes: 0 +CHECK-TRIM-NEXT: [main:3.1 @ _Z5funcBi:1 @ _Z8funcLeafi]:500853:20 +CHECK-TRIM-NEXT: 0: 15 +CHECK-TRIM-NEXT: 1: 15 +CHECK-TRIM-NEXT: 3: 74946 +CHECK-TRIM-NEXT: 4: 74941 _Z3fibi:82359 +CHECK-TRIM-NEXT: 10: 23324 +CHECK-TRIM-NEXT: 11: 23327 _Z3fibi:25228 +CHECK-TRIM-NEXT: 15: 11 +CHECK-TRIM-NEXT: !Attributes: 1 +CHECK-END-NOT: [ +CHECK-MERGE: [_Z5funcBi]:360:32 +CHECK-MERGE-NEXT: 0: 32 +CHECK-MERGE-NEXT: 1: 32 _Z8funcLeafi:20 +CHECK-MERGE-NEXT: 3: 12 +CHECK-MERGE-NEXT: !Attributes: 0 +CHECK-MERGE-NEXT:[main]:308:12 +CHECK-MERGE-NEXT: 2: 24 +CHECK-MERGE-NEXT: 3: 28 _Z5funcAi:18 +CHECK-MERGE-NEXT: 3.1: 28 _Z5funcBi:30 +CHECK-MERGE-NEXT: !Attributes: 0 +CHECK-MERGE-NEXT:[_Z5funcAi]:99:11 +CHECK-MERGE-NEXT: 0: 10 +CHECK-MERGE-NEXT: 1: 10 _Z8funcLeafi:11 +CHECK-MERGE-NEXT: 3: 24 +CHECK-MERGE-NEXT: !Attributes: 0 diff --git a/llvm/test/tools/llvm-profgen/cs-preinline.test b/llvm/test/tools/llvm-profgen/cs-preinline.test --- a/llvm/test/tools/llvm-profgen/cs-preinline.test +++ b/llvm/test/tools/llvm-profgen/cs-preinline.test @@ -7,7 +7,7 @@ ; RUN: FileCheck %s --input-file %t --check-prefix=CHECK-PREINL ; Test preinliner threshold that prevents all possible inlining and merges everything into base profile. -; RUN: llvm-profgen --perfscript=%S/Inputs/inline-cs-noprobe.perfscript --binary=%S/Inputs/inline-cs-noprobe.perfbin --output=%t --csspgo-preinliner=1 -sample-profile-hot-inline-threshold=0 +; RUN: llvm-profgen --perfscript=%S/Inputs/inline-cs-noprobe.perfscript --binary=%S/Inputs/inline-cs-noprobe.perfbin --output=%t --csspgo-preinliner=1 -sample-profile-cold-inline-threshold=0 ; RUN: FileCheck %s --input-file %t --check-prefix=CHECK-NO-PREINL ; CHECK-DEFAULT: [main:1 @ foo]:309:0 diff --git a/llvm/tools/llvm-profdata/CMakeLists.txt b/llvm/tools/llvm-profdata/CMakeLists.txt --- a/llvm/tools/llvm-profdata/CMakeLists.txt +++ b/llvm/tools/llvm-profdata/CMakeLists.txt @@ -1,4 +1,5 @@ set(LLVM_LINK_COMPONENTS + Analysis Core ProfileData Support diff --git a/llvm/tools/llvm-profdata/llvm-profdata.cpp b/llvm/tools/llvm-profdata/llvm-profdata.cpp --- a/llvm/tools/llvm-profdata/llvm-profdata.cpp +++ b/llvm/tools/llvm-profdata/llvm-profdata.cpp @@ -13,6 +13,7 @@ #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Analysis/ProfileSummaryInfo.h" #include "llvm/IR/LLVMContext.h" #include "llvm/ProfileData/InstrProfReader.h" #include "llvm/ProfileData/InstrProfWriter.h" @@ -666,7 +667,9 @@ mergeSampleProfile(const WeightedFileVector &Inputs, SymbolRemapper *Remapper, StringRef OutputFilename, ProfileFormat OutputFormat, StringRef ProfileSymbolListFile, bool CompressAllSections, - bool UseMD5, bool GenPartialProfile, FailureMode FailMode) { + bool UseMD5, bool GenPartialProfile, + bool SampleMergeColdContext, bool SampleTrimColdContext, + FailureMode FailMode) { using namespace sampleprof; StringMap ProfileMap; SmallVector, 5> Readers; @@ -723,6 +726,21 @@ if (ReaderList) WriterList.merge(*ReaderList); } + + if (SampleMergeColdContext || SampleTrimColdContext) { + // Use threshold calculated from profile summary unless specified. + SampleProfileSummaryBuilder Builder(ProfileSummaryBuilder::DefaultCutoffs); + auto Summary = Builder.computeSummaryForProfiles(ProfileMap); + uint64_t SampleProfColdThreshold = + ProfileSummaryInfo(std::move(Summary)).getColdCountThreshold(); + + // Trim and merge cold context profile using cold threshold above; + SampleContextTrimmer(ProfileMap) + .trimAndMergeColdContextProfiles(SampleProfColdThreshold, + SampleTrimColdContext, + SampleMergeColdContext); + } + auto WriterOrErr = SampleProfileWriter::create(OutputFilename, FormatMap[OutputFormat]); if (std::error_code EC = WriterOrErr.getError()) @@ -866,6 +884,14 @@ "use-md5", cl::init(false), cl::Hidden, cl::desc("Choose to use MD5 to represent string in name table (only " "meaningful for -extbinary)")); + cl::opt SampleMergeColdContext( + "sample-merge-cold-context", cl::init(false), cl::Hidden, + cl::desc( + "Merge context sample profiles whose count is below cold threshold")); + cl::opt SampleTrimColdContext( + "sample-trim-cold-context", cl::init(false), cl::Hidden, + cl::desc( + "Trim context sample profiles whose count is below cold threshold")); cl::opt GenPartialProfile( "gen-partial-profile", cl::init(false), cl::Hidden, cl::desc("Generate a partial profile (only meaningful for -extbinary)")); @@ -936,7 +962,8 @@ else mergeSampleProfile(WeightedInputs, Remapper.get(), OutputFilename, OutputFormat, ProfileSymbolListFile, CompressAllSections, - UseMD5, GenPartialProfile, FailureMode); + UseMD5, GenPartialProfile, SampleMergeColdContext, + SampleTrimColdContext, FailureMode); return 0; } diff --git a/llvm/tools/llvm-profgen/CMakeLists.txt b/llvm/tools/llvm-profgen/CMakeLists.txt --- a/llvm/tools/llvm-profgen/CMakeLists.txt +++ b/llvm/tools/llvm-profgen/CMakeLists.txt @@ -3,6 +3,7 @@ AllTargetsDescs AllTargetsDisassemblers AllTargetsInfos + Analysis Core MC IPO