Skip to content

Commit 3f61189

Browse files
authored
Merge pull request #80914 from kubamracek/inliner-knobs
[SILOptimizer] Expose SIL inliner heuristics/constants as -Xllvm configurable knobs
2 parents 2d7b7a7 + 9878da9 commit 3f61189

File tree

1 file changed

+100
-71
lines changed

1 file changed

+100
-71
lines changed

lib/SILOptimizer/Transforms/PerformanceInliner.cpp

Lines changed: 100 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,104 @@ llvm::cl::opt<bool> EnableVerifyAfterEachInlining(
7373
"Run sil verification after inlining each found callee apply "
7474
"site into a caller."));
7575

76+
//===----------------------------------------------------------------------===//
77+
// Heuristics
78+
//===----------------------------------------------------------------------===//
79+
80+
/// The following constants define the cost model for inlining. Some constants
81+
/// are also defined in ShortestPathAnalysis.
82+
83+
llvm::cl::opt<int> RemovedCallBenefit(
84+
"sil-inline-removed-call-benefit", llvm::cl::init(20),
85+
llvm::cl::desc("The base value for every call: it represents the benefit "
86+
"of removing the call overhead itself."));
87+
88+
llvm::cl::opt<int> RemovedCoroutineCallBenefit(
89+
"sil-inline-removed-coroutine-call-benefit", llvm::cl::init(300),
90+
llvm::cl::desc("The benefit of inlining a `begin_apply`."));
91+
92+
llvm::cl::opt<int> RemovedClosureBenefit(
93+
"sil-inline-removed-closure-benefit",
94+
llvm::cl::init(RemovedCallBenefit + 50),
95+
llvm::cl::desc(
96+
"The benefit if the operand of an apply gets constant e.g. if a "
97+
"closure is passed to an apply instruction in the callee."));
98+
99+
llvm::cl::opt<int> RemovedLoadBenefit(
100+
"sil-inline-removed-load-benefit", llvm::cl::init(RemovedCallBenefit + 5),
101+
llvm::cl::desc("The benefit if a load can (probably) eliminated because it "
102+
"loads from a stack location in the caller."));
103+
104+
llvm::cl::opt<int> RemovedStoreBenefit(
105+
"sil-inline-removed-store-benefit", llvm::cl::init(RemovedCallBenefit + 10),
106+
llvm::cl::desc("The benefit if a store can (probably) eliminated because "
107+
"it stores to a stack location in the caller."));
108+
109+
llvm::cl::opt<int> RemovedTerminatorBenefit(
110+
"sil-inline-removed-terminator-benefit",
111+
llvm::cl::init(RemovedCallBenefit + 10),
112+
llvm::cl::desc("The benefit if the condition of a terminator instruction "
113+
"gets constant due to inlining."));
114+
115+
llvm::cl::opt<int>
116+
RefCountBenefit("sil-inline-ref-count-benefit",
117+
llvm::cl::init(RemovedCallBenefit + 20),
118+
llvm::cl::desc("The benefit if a retain/release can "
119+
"(probably) be eliminated after inlining."));
120+
121+
llvm::cl::opt<int> FastPathBuiltinBenefit(
122+
"sil-inline-fast-path-builtin-benefit",
123+
llvm::cl::init(RemovedCallBenefit + 40),
124+
llvm::cl::desc("The benefit of a onFastPath builtin."));
125+
126+
llvm::cl::opt<int> DevirtualizedCallBenefit(
127+
"sil-inline-devirtualized-call-benefit",
128+
llvm::cl::init(RemovedCallBenefit + 300),
129+
llvm::cl::desc("The benefit of being able to devirtualize a call."));
130+
131+
llvm::cl::opt<int> GenericSpecializationBenefit(
132+
"sil-inline-generic-specialization-benefit",
133+
llvm::cl::init(RemovedCallBenefit + 300),
134+
llvm::cl::desc("The benefit of being able to produce a generic "
135+
"specialization for a call."));
136+
137+
llvm::cl::opt<int> ExclusivityBenefit(
138+
"sil-inline-exclusivity-benefit", llvm::cl::init(RemovedCallBenefit + 10),
139+
llvm::cl::desc("The benefit of inlining an exclusivity-containing callee. "
140+
"The exclusivity needs to be: dynamic, has no nested "
141+
"conflict and addresses known storage"));
142+
143+
llvm::cl::opt<int> OSizeClassMethodBenefit(
144+
"sil-inline-o-size-class-method-benefit", llvm::cl::init(5),
145+
llvm::cl::desc("The benefit of inlining class methods with -Osize. We only "
146+
"inline very small class methods with -Osize."));
147+
148+
llvm::cl::opt<int> TrivialFunctionThreshold(
149+
"sil-inline-trivial-function-threshold", llvm::cl::init(18),
150+
llvm::cl::desc("Approximately up to this cost level a function can be "
151+
"inlined without increasing the code size."));
152+
153+
llvm::cl::opt<int> BlockLimitDenominator(
154+
"sil-inline-block-limit-denominator", llvm::cl::init(3000),
155+
llvm::cl::desc("Configuration for the \"soft\" caller block limit. When "
156+
"changing make sure you update BlockLimitMaxIntNumerator."));
157+
158+
llvm::cl::opt<int> BlockLimitMaxIntNumerator(
159+
"sil-inline-block-limit-max-int-numerator", llvm::cl::init(18608),
160+
llvm::cl::desc("Computations with BlockLimitDenominator will overflow with "
161+
"numerators >= this value. This equals cbrt(INT_MAX) * "
162+
"cbrt(BlockLimitDenominator); we hardcode its value because "
163+
"std::cbrt() is not constexpr."));
164+
165+
llvm::cl::opt<int> OverallCallerBlockLimit(
166+
"sil-inline-overall-caller-block-limit", llvm::cl::init(400),
167+
llvm::cl::desc("No inlining is done if the caller has more than this "
168+
"number of blocks."));
169+
170+
llvm::cl::opt<int> DefaultApplyLength(
171+
"sil-inline-default-apply-length", llvm::cl::init(10),
172+
llvm::cl::desc("The assumed execution length of a function call."));
173+
76174
//===----------------------------------------------------------------------===//
77175
// Printing Helpers
78176
//===----------------------------------------------------------------------===//
@@ -118,75 +216,6 @@ class SILPerformanceInliner {
118216

119217
OptRemark::Emitter &ORE;
120218

121-
/// The following constants define the cost model for inlining. Some constants
122-
/// are also defined in ShortestPathAnalysis.
123-
enum {
124-
/// The base value for every call: it represents the benefit of removing the
125-
/// call overhead itself.
126-
RemovedCallBenefit = 20,
127-
128-
/// The benefit of inlining a `begin_apply`.
129-
RemovedCoroutineCallBenefit = 300,
130-
131-
/// The benefit if the operand of an apply gets constant, e.g. if a closure
132-
/// is passed to an apply instruction in the callee.
133-
RemovedClosureBenefit = RemovedCallBenefit + 50,
134-
135-
/// The benefit if a load can (probably) eliminated because it loads from
136-
/// a stack location in the caller.
137-
RemovedLoadBenefit = RemovedCallBenefit + 5,
138-
139-
/// The benefit if a store can (probably) eliminated because it stores to
140-
/// a stack location in the caller.
141-
RemovedStoreBenefit = RemovedCallBenefit + 10,
142-
143-
/// The benefit if the condition of a terminator instruction gets constant
144-
/// due to inlining.
145-
RemovedTerminatorBenefit = RemovedCallBenefit + 10,
146-
147-
/// The benefit if a retain/release can (probably) be eliminated after
148-
/// inlining.
149-
RefCountBenefit = RemovedCallBenefit + 20,
150-
151-
/// The benefit of a onFastPath builtin.
152-
FastPathBuiltinBenefit = RemovedCallBenefit + 40,
153-
154-
/// The benefit of being able to devirtualize a call.
155-
DevirtualizedCallBenefit = RemovedCallBenefit + 300,
156-
157-
/// The benefit of being able to produce a generic
158-
/// specialization for a call.
159-
GenericSpecializationBenefit = RemovedCallBenefit + 300,
160-
161-
/// The benefit of inlining an exclusivity-containing callee.
162-
/// The exclusivity needs to be: dynamic,
163-
/// has no nested conflict and addresses known storage
164-
ExclusivityBenefit = RemovedCallBenefit + 10,
165-
166-
/// The benefit of inlining class methods with -Osize.
167-
/// We only inline very small class methods with -Osize.
168-
OSizeClassMethodBenefit = 5,
169-
170-
/// Approximately up to this cost level a function can be inlined without
171-
/// increasing the code size.
172-
TrivialFunctionThreshold = 18,
173-
174-
/// Configuration for the "soft" caller block limit. When changing, make
175-
/// sure you update BlockLimitMaxIntNumerator.
176-
BlockLimitDenominator = 3000,
177-
178-
/// Computations with BlockLimitDenominator will overflow with numerators
179-
/// >= this value. This equals cbrt(INT_MAX) * cbrt(BlockLimitDenominator);
180-
/// we hardcode its value because std::cbrt() is not constexpr.
181-
BlockLimitMaxIntNumerator = 18608,
182-
183-
/// No inlining is done if the caller has more than this number of blocks.
184-
OverallCallerBlockLimit = 400,
185-
186-
/// The assumed execution length of a function call.
187-
DefaultApplyLength = 10
188-
};
189-
190219
OptimizationMode OptMode;
191220

192221
#ifndef NDEBUG
@@ -577,7 +606,7 @@ bool SILPerformanceInliner::isProfitableToInline(
577606
CalleeSPA->analyze(CBI, [](FullApplySite FAS) {
578607
// We don't compute SPA for another call-level. Functions called from
579608
// the callee are assumed to have DefaultApplyLength.
580-
return DefaultApplyLength;
609+
return DefaultApplyLength.getValue();
581610
});
582611
}
583612

@@ -1129,7 +1158,7 @@ void SILPerformanceInliner::collectAppliesToInline(
11291158
CalleeSPA->analyze(CBI, [](FullApplySite FAS) {
11301159
// We don't compute SPA for another call-level. Functions called from
11311160
// the callee are assumed to have DefaultApplyLength.
1132-
return DefaultApplyLength;
1161+
return DefaultApplyLength.getValue();
11331162
});
11341163
}
11351164
int CalleeLength = CalleeSPA->getScopeLength(&Callee->front(), 0);

0 commit comments

Comments
 (0)