diff --git a/llvm/include/llvm/ProfileData/SampleProf.h b/llvm/include/llvm/ProfileData/SampleProf.h --- a/llvm/include/llvm/ProfileData/SampleProf.h +++ b/llvm/include/llvm/ProfileData/SampleProf.h @@ -23,6 +23,7 @@ #include "llvm/IR/GlobalValue.h" #include "llvm/IR/Module.h" #include "llvm/Support/Allocator.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorOr.h" #include "llvm/Support/MathExtras.h" @@ -38,6 +39,9 @@ #include #include +extern llvm::cl::opt GenCSNestedProfile; +extern llvm::cl::opt GenerateMergedBaseProfiles; + namespace llvm { const std::error_category &sampleprof_category(); diff --git a/llvm/lib/ProfileData/ProfileSummaryBuilder.cpp b/llvm/lib/ProfileData/ProfileSummaryBuilder.cpp --- a/llvm/lib/ProfileData/ProfileSummaryBuilder.cpp +++ b/llvm/lib/ProfileData/ProfileSummaryBuilder.cpp @@ -115,9 +115,13 @@ uint64_t Count = I.second.getSamples(); addCount(Count); } - for (const auto &I : FS.getCallsiteSamples()) - for (const auto &CS : I.second) - addRecord(CS.second, true); + + // Do not recount callee samples if they are already merged into their base + // profiles. This can happen during the generation of CS nested profile. + if (!GenCSNestedProfile || !GenerateMergedBaseProfiles) + for (const auto &I : FS.getCallsiteSamples()) + for (const auto &CS : I.second) + addRecord(CS.second, true); } // The argument to this method is a vector of cutoff percentages and the return diff --git a/llvm/lib/ProfileData/SampleProf.cpp b/llvm/lib/ProfileData/SampleProf.cpp --- a/llvm/lib/ProfileData/SampleProf.cpp +++ b/llvm/lib/ProfileData/SampleProf.cpp @@ -41,6 +41,10 @@ "generate extra base profile for function with all its context " "profiles merged into it.")); +cl::opt GenCSNestedProfile( + "gen-cs-nested-profile", cl::Hidden, cl::init(false), + cl::desc("Generate nested function profiles for CSSPGO")); + namespace llvm { namespace sampleprof { SampleProfileFormat FunctionSamples::Format; diff --git a/llvm/test/tools/llvm-profdata/cs-sample-nested-profile.test b/llvm/test/tools/llvm-profdata/cs-sample-nested-profile.test --- a/llvm/test/tools/llvm-profdata/cs-sample-nested-profile.test +++ b/llvm/test/tools/llvm-profdata/cs-sample-nested-profile.test @@ -8,6 +8,9 @@ RUN: llvm-profdata show --sample -show-sec-info-only %t.profbin | FileCheck %s -check-prefix=PREINLINE RUN: llvm-profdata merge --sample --text -output=%t.proftext %S/Inputs/cs-sample-preinline.proftext --gen-cs-nested-profile=1 -generate-merged-base-profiles=1 RUN: FileCheck %s < %t.proftext --match-full-lines --strict-whitespace -check-prefix=RECOUNT +RUN: llvm-profdata merge --sample --extbinary -output=%t2.profbin %S/Inputs/cs-sample-preinline.proftext --gen-cs-nested-profile=1 -generate-merged-base-profiles=1 +RUN: llvm-profdata show -sample -detailed-summary %S/Inputs/cs-sample-preinline.proftext | FileCheck %s -check-prefix=SUMMARY +RUN: llvm-profdata show -sample -detailed-summary %t2.profbin | FileCheck %s -check-prefix=SUMMARY ; CHECK:main:1968679:12 @@ -153,3 +156,27 @@ ; PREINLINE: ProfileSummarySection {{.*}} Flags: {context-nested} + + +; SUMMARY: Total functions: 4 +; SUMMARY-NEXT: Maximum function count: 32 +; SUMMARY-NEXT: Maximum block count: 362830 +; SUMMARY-NEXT: Total number of blocks: 16 +; SUMMARY-NEXT: Total count: 772562 +; SUMMARY-NEXT: Detailed summary: +; SUMMARY-NEXT: 1 blocks with count >= 362830 account for 1 percentage of the total counts. +; SUMMARY-NEXT: 1 blocks with count >= 362830 account for 10 percentage of the total counts. +; SUMMARY-NEXT: 1 blocks with count >= 362830 account for 20 percentage of the total counts. +; SUMMARY-NEXT: 1 blocks with count >= 362830 account for 30 percentage of the total counts. +; SUMMARY-NEXT: 1 blocks with count >= 362830 account for 40 percentage of the total counts. +; SUMMARY-NEXT: 2 blocks with count >= 362805 account for 50 percentage of the total counts. +; SUMMARY-NEXT: 2 blocks with count >= 362805 account for 60 percentage of the total counts. +; SUMMARY-NEXT: 2 blocks with count >= 362805 account for 70 percentage of the total counts. +; SUMMARY-NEXT: 2 blocks with count >= 362805 account for 80 percentage of the total counts. +; SUMMARY-NEXT: 2 blocks with count >= 362805 account for 90 percentage of the total counts. +; SUMMARY-NEXT: 3 blocks with count >= 23327 account for 95 percentage of the total counts. +; SUMMARY-NEXT: 4 blocks with count >= 23324 account for 99 percentage of the total counts. +; SUMMARY-NEXT: 4 blocks with count >= 23324 account for 99.9 percentage of the total counts. +; SUMMARY-NEXT: 11 blocks with count >= 24 account for 99.99 percentage of the total counts. +; SUMMARY-NEXT: 16 blocks with count >= 10 account for 99.999 percentage of the total counts. +; SUMMARY-NEXT: 16 blocks with count >= 10 account for 99.9999 percentage of the total counts. 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 @@ -961,9 +961,6 @@ "instr-prof-cold-threshold", cl::init(0), cl::Hidden, cl::desc("User specified cold threshold for instr profile which will " "override the cold threshold got from profile summary. ")); - cl::opt GenCSNestedProfile( - "gen-cs-nested-profile", cl::Hidden, cl::init(false), - cl::desc("Generate nested function profiles for CSSPGO")); cl::opt DebugInfoFilename( "debug-info", cl::init(""), cl::desc("Use the provided debug info to correlate the raw profile.")); diff --git a/llvm/tools/llvm-profgen/ProfileGenerator.cpp b/llvm/tools/llvm-profgen/ProfileGenerator.cpp --- a/llvm/tools/llvm-profgen/ProfileGenerator.cpp +++ b/llvm/tools/llvm-profgen/ProfileGenerator.cpp @@ -89,10 +89,6 @@ extern cl::opt ProfileSummaryCutoffHot; -static cl::opt GenCSNestedProfile( - "gen-cs-nested-profile", cl::Hidden, cl::init(false), - cl::desc("Generate nested function profiles for CSSPGO")); - using namespace llvm; using namespace sampleprof;