Adding support to the CS preinliner to trim cold base profiles. This makes trimming consistent with the inline decision made by the preinliner. Also disable the existing profile merger when preinliner is on unless explicitly specified.
Reviewed By: wenlei, wlei
Differential Revision: https://reviews.llvm.org/D112489
class SampleContextTrimmer {
public:
SampleContextTrimmer(SampleProfileMap &Profiles) : ProfileMap(Profiles){};
- // Trim and merge cold context profile when requested.
+ // Trim and merge cold context profile when requested. TrimBaseProfileOnly
+ // should only be effective when TrimColdContext is true. On top of
+ // TrimColdContext, TrimBaseProfileOnly can be used to specify to trim all
+ // cold profiles or only cold base profiles. Trimming base profiles only is
+ // mainly to honor the preinliner decsion. Note that when MergeColdContext is
+ // true, preinliner decsion is not honored anyway so TrimBaseProfileOnly will
+ // be ignored.
void trimAndMergeColdContextProfiles(uint64_t ColdCountThreshold,
bool TrimColdContext,
bool MergeColdContext,
- uint32_t ColdContextFrameLength);
+ uint32_t ColdContextFrameLength,
+ bool TrimBaseProfileOnly);
// Canonicalize context profile name and attributes.
void canonicalizeContextProfiles();
void SampleContextTrimmer::trimAndMergeColdContextProfiles(
uint64_t ColdCountThreshold, bool TrimColdContext, bool MergeColdContext,
- uint32_t ColdContextFrameLength) {
+ uint32_t ColdContextFrameLength, bool TrimBaseProfileOnly) {
if (!TrimColdContext && !MergeColdContext)
return;
if (ColdCountThreshold == 0)
return;
+ // Trimming base profiles only is mainly to honor the preinliner decsion. When
+ // MergeColdContext is true preinliner decsion is not honored anyway so turn
+ // off TrimBaseProfileOnly.
+ if (MergeColdContext)
+ TrimBaseProfileOnly = false;
+
// Filter the cold profiles from ProfileMap and move them into a tmp
// container
std::vector<std::pair<SampleContext, const FunctionSamples *>> ColdProfiles;
for (const auto &I : ProfileMap) {
+ const SampleContext &Context = I.first;
const FunctionSamples &FunctionProfile = I.second;
- if (FunctionProfile.getTotalSamples() >= ColdCountThreshold)
- continue;
- ColdProfiles.emplace_back(I.first, &I.second);
+ if (FunctionProfile.getTotalSamples() < ColdCountThreshold &&
+ (!TrimBaseProfileOnly || Context.isBaseContext()))
+ ColdProfiles.emplace_back(Context, &I.second);
}
// Remove the cold profile from ProfileMap and merge them into
; RUN: llvm-profgen --format=text --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
+; Test cold profile trimming. Only base profiles should be dropped.
+; RUN: llvm-profgen --format=text --perfscript=%S/Inputs/inline-cs-noprobe.perfscript --binary=%S/Inputs/inline-cs-noprobe.perfbin --output=%t --csspgo-preinliner=1 --csprof-trim-cold-context=1 --profile-summary-hot-count=250
+
+; RUN: FileCheck %s --input-file %t --check-prefix=CHECK-TRIM
+
; CHECK-DEFAULT: [main:1 @ foo]:225:0
; CHECK-DEFAULT-NEXT: 2.1: 14
; CHECK-DEFAULT-NEXT: 3: 15
; CHECK-NO-PREINL-NEXT:[bar]:84:0
; CHECK-NO-PREINL-NEXT: 1: 14
; CHECK-NO-PREINL-NEXT: !Attributes: 1
+
+; CHECK-TRIM-NOT: [foo]:225:0
+; CHECK-TRIM:[foo:3.1 @ bar]:84:0
+; CHECK-TRIM-NEXT: 1: 14
+; CHECK-TRIM-NEXT: !Attributes: 3
SampleContextTrimmer(ProfileMap)
.trimAndMergeColdContextProfiles(
SampleProfColdThreshold, SampleTrimColdContext,
- SampleMergeColdContext, SampleColdContextFrameDepth);
+ SampleMergeColdContext, SampleColdContextFrameDepth, false);
}
auto WriterOrErr =
// trim out such profiles from the output.
std::vector<SampleContext> ProfilesToBeRemoved;
for (auto &It : ProfileMap) {
- SampleContext Context = It.second.getContext();
+ SampleContext &Context = It.second.getContext();
if (!Context.isBaseContext() && !Context.hasState(InlinedContext)) {
assert(Context.hasState(MergedContext) &&
"Not inlined context profile should be merged already");
if (EnableCSPreInliner) {
CSPreInliner(ProfileMap, *Binary, HotCountThreshold, ColdCountThreshold)
.run();
+ // Turn off the profile merger by default unless it is explicitly enabled.
+ if (!CSProfMergeColdContext.getNumOccurrences())
+ CSProfMergeColdContext = false;
}
- // Trim and merge cold context profile using cold threshold above. By default,
- // we skip such merging and trimming when preinliner is on.
- if (!EnableCSPreInliner || CSProfTrimColdContext.getNumOccurrences() ||
- CSProfMergeColdContext.getNumOccurrences()) {
+ // Trim and merge cold context profile using cold threshold above.
+ if (CSProfTrimColdContext || CSProfMergeColdContext) {
SampleContextTrimmer(ProfileMap)
.trimAndMergeColdContextProfiles(
HotCountThreshold, CSProfTrimColdContext, CSProfMergeColdContext,
- CSProfMaxColdContextDepth);
+ CSProfMaxColdContextDepth, EnableCSPreInliner);
}
}