Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(32)

Unified Diff: runtime/vm/flow_graph_inliner.cc

Issue 11541002: Use call counts to prevent cold calls from being inlined. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | runtime/vm/object.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/flow_graph_inliner.cc
===================================================================
--- runtime/vm/flow_graph_inliner.cc (revision 16141)
+++ runtime/vm/flow_graph_inliner.cc (working copy)
@@ -36,6 +36,9 @@
DEFINE_FLAG(int, inlining_constant_arguments_size_threshold, 60,
"Inline function calls with sufficient constant arguments "
"and up to the increased threshold on instructions");
+DEFINE_FLAG(int, inlining_hotness, 15,
+ "Inline only hotter calls, in percents (0 .. 100); "
+ "default 20%: calls above-equal 20% of max-count are inlined.");
Vyacheslav Egorov (Google) 2012/12/17 13:16:05 comment does not match the default value.
srdjan 2012/12/17 22:46:13 Done.
DECLARE_FLAG(bool, print_flow_graph);
DECLARE_FLAG(int, deoptimization_counter_threshold);
@@ -183,21 +186,28 @@
static_calls_(),
closure_calls_(),
instance_calls_(),
- skip_static_call_deopt_ids_() { }
+ instance_calls_caller_count_(),
+ skip_static_call_deopt_ids_(),
+ caller_count_(1) { }
- GrowableArray<StaticCallInstr*>* static_calls() {
- return &static_calls_;
+ const GrowableArray<StaticCallInstr*>& static_calls() const {
+ return static_calls_;
}
- GrowableArray<ClosureCallInstr*>* closure_calls() {
- return &closure_calls_;
+ const GrowableArray<ClosureCallInstr*>& closure_calls() const {
+ return closure_calls_;
}
- GrowableArray<PolymorphicInstanceCallInstr*>* instance_calls() {
- return &instance_calls_;
+ const GrowableArray<PolymorphicInstanceCallInstr*>& instance_calls() const {
Vyacheslav Egorov (Google) 2012/12/17 13:16:05 I'd prefer that this array contained a two field s
srdjan 2012/12/17 22:46:13 Done.
+ return instance_calls_;
}
+ const GrowableArray<intptr_t>& instance_calls_caller_count() const {
+ return instance_calls_caller_count_;
+ }
+
bool HasCalls() const {
+ ASSERT(instance_calls_.length() == instance_calls_caller_count_.length());
return !(static_calls_.is_empty() &&
closure_calls_.is_empty() &&
instance_calls_.is_empty());
@@ -207,10 +217,13 @@
static_calls_.Clear();
closure_calls_.Clear();
instance_calls_.Clear();
+ instance_calls_caller_count_.Clear();
skip_static_call_deopt_ids_.Clear();
}
- void FindCallSites(FlowGraph* graph) {
+ void FindCallSites(FlowGraph* graph, intptr_t caller_count) {
+ const intptr_t prev_caller_count = caller_count_;
+ caller_count_ = caller_count;
ASSERT(graph != NULL);
const Function& function = graph->parsed_function().function();
ASSERT(function.HasCode());
@@ -226,6 +239,7 @@
it.Current()->Accept(this);
}
}
+ caller_count_ = prev_caller_count;
}
void VisitClosureCall(ClosureCallInstr* call) {
@@ -234,6 +248,7 @@
void VisitPolymorphicInstanceCall(PolymorphicInstanceCallInstr* call) {
instance_calls_.Add(call);
+ instance_calls_caller_count_.Add(caller_count_);
}
void VisitStaticCall(StaticCallInstr* call) {
@@ -252,7 +267,9 @@
GrowableArray<StaticCallInstr*> static_calls_;
GrowableArray<ClosureCallInstr*> closure_calls_;
GrowableArray<PolymorphicInstanceCallInstr*> instance_calls_;
+ GrowableArray<intptr_t> instance_calls_caller_count_;
GrowableArray<intptr_t> skip_static_call_deopt_ids_;
+ intptr_t caller_count_;
DISALLOW_COPY_AND_ASSIGN(CallSites);
};
@@ -304,7 +321,7 @@
collected_call_sites_ = &sites1;
inlining_call_sites_ = &sites2;
// Collect initial call sites.
- collected_call_sites_->FindCallSites(caller_graph_);
+ collected_call_sites_->FindCallSites(caller_graph_, 1);
while (collected_call_sites_->HasCalls()) {
TRACE_INLINING(OS::Print(" Depth %"Pd" ----------\n", inlining_depth_));
// Swap collected and inlining arrays and clear the new collecting array.
@@ -334,7 +351,8 @@
bool TryInlining(const Function& function,
const Array& argument_names,
GrowableArray<Value*>* arguments,
- Definition* call) {
+ Definition* call,
+ intptr_t caller_count) {
TRACE_INLINING(OS::Print(" => %s (deopt count %d)\n",
function.ToCString(),
function.deoptimization_counter()));
@@ -511,7 +529,7 @@
// If depth is less or equal to threshold recursively add call sites.
if (inlining_depth_ < FLAG_inlining_depth_threshold) {
- collected_call_sites_->FindCallSites(callee_graph);
+ collected_call_sites_->FindCallSites(callee_graph, caller_count);
}
{
@@ -601,7 +619,7 @@
void InlineStaticCalls() {
const GrowableArray<StaticCallInstr*>& calls =
- *inlining_call_sites_->static_calls();
+ inlining_call_sites_->static_calls();
TRACE_INLINING(OS::Print(" Static Calls (%d)\n", calls.length()));
for (intptr_t i = 0; i < calls.length(); ++i) {
StaticCallInstr* call = calls[i];
@@ -609,13 +627,17 @@
for (int i = 0; i < call->ArgumentCount(); ++i) {
arguments.Add(call->ArgumentAt(i)->value());
}
- TryInlining(call->function(), call->argument_names(), &arguments, call);
+ TryInlining(call->function(),
+ call->argument_names(),
+ &arguments,
+ call,
+ 1);
}
}
void InlineClosureCalls() {
const GrowableArray<ClosureCallInstr*>& calls =
- *inlining_call_sites_->closure_calls();
+ inlining_call_sites_->closure_calls();
TRACE_INLINING(OS::Print(" Closure Calls (%d)\n", calls.length()));
for (intptr_t i = 0; i < calls.length(); ++i) {
ClosureCallInstr* call = calls[i];
@@ -634,35 +656,60 @@
TryInlining(closure->function(),
call->argument_names(),
&arguments,
- call);
+ call,
+ 1);
}
}
void InlineInstanceCalls() {
const GrowableArray<PolymorphicInstanceCallInstr*>& calls =
- *inlining_call_sites_->instance_calls();
+ inlining_call_sites_->instance_calls();
+ const GrowableArray<intptr_t>& calls_caller_count =
+ inlining_call_sites_->instance_calls_caller_count();
TRACE_INLINING(OS::Print(" Polymorphic Instance Calls (%d)\n",
calls.length()));
+ GrowableArray<intptr_t> call_counts(calls.length());
+ intptr_t max_count = 0;
for (intptr_t i = 0; i < calls.length(); ++i) {
+ const intptr_t count =
+ calls[i]->ic_data().AggregateCount() * calls_caller_count[i];
Vyacheslav Egorov (Google) 2012/12/17 13:16:05 I can't fully grasp the physical meaning behind th
srdjan 2012/12/17 22:46:13 You are right. Changed to use a ratio per one scop
+ call_counts.Add(count);
+ if (count > max_count) {
+ max_count = count;
+ }
+ }
+ for (intptr_t i = 0; i < calls.length(); ++i) {
PolymorphicInstanceCallInstr* instr = calls[i];
const ICData& ic_data = instr->ic_data();
const Function& target = Function::ZoneHandle(ic_data.GetTargetAt(0));
if (instr->with_checks()) {
TRACE_INLINING(OS::Print(
- " => %s (deopt count %d)\n Bailout: %"Pd" checks\n",
- target.ToCString(),
- target.deoptimization_counter(),
- ic_data.NumberOfChecks()));
+ " => %s (deopt count %d)\n Bailout: %"Pd" checks\n",
+ target.ToCString(),
+ target.deoptimization_counter(),
+ ic_data.NumberOfChecks()));
continue;
}
+ const intptr_t count_threshold = FLAG_inlining_hotness < 0 ?
+ 0 : (max_count * FLAG_inlining_hotness) / 100;
+ if (call_counts[i] < count_threshold) {
+ TRACE_INLINING(OS::Print(
+ " => %s (deopt count %d)\n Bailout: cold %"Pd" limit %"Pd"\n",
+ target.ToCString(),
+ target.deoptimization_counter(),
+ call_counts[i],
+ count_threshold));
+ continue;
+ }
GrowableArray<Value*> arguments(instr->ArgumentCount());
- for (int i = 0; i < instr->ArgumentCount(); ++i) {
- arguments.Add(instr->ArgumentAt(i)->value());
+ for (int arg_i = 0; arg_i < instr->ArgumentCount(); ++arg_i) {
+ arguments.Add(instr->ArgumentAt(arg_i)->value());
}
TryInlining(target,
instr->instance_call()->argument_names(),
&arguments,
- instr);
+ instr,
+ call_counts[i]);
}
}
« no previous file with comments | « no previous file | runtime/vm/object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698