Skip to content

Commit e35df1a

Browse files
WenleiHememfrob
authored andcommitted
[CSSPGO] Allow inlining recursive call for preinliner
When preinliner is used for CSSPGO, we try to honor global preinliner decision as much as we can except for uninlinable callees. We rely on InlineCost::Never to prevent us from illegal inlining. However, it turns out that we use InlineCost::Never for both illeagle inlining and some of the "not-so-beneficial" inlining. The most common one is recursive inlining, while it can bloat size a lot during CGSCC bottom-up inlining, it's less of a problem when recursive inlining is guided by profile and done in top-down manner. Ideally it'd be better to have a clear separation between inline legality check vs cost-benefit check, but that requires a bigger change. This change enables InlineCost computation to allow inlining recursive calls, controlled by InlineParams. In SampleLoader, we now enable recursive inlining for CSSPGO when global preinliner decision is used. With this change, we saw a few perf improvements on SPEC2017 with CSSPGO and preinliner on: 2% for povray_r, 6% for xalancbmk_s, 3% omnetpp_s, while size is about the same (no noticeable perf change for all other benchmarks) Differential Revision: https://reviews.llvm.org/D109104
1 parent d233f7f commit e35df1a

File tree

3 files changed

+26
-4
lines changed

3 files changed

+26
-4
lines changed

llvm/include/llvm/Analysis/InlineCost.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,9 @@ struct InlineParams {
213213

214214
/// Indicate whether we should allow inline deferral.
215215
Optional<bool> EnableDeferral = true;
216+
217+
/// Indicate whether we allow inlining for recursive call.
218+
Optional<bool> AllowRecursiveCall = false;
216219
};
217220

218221
/// Generate the parameters to tune the inline cost analysis based only on the

llvm/lib/Analysis/InlineCost.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,10 @@ class CallAnalyzer : public InstVisitor<CallAnalyzer, bool> {
362362
/// whenever we simplify away the stores that would otherwise cause them to be
363363
/// loads.
364364
bool EnableLoadElimination;
365+
366+
/// Whether we allow inlining for recursive call.
367+
bool AllowRecursiveCall;
368+
365369
SmallPtrSet<Value *, 16> LoadAddrSet;
366370

367371
AllocaInst *getSROAArgForValueOrNull(Value *V) const {
@@ -450,7 +454,8 @@ class CallAnalyzer : public InstVisitor<CallAnalyzer, bool> {
450454
OptimizationRemarkEmitter *ORE = nullptr)
451455
: TTI(TTI), GetAssumptionCache(GetAssumptionCache), GetBFI(GetBFI),
452456
PSI(PSI), F(Callee), DL(F.getParent()->getDataLayout()), ORE(ORE),
453-
CandidateCall(Call), EnableLoadElimination(true) {}
457+
CandidateCall(Call), EnableLoadElimination(true),
458+
AllowRecursiveCall(false) {}
454459

455460
InlineResult analyze();
456461

@@ -983,7 +988,9 @@ class InlineCostCallAnalyzer final : public CallAnalyzer {
983988
Params(Params), Threshold(Params.DefaultThreshold),
984989
BoostIndirectCalls(BoostIndirect), IgnoreThreshold(IgnoreThreshold),
985990
CostBenefitAnalysisEnabled(isCostBenefitAnalysisEnabled()),
986-
Writer(this) {}
991+
Writer(this) {
992+
AllowRecursiveCall = Params.AllowRecursiveCall.getValue();
993+
}
987994

988995
/// Annotation Writer for instruction details
989996
InlineCostAnnotationWriter Writer;
@@ -2154,7 +2161,8 @@ bool CallAnalyzer::visitCallBase(CallBase &Call) {
21542161
// This flag will fully abort the analysis, so don't bother with anything
21552162
// else.
21562163
IsRecursiveCall = true;
2157-
return false;
2164+
if (!AllowRecursiveCall)
2165+
return false;
21582166
}
21592167

21602168
if (TTI.isLoweredToCall(F)) {
@@ -2392,7 +2400,7 @@ CallAnalyzer::analyzeBlock(BasicBlock *BB,
23922400
using namespace ore;
23932401
// If the visit this instruction detected an uninlinable pattern, abort.
23942402
InlineResult IR = InlineResult::success();
2395-
if (IsRecursiveCall)
2403+
if (IsRecursiveCall && !AllowRecursiveCall)
23962404
IR = InlineResult::failure("recursive");
23972405
else if (ExposesReturnsTwice)
23982406
IR = InlineResult::failure("exposes returns twice");

llvm/lib/Transforms/IPO/SampleProfile.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,11 @@ static cl::opt<bool> UsePreInlinerDecision(
219219
cl::init(false),
220220
cl::desc("Use the preinliner decisions stored in profile context."));
221221

222+
static cl::opt<bool> AllowRecursiveInline(
223+
"sample-profile-recursive-inline", cl::Hidden, cl::ZeroOrMore,
224+
cl::init(false),
225+
cl::desc("Allow sample loader inliner to inline recursive calls."));
226+
222227
static cl::opt<std::string> ProfileInlineReplayFile(
223228
"sample-profile-inline-replay", cl::init(""), cl::value_desc("filename"),
224229
cl::desc(
@@ -1283,7 +1288,9 @@ SampleProfileLoader::shouldInlineCandidate(InlineCandidate &Candidate) {
12831288
assert(Callee && "Expect a definition for inline candidate of direct call");
12841289

12851290
InlineParams Params = getInlineParams();
1291+
// We will ignore the threshold from inline cost, so always get full cost.
12861292
Params.ComputeFullInlineCost = true;
1293+
Params.AllowRecursiveCall = AllowRecursiveInline;
12871294
// Checks if there is anything in the reachable portion of the callee at
12881295
// this callsite that makes this inlining potentially illegal. Need to
12891296
// set ComputeFullInlineCost, otherwise getInlineCost may return early
@@ -1840,6 +1847,10 @@ bool SampleProfileLoader::doInitialization(Module &M,
18401847
if (!UsePreInlinerDecision.getNumOccurrences())
18411848
UsePreInlinerDecision = true;
18421849

1850+
// For CSSPGO, we also allow recursive inline to best use context profile.
1851+
if (!AllowRecursiveInline.getNumOccurrences())
1852+
AllowRecursiveInline = true;
1853+
18431854
// Enable iterative-BFI by default for CSSPGO.
18441855
if (!UseIterativeBFIInference.getNumOccurrences())
18451856
UseIterativeBFIInference = true;

0 commit comments

Comments
 (0)