Chromium Code Reviews| Index: runtime/vm/flow_graph_inliner.cc |
| =================================================================== |
| --- runtime/vm/flow_graph_inliner.cc (revision 24374) |
| +++ runtime/vm/flow_graph_inliner.cc (working copy) |
| @@ -189,10 +189,6 @@ |
| instance_calls_(), |
| skip_static_call_deopt_ids_() { } |
| - const GrowableArray<StaticCallInstr*>& static_calls() const { |
| - return static_calls_; |
| - } |
| - |
| const GrowableArray<ClosureCallInstr*>& closure_calls() const { |
| return closure_calls_; |
| } |
| @@ -204,10 +200,21 @@ |
| : call(call_arg), ratio(0.0) {} |
| }; |
| + struct StaticCallInfo { |
| + StaticCallInstr* call; |
| + double ratio; |
| + explicit StaticCallInfo(StaticCallInstr* value) |
| + : call(value), ratio(0.0) {} |
| + }; |
| + |
| const GrowableArray<InstanceCallInfo>& instance_calls() const { |
| return instance_calls_; |
| } |
| + const GrowableArray<StaticCallInfo>& static_calls() const { |
| + return static_calls_; |
| + } |
| + |
| bool HasCalls() const { |
| return !(static_calls_.is_empty() && |
| closure_calls_.is_empty() && |
| @@ -221,6 +228,44 @@ |
| skip_static_call_deopt_ids_.Clear(); |
| } |
| + void ComputeCallSiteRatio(intptr_t static_call_start_ix, |
| + intptr_t instance_call_start_ix) { |
| + const intptr_t num_static_calls = |
| + static_calls_.length() - static_call_start_ix; |
| + const intptr_t num_instance_calls = |
| + instance_calls_.length() - instance_call_start_ix; |
| + |
| + intptr_t max_count = 0; |
| + GrowableArray<intptr_t> instance_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(); |
| + instance_call_counts.Add(aggregate_count); |
| + if (aggregate_count > max_count) max_count = aggregate_count; |
| + } |
| + |
| + GrowableArray<intptr_t> static_call_counts(num_static_calls); |
| + for (intptr_t i = 0; i < num_static_calls; ++i) { |
| + const intptr_t aggregate_count = |
| + static_calls_[i + static_call_start_ix]. |
| + call->ic_data()->AggregateCount(); |
| + static_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>(instance_call_counts[i]) / max_count; |
| + instance_calls_[i + instance_call_start_ix].ratio = ratio; |
| + } |
| + for (intptr_t i = 0; i < num_static_calls; ++i) { |
| + const double ratio = |
| + static_cast<double>(static_call_counts[i]) / max_count; |
| + static_calls_[i + static_call_start_ix].ratio = ratio; |
| + } |
| + } |
| + |
| void FindCallSites(FlowGraph* graph) { |
| ASSERT(graph != NULL); |
| const Function& function = graph->parsed_function().function(); |
| @@ -231,6 +276,7 @@ |
| code.ExtractUncalledStaticCallDeoptIds(&skip_static_call_deopt_ids_); |
| const intptr_t instance_call_start_ix = instance_calls_.length(); |
| + const intptr_t static_call_start_ix = static_calls_.length(); |
| for (BlockIterator block_it = graph->postorder_iterator(); |
| !block_it.Done(); |
| block_it.Advance()) { |
| @@ -240,24 +286,7 @@ |
| 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(); |
| - 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; |
| - } |
| + ComputeCallSiteRatio(static_call_start_ix, instance_call_start_ix); |
| } |
| void VisitClosureCall(ClosureCallInstr* call) { |
| @@ -277,11 +306,11 @@ |
| return; |
| } |
| } |
| - static_calls_.Add(call); |
| + static_calls_.Add(StaticCallInfo(call)); |
| } |
| private: |
| - GrowableArray<StaticCallInstr*> static_calls_; |
| + GrowableArray<StaticCallInfo> static_calls_; |
| GrowableArray<ClosureCallInstr*> closure_calls_; |
| GrowableArray<InstanceCallInfo> instance_calls_; |
| GrowableArray<intptr_t> skip_static_call_deopt_ids_; |
| @@ -713,11 +742,11 @@ |
| // if the incoming argument is a non-constant value. |
| // TODO(srdjan): Fix inlining of List. factory. |
| void InlineStaticCalls() { |
| - const GrowableArray<StaticCallInstr*>& calls = |
| + const GrowableArray<CallSites::StaticCallInfo>& call_info = |
| 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]; |
| + TRACE_INLINING(OS::Print(" Static Calls (%d)\n", call_info.length())); |
| + for (intptr_t call_idx = 0; call_idx < call_info.length(); ++call_idx) { |
| + StaticCallInstr* call = call_info[call_idx].call; |
| if (call->function().name() == Symbols::ListFactory().raw()) { |
| // Inline only if no arguments or a constant was passed. |
| ASSERT(call->function().NumImplicitParameters() == 1); |
| @@ -730,6 +759,15 @@ |
| continue; |
| } |
| } |
| + if ((call_info[call_idx].ratio * 100) < FLAG_inlining_hotness) { |
|
Florian Schneider
2013/06/25 08:48:32
Maybe we need to adapt the threshold now that stat
|
| + const Function& target = call->function(); |
| + TRACE_INLINING(OS::Print( |
| + " => %s (deopt count %d)\n Bailout: cold %f\n", |
| + target.ToCString(), |
| + target.deoptimization_counter(), |
| + call_info[call_idx].ratio)); |
| + continue; |
| + } |
| GrowableArray<Value*> arguments(call->ArgumentCount()); |
| for (int i = 0; i < call->ArgumentCount(); ++i) { |
| arguments.Add(call->PushArgumentAt(i)->value()); |