Chromium Code Reviews| Index: runtime/vm/flow_graph_inliner.cc |
| =================================================================== |
| --- runtime/vm/flow_graph_inliner.cc (revision 16232) |
| +++ 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, 10, |
| + "Inline only hotter calls, in percents (0 .. 100); " |
| + "default 10%: calls above-equal 10% of max-count are inlined."); |
| DECLARE_FLAG(bool, print_flow_graph); |
| DECLARE_FLAG(int, deoptimization_counter_threshold); |
| @@ -185,16 +188,23 @@ |
| instance_calls_(), |
| skip_static_call_deopt_ids_() { } |
| - 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_; |
| + struct InstanceCallInfo { |
| + PolymorphicInstanceCallInstr* call; |
| + double ratio; |
| + explicit InstanceCallInfo(PolymorphicInstanceCallInstr* call_arg) |
| + : call(call_arg), ratio(0.0) {} |
| + }; |
| + |
| + const GrowableArray<InstanceCallInfo>& instance_calls() const { |
| + return instance_calls_; |
| } |
| bool HasCalls() const { |
| @@ -215,8 +225,11 @@ |
| const Function& function = graph->parsed_function().function(); |
| ASSERT(function.HasCode()); |
| const Code& code = Code::Handle(function.unoptimized_code()); |
| + |
| skip_static_call_deopt_ids_.Clear(); |
| code.ExtractUncalledStaticCallDeoptIds(&skip_static_call_deopt_ids_); |
| + |
| + const intptr_t instance_call_start_ix = instance_calls_.length(); |
| for (BlockIterator block_it = graph->postorder_iterator(); |
| !block_it.Done(); |
| block_it.Advance()) { |
| @@ -226,6 +239,24 @@ |
| it.Current()->Accept(this); |
| } |
| } |
| + // Compute instance call site ratio. |
| + const intptr_t num_instance_calls = |
| + instance_calls_.length() - instance_call_start_ix; |
| + intptr_t max_count = 0; |
| + GrowableArray<intptr_t> call_counts(num_instance_calls); |
| + for (intptr_t i = 0; i < num_instance_calls; ++i) { |
| + const intptr_t aggregate_count = |
| + instance_calls_[i + instance_call_start_ix]. |
| + call-> ic_data().AggregateCount(); |
|
Vyacheslav Egorov (Google)
2012/12/18 11:55:51
remove space after ->
srdjan
2012/12/18 16:37:51
Done.
|
| + call_counts.Add(aggregate_count); |
| + if (aggregate_count > max_count) max_count = aggregate_count; |
| + } |
| + |
| + |
| + for (intptr_t i = 0; i < num_instance_calls; ++i) { |
| + const double ratio = static_cast<double>(call_counts[i]) / max_count; |
| + instance_calls_[i + instance_call_start_ix].ratio = ratio; |
| + } |
| } |
| void VisitClosureCall(ClosureCallInstr* call) { |
| @@ -233,7 +264,7 @@ |
| } |
| void VisitPolymorphicInstanceCall(PolymorphicInstanceCallInstr* call) { |
| - instance_calls_.Add(call); |
| + instance_calls_.Add(InstanceCallInfo(call)); |
| } |
| void VisitStaticCall(StaticCallInstr* call) { |
| @@ -251,7 +282,7 @@ |
| private: |
| GrowableArray<StaticCallInstr*> static_calls_; |
| GrowableArray<ClosureCallInstr*> closure_calls_; |
| - GrowableArray<PolymorphicInstanceCallInstr*> instance_calls_; |
| + GrowableArray<InstanceCallInfo> instance_calls_; |
| GrowableArray<intptr_t> skip_static_call_deopt_ids_; |
| DISALLOW_COPY_AND_ASSIGN(CallSites); |
| @@ -630,7 +661,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]; |
| @@ -644,7 +675,7 @@ |
| 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]; |
| @@ -668,25 +699,33 @@ |
| } |
| void InlineInstanceCalls() { |
| - const GrowableArray<PolymorphicInstanceCallInstr*>& calls = |
| - *inlining_call_sites_->instance_calls(); |
| + const GrowableArray<CallSites::InstanceCallInfo>& call_info = |
| + inlining_call_sites_->instance_calls(); |
| TRACE_INLINING(OS::Print(" Polymorphic Instance Calls (%d)\n", |
| - calls.length())); |
| - for (intptr_t i = 0; i < calls.length(); ++i) { |
| - PolymorphicInstanceCallInstr* instr = calls[i]; |
| + call_info.length())); |
| + for (intptr_t i = 0; i < call_info.length(); ++i) { |
| + PolymorphicInstanceCallInstr* instr = call_info[i].call; |
| 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; |
| } |
| + if ((call_info[i].ratio * 100) < FLAG_inlining_hotness) { |
| + TRACE_INLINING(OS::Print( |
| + " => %s (deopt count %d)\n Bailout: cold %f\n", |
| + target.ToCString(), |
| + target.deoptimization_counter(), |
| + call_info[i].ratio)); |
| + 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(), |