[dart/vm] simplified inlining heuristics
Rationale:
Less special casing, more informed decisions
https://github.com/dart-lang/sdk/issues/37126
Change-Id: I3415f52cf38ed6110ebe16c44a719f6081f24dbf
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/106182
Commit-Queue: Aart Bik <ajcbik@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
diff --git a/runtime/vm/compiler/backend/inliner.cc b/runtime/vm/compiler/backend/inliner.cc
index 6dd87b1..a98ed66 100644
--- a/runtime/vm/compiler/backend/inliner.cc
+++ b/runtime/vm/compiler/backend/inliner.cc
@@ -54,7 +54,7 @@
"Always inline functions containing threshold or fewer calls.");
DEFINE_FLAG(int,
inlining_callee_size_threshold,
- 80,
+ 160,
"Do not inline callees larger than threshold");
DEFINE_FLAG(int,
inlining_small_leaf_size_threshold,
@@ -65,21 +65,6 @@
50000,
"Stop inlining once caller reaches the threshold.");
DEFINE_FLAG(int,
- inlining_constant_arguments_count,
- 1,
- "Inline function calls with sufficient constant arguments "
- "and up to the increased threshold on instructions");
-DEFINE_FLAG(
- int,
- inlining_constant_arguments_max_size_threshold,
- 200,
- "Do not inline callees larger than threshold if constant arguments");
-DEFINE_FLAG(int,
- inlining_constant_arguments_min_size_threshold,
- 60,
- "Inline function calls with sufficient constant arguments "
- "and up to the increased threshold on instructions");
-DEFINE_FLAG(int,
inlining_hotness,
10,
"Inline only hotter calls, in percents (0 .. 100); "
@@ -779,45 +764,36 @@
};
// Inlining heuristics based on Cooper et al. 2008.
- // TODO(ajcbik): with the better specialized computation of counts,
- // do we still want to special-case const_arg_count here?
InliningDecision ShouldWeInline(const Function& callee,
intptr_t instr_count,
- intptr_t call_site_count,
- intptr_t const_arg_count) {
+ intptr_t call_site_count) {
+ // Pragma or size heuristics.
if (inliner_->AlwaysInline(callee)) {
return InliningDecision::Yes("AlwaysInline");
- }
- if (inlined_size_ > FLAG_inlining_caller_size_threshold) {
- // Prevent methods becoming humongous and thus slow to compile.
+ } else if (inlined_size_ > FLAG_inlining_caller_size_threshold) {
+ // Prevent caller methods becoming humongous and thus slow to compile.
return InliningDecision::No("--inlining-caller-size-threshold");
- }
- if (const_arg_count > 0) {
- if (instr_count > FLAG_inlining_constant_arguments_max_size_threshold) {
- return InliningDecision(
- false, "--inlining-constant-arguments-max-size-threshold");
- }
} else if (instr_count > FLAG_inlining_callee_size_threshold) {
+ // Prevent inlining of callee methods that exceed certain size.
return InliningDecision::No("--inlining-callee-size-threshold");
}
- int callee_inlining_depth = callee.inlining_depth();
- if (callee_inlining_depth > 0 && callee_inlining_depth + inlining_depth_ >
- FLAG_inlining_depth_threshold) {
+ // Inlining depth.
+ const int callee_inlining_depth = callee.inlining_depth();
+ if (callee_inlining_depth > 0 &&
+ ((callee_inlining_depth + inlining_depth_) >
+ FLAG_inlining_depth_threshold)) {
return InliningDecision::No("--inlining-depth-threshold");
}
- // 'instr_count' can be 0 if it was not computed yet.
- if ((instr_count != 0) && (instr_count <= FLAG_inlining_size_threshold)) {
+ // Situation instr_count == 0 denotes no counts have been computed yet.
+ // In that case, we say ok to the early heuristic and come back with the
+ // late heuristic.
+ if (instr_count == 0) {
+ return InliningDecision::Yes("need to count first");
+ } else if (instr_count <= FLAG_inlining_size_threshold) {
return InliningDecision::Yes("--inlining-size-threshold");
- }
- if (call_site_count <= FLAG_inlining_callee_call_sites_threshold) {
+ } else if (call_site_count <= FLAG_inlining_callee_call_sites_threshold) {
return InliningDecision::Yes("--inlining-callee-call-sites-threshold");
}
- if ((const_arg_count >= FLAG_inlining_constant_arguments_count) &&
- (instr_count <= FLAG_inlining_constant_arguments_min_size_threshold)) {
- return InliningDecision(true,
- "--inlining-constant-arguments-count and "
- "inlining-constant-arguments-min-size-threshold");
- }
return InliningDecision::No("default");
}
@@ -968,8 +944,8 @@
constant_arg_count == 0 ? function.optimized_instruction_count() : 0;
const intptr_t call_site_count =
constant_arg_count == 0 ? function.optimized_call_site_count() : 0;
- InliningDecision decision = ShouldWeInline(
- function, instruction_count, call_site_count, constant_arg_count);
+ InliningDecision decision =
+ ShouldWeInline(function, instruction_count, call_site_count);
if (!decision.value) {
TRACE_INLINING(
THR_Print(" Bailout: early heuristics (%s) with "
@@ -1216,16 +1192,12 @@
&call_site_count);
// Use heuristics do decide if this call should be inlined.
- InliningDecision decision = ShouldWeInline(
- function, instruction_count, call_site_count, constants_count);
+ InliningDecision decision =
+ ShouldWeInline(function, instruction_count, call_site_count);
if (!decision.value) {
// If size is larger than all thresholds, don't consider it again.
if ((instruction_count > FLAG_inlining_size_threshold) &&
- (call_site_count > FLAG_inlining_callee_call_sites_threshold) &&
- (instruction_count >
- FLAG_inlining_constant_arguments_min_size_threshold) &&
- (instruction_count >
- FLAG_inlining_constant_arguments_max_size_threshold)) {
+ (call_site_count > FLAG_inlining_callee_call_sites_threshold)) {
function.set_is_inlinable(false);
}
TRACE_INLINING(