OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 #if !defined(DART_PRECOMPILED_RUNTIME) | 4 #if !defined(DART_PRECOMPILED_RUNTIME) |
5 #include "vm/flow_graph_inliner.h" | 5 #include "vm/flow_graph_inliner.h" |
6 | 6 |
7 #include "vm/aot_optimizer.h" | 7 #include "vm/aot_optimizer.h" |
8 #include "vm/precompiler.h" | 8 #include "vm/precompiler.h" |
9 #include "vm/block_scheduler.h" | 9 #include "vm/block_scheduler.h" |
10 #include "vm/branch_optimizer.h" | 10 #include "vm/branch_optimizer.h" |
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
290 GrowableArray<intptr_t> instance_call_counts(num_instance_calls); | 290 GrowableArray<intptr_t> instance_call_counts(num_instance_calls); |
291 for (intptr_t i = 0; i < num_instance_calls; ++i) { | 291 for (intptr_t i = 0; i < num_instance_calls; ++i) { |
292 const intptr_t aggregate_count = | 292 const intptr_t aggregate_count = |
293 instance_calls_[i + instance_call_start_ix].call->CallCount(); | 293 instance_calls_[i + instance_call_start_ix].call->CallCount(); |
294 instance_call_counts.Add(aggregate_count); | 294 instance_call_counts.Add(aggregate_count); |
295 if (aggregate_count > max_count) max_count = aggregate_count; | 295 if (aggregate_count > max_count) max_count = aggregate_count; |
296 } | 296 } |
297 | 297 |
298 GrowableArray<intptr_t> static_call_counts(num_static_calls); | 298 GrowableArray<intptr_t> static_call_counts(num_static_calls); |
299 for (intptr_t i = 0; i < num_static_calls; ++i) { | 299 for (intptr_t i = 0; i < num_static_calls; ++i) { |
300 intptr_t aggregate_count = 0; | 300 intptr_t aggregate_count = |
301 if (static_calls_[i + static_call_start_ix].call->ic_data() == NULL) { | 301 static_calls_[i + static_call_start_ix].call->CallCount(); |
302 aggregate_count = 0; | |
303 } else { | |
304 aggregate_count = static_calls_[i + static_call_start_ix] | |
305 .call->ic_data() | |
306 ->AggregateCount(); | |
307 } | |
308 static_call_counts.Add(aggregate_count); | 302 static_call_counts.Add(aggregate_count); |
309 if (aggregate_count > max_count) max_count = aggregate_count; | 303 if (aggregate_count > max_count) max_count = aggregate_count; |
310 } | 304 } |
311 | 305 |
312 // max_count can be 0 if none of the calls was executed. | 306 // max_count can be 0 if none of the calls was executed. |
313 for (intptr_t i = 0; i < num_instance_calls; ++i) { | 307 for (intptr_t i = 0; i < num_instance_calls; ++i) { |
314 const double ratio = | 308 const double ratio = |
315 (max_count == 0) | 309 (max_count == 0) |
316 ? 0.0 | 310 ? 0.0 |
317 : static_cast<double>(instance_call_counts[i]) / max_count; | 311 : static_cast<double>(instance_call_counts[i]) / max_count; |
(...skipping 962 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1280 } | 1274 } |
1281 } | 1275 } |
1282 | 1276 |
1283 void InlineInstanceCalls() { | 1277 void InlineInstanceCalls() { |
1284 const GrowableArray<CallSites::InstanceCallInfo>& call_info = | 1278 const GrowableArray<CallSites::InstanceCallInfo>& call_info = |
1285 inlining_call_sites_->instance_calls(); | 1279 inlining_call_sites_->instance_calls(); |
1286 TRACE_INLINING(THR_Print(" Polymorphic Instance Calls (%" Pd ")\n", | 1280 TRACE_INLINING(THR_Print(" Polymorphic Instance Calls (%" Pd ")\n", |
1287 call_info.length())); | 1281 call_info.length())); |
1288 for (intptr_t call_idx = 0; call_idx < call_info.length(); ++call_idx) { | 1282 for (intptr_t call_idx = 0; call_idx < call_info.length(); ++call_idx) { |
1289 PolymorphicInstanceCallInstr* call = call_info[call_idx].call; | 1283 PolymorphicInstanceCallInstr* call = call_info[call_idx].call; |
1290 if (call->with_checks()) { | 1284 // PolymorphicInliner introduces deoptimization paths. |
1291 // PolymorphicInliner introduces deoptimization paths. | 1285 if (!call->complete() && !FLAG_polymorphic_with_deopt) { |
1292 if (!call->complete() && !FLAG_polymorphic_with_deopt) { | 1286 TRACE_INLINING( |
1293 TRACE_INLINING( | 1287 THR_Print(" => %s\n Bailout: call with checks\n", |
1294 THR_Print(" => %s\n Bailout: call with checks\n", | 1288 call->instance_call()->function_name().ToCString())); |
1295 call->instance_call()->function_name().ToCString())); | |
1296 continue; | |
1297 } | |
1298 const Function& cl = call_info[call_idx].caller(); | |
1299 intptr_t caller_inlining_id = | |
1300 call_info[call_idx].caller_graph->inlining_id(); | |
1301 PolymorphicInliner inliner(this, call, cl, caller_inlining_id); | |
1302 inliner.Inline(); | |
1303 continue; | 1289 continue; |
1304 } | 1290 } |
1305 | 1291 const Function& cl = call_info[call_idx].caller(); |
1306 const Function& target = call->targets().MostPopularTarget(); | 1292 intptr_t caller_inlining_id = |
1307 if (!inliner_->AlwaysInline(target) && | 1293 call_info[call_idx].caller_graph->inlining_id(); |
1308 (call_info[call_idx].ratio * 100) < FLAG_inlining_hotness) { | 1294 PolymorphicInliner inliner(this, call, cl, caller_inlining_id); |
1309 if (trace_inlining()) { | 1295 inliner.Inline(); |
1310 String& name = String::Handle(target.QualifiedUserVisibleName()); | |
1311 THR_Print(" => %s (deopt count %d)\n Bailout: cold %f\n", | |
1312 name.ToCString(), target.deoptimization_counter(), | |
1313 call_info[call_idx].ratio); | |
1314 } | |
1315 PRINT_INLINING_TREE("Too cold", &call_info[call_idx].caller(), &target, | |
1316 call); | |
1317 continue; | |
1318 } | |
1319 GrowableArray<Value*> arguments(call->ArgumentCount()); | |
1320 for (int arg_i = 0; arg_i < call->ArgumentCount(); ++arg_i) { | |
1321 arguments.Add(call->PushArgumentAt(arg_i)->value()); | |
1322 } | |
1323 InlinedCallData call_data( | |
1324 call, &arguments, call_info[call_idx].caller(), | |
1325 call_info[call_idx].caller_graph->inlining_id()); | |
1326 if (TryInlining(target, call->instance_call()->argument_names(), | |
1327 &call_data)) { | |
1328 InlineCall(&call_data); | |
1329 } | |
1330 } | 1296 } |
1331 } | 1297 } |
1332 | 1298 |
1333 bool AdjustForOptionalParameters(const ParsedFunction& parsed_function, | 1299 bool AdjustForOptionalParameters(const ParsedFunction& parsed_function, |
1334 const Array& argument_names, | 1300 const Array& argument_names, |
1335 GrowableArray<Value*>* arguments, | 1301 GrowableArray<Value*>* arguments, |
1336 ZoneGrowableArray<Definition*>* param_stubs, | 1302 ZoneGrowableArray<Definition*>* param_stubs, |
1337 FlowGraph* callee_graph) { | 1303 FlowGraph* callee_graph) { |
1338 const Function& function = parsed_function.function(); | 1304 const Function& function = parsed_function.function(); |
1339 // The language and this code does not support both optional positional | 1305 // The language and this code does not support both optional positional |
(...skipping 545 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1885 // Move push arguments of the call. | 1851 // Move push arguments of the call. |
1886 for (intptr_t i = 0; i < call_->ArgumentCount(); ++i) { | 1852 for (intptr_t i = 0; i < call_->ArgumentCount(); ++i) { |
1887 PushArgumentInstr* push = call_->PushArgumentAt(i); | 1853 PushArgumentInstr* push = call_->PushArgumentAt(i); |
1888 push->ReplaceUsesWith(push->value()->definition()); | 1854 push->ReplaceUsesWith(push->value()->definition()); |
1889 push->previous()->LinkTo(push->next()); | 1855 push->previous()->LinkTo(push->next()); |
1890 cursor->LinkTo(push); | 1856 cursor->LinkTo(push); |
1891 cursor = push; | 1857 cursor = push; |
1892 } | 1858 } |
1893 PolymorphicInstanceCallInstr* fallback_call = | 1859 PolymorphicInstanceCallInstr* fallback_call = |
1894 new PolymorphicInstanceCallInstr( | 1860 new PolymorphicInstanceCallInstr( |
1895 call_->instance_call(), *non_inlined_variants_, | 1861 call_->instance_call(), *non_inlined_variants_, call_->complete()); |
1896 /* with_checks = */ true, call_->complete()); | |
1897 fallback_call->set_ssa_temp_index( | 1862 fallback_call->set_ssa_temp_index( |
1898 owner_->caller_graph()->alloc_ssa_temp_index()); | 1863 owner_->caller_graph()->alloc_ssa_temp_index()); |
1899 fallback_call->InheritDeoptTarget(zone(), call_); | 1864 fallback_call->InheritDeoptTarget(zone(), call_); |
1900 fallback_call->set_total_call_count(call_->CallCount()); | 1865 fallback_call->set_total_call_count(call_->CallCount()); |
1901 ReturnInstr* fallback_return = new ReturnInstr( | 1866 ReturnInstr* fallback_return = new ReturnInstr( |
1902 call_->instance_call()->token_pos(), new Value(fallback_call)); | 1867 call_->instance_call()->token_pos(), new Value(fallback_call)); |
1903 fallback_return->InheritDeoptTargetAfter(owner_->caller_graph(), call_, | 1868 fallback_return->InheritDeoptTargetAfter(owner_->caller_graph(), call_, |
1904 fallback_call); | 1869 fallback_call); |
1905 AppendInstruction(AppendInstruction(cursor, fallback_call), | 1870 AppendInstruction(AppendInstruction(cursor, fallback_call), |
1906 fallback_return); | 1871 fallback_return); |
(...skipping 1902 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3809 } | 3774 } |
3810 | 3775 |
3811 default: | 3776 default: |
3812 return false; | 3777 return false; |
3813 } | 3778 } |
3814 } | 3779 } |
3815 | 3780 |
3816 | 3781 |
3817 } // namespace dart | 3782 } // namespace dart |
3818 #endif // !defined(DART_PRECOMPILED_RUNTIME) | 3783 #endif // !defined(DART_PRECOMPILED_RUNTIME) |
OLD | NEW |