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/block_scheduler.h" | 8 #include "vm/block_scheduler.h" |
9 #include "vm/branch_optimizer.h" | 9 #include "vm/branch_optimizer.h" |
10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
(...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
374 for (BlockIterator block_it = graph->postorder_iterator(); !block_it.Done(); | 374 for (BlockIterator block_it = graph->postorder_iterator(); !block_it.Done(); |
375 block_it.Advance()) { | 375 block_it.Advance()) { |
376 for (ForwardInstructionIterator it(block_it.Current()); !it.Done(); | 376 for (ForwardInstructionIterator it(block_it.Current()); !it.Done(); |
377 it.Advance()) { | 377 it.Advance()) { |
378 Instruction* current = it.Current(); | 378 Instruction* current = it.Current(); |
379 if (current->IsPolymorphicInstanceCall()) { | 379 if (current->IsPolymorphicInstanceCall()) { |
380 PolymorphicInstanceCallInstr* instance_call = | 380 PolymorphicInstanceCallInstr* instance_call = |
381 current->AsPolymorphicInstanceCall(); | 381 current->AsPolymorphicInstanceCall(); |
382 if (!inline_only_recognized_methods || | 382 if (!inline_only_recognized_methods || |
383 instance_call->HasSingleRecognizedTarget() || | 383 instance_call->HasSingleRecognizedTarget() || |
384 instance_call->ic_data().HasOnlyDispatcherTargets()) { | 384 instance_call->ic_data() |
| 385 .HasOnlyDispatcherOrImplicitAccessorTargets()) { |
385 instance_calls_.Add(InstanceCallInfo(instance_call, graph)); | 386 instance_calls_.Add(InstanceCallInfo(instance_call, graph)); |
386 } else { | 387 } else { |
387 // Method not inlined because inlining too deep and method | 388 // Method not inlined because inlining too deep and method |
388 // not recognized. | 389 // not recognized. |
389 if (FLAG_print_inlining_tree) { | 390 if (FLAG_print_inlining_tree) { |
390 const Function* caller = &graph->function(); | 391 const Function* caller = &graph->function(); |
391 const Function* target = &Function::ZoneHandle( | 392 const Function* target = &Function::ZoneHandle( |
392 instance_call->ic_data().GetTargetAt(0)); | 393 instance_call->ic_data().GetTargetAt(0)); |
393 inlined_info->Add(InlinedInfo(caller, target, depth + 1, | 394 inlined_info->Add(InlinedInfo(caller, target, depth + 1, |
394 instance_call, "Too deep")); | 395 instance_call, "Too deep")); |
395 } | 396 } |
396 } | 397 } |
397 } else if (current->IsStaticCall()) { | 398 } else if (current->IsStaticCall()) { |
398 StaticCallInstr* static_call = current->AsStaticCall(); | 399 StaticCallInstr* static_call = current->AsStaticCall(); |
399 if (!inline_only_recognized_methods || | 400 if (!inline_only_recognized_methods || |
400 static_call->function().IsRecognized()) { | 401 static_call->function().IsRecognized() || |
| 402 static_call->function().IsDispatcherOrImplicitAccessor()) { |
401 static_calls_.Add(StaticCallInfo(static_call, graph)); | 403 static_calls_.Add(StaticCallInfo(static_call, graph)); |
402 } else { | 404 } else { |
403 // Method not inlined because inlining too deep and method | 405 // Method not inlined because inlining too deep and method |
404 // not recognized. | 406 // not recognized. |
405 if (FLAG_print_inlining_tree) { | 407 if (FLAG_print_inlining_tree) { |
406 const Function* caller = &graph->function(); | 408 const Function* caller = &graph->function(); |
407 const Function* target = &static_call->function(); | 409 const Function* target = &static_call->function(); |
408 inlined_info->Add(InlinedInfo(caller, target, depth + 1, | 410 inlined_info->Add(InlinedInfo(caller, target, depth + 1, |
409 static_call, "Too deep")); | 411 static_call, "Too deep")); |
410 } | 412 } |
(...skipping 518 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
929 "code size: %" Pd ", " | 931 "code size: %" Pd ", " |
930 "call sites: %" Pd ", " | 932 "call sites: %" Pd ", " |
931 "const args: %" Pd "\n", | 933 "const args: %" Pd "\n", |
932 size, call_site_count, constants_count)); | 934 size, call_site_count, constants_count)); |
933 PRINT_INLINING_TREE("Heuristic fail", &call_data->caller, &function, | 935 PRINT_INLINING_TREE("Heuristic fail", &call_data->caller, &function, |
934 call_data->call); | 936 call_data->call); |
935 return false; | 937 return false; |
936 } | 938 } |
937 | 939 |
938 // Inline dispatcher methods regardless of the current depth. | 940 // Inline dispatcher methods regardless of the current depth. |
939 const intptr_t depth = (function.IsInvokeFieldDispatcher() || | 941 const intptr_t depth = |
940 function.IsNoSuchMethodDispatcher()) | 942 function.IsDispatcherOrImplicitAccessor() ? 0 : inlining_depth_; |
941 ? 0 | |
942 : inlining_depth_; | |
943 collected_call_sites_->FindCallSites(callee_graph, depth, | 943 collected_call_sites_->FindCallSites(callee_graph, depth, |
944 &inlined_info_); | 944 &inlined_info_); |
945 | 945 |
946 // Add the function to the cache. | 946 // Add the function to the cache. |
947 if (!in_cache) { | 947 if (!in_cache) { |
948 function_cache_.Add(parsed_function); | 948 function_cache_.Add(parsed_function); |
949 } | 949 } |
950 | 950 |
951 // Build succeeded so we restore the bailout jump. | 951 // Build succeeded so we restore the bailout jump. |
952 inlined_ = true; | 952 inlined_ = true; |
(...skipping 964 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1917 | 1917 |
1918 bool FlowGraphInliner::AlwaysInline(const Function& function) { | 1918 bool FlowGraphInliner::AlwaysInline(const Function& function) { |
1919 const char* kAlwaysInlineAnnotation = "AlwaysInline"; | 1919 const char* kAlwaysInlineAnnotation = "AlwaysInline"; |
1920 if (FLAG_enable_inlining_annotations && | 1920 if (FLAG_enable_inlining_annotations && |
1921 HasAnnotation(function, kAlwaysInlineAnnotation)) { | 1921 HasAnnotation(function, kAlwaysInlineAnnotation)) { |
1922 TRACE_INLINING( | 1922 TRACE_INLINING( |
1923 THR_Print("AlwaysInline annotation for %s\n", function.ToCString())); | 1923 THR_Print("AlwaysInline annotation for %s\n", function.ToCString())); |
1924 return true; | 1924 return true; |
1925 } | 1925 } |
1926 | 1926 |
1927 if (function.IsImplicitGetterFunction() || | 1927 if (function.IsDispatcherOrImplicitAccessor()) { |
1928 function.IsImplicitSetterFunction()) { | 1928 // Smaller or same size as the call. |
1929 // Inlined accessors are smaller than a call. | |
1930 return true; | 1929 return true; |
1931 } | 1930 } |
1932 | 1931 |
1933 if (function.IsGetterFunction() || function.IsSetterFunction() || | 1932 if (function.IsGetterFunction() || function.IsSetterFunction() || |
1934 IsInlineableOperator(function) || | 1933 IsInlineableOperator(function) || |
1935 (function.kind() == RawFunction::kConstructor)) { | 1934 (function.kind() == RawFunction::kConstructor)) { |
1936 const intptr_t count = function.optimized_instruction_count(); | 1935 const intptr_t count = function.optimized_instruction_count(); |
1937 if ((count != 0) && (count < FLAG_inline_getters_setters_smaller_than)) { | 1936 if ((count != 0) && (count < FLAG_inline_getters_setters_smaller_than)) { |
1938 return true; | 1937 return true; |
1939 } | 1938 } |
(...skipping 1658 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3598 } | 3597 } |
3599 | 3598 |
3600 default: | 3599 default: |
3601 return false; | 3600 return false; |
3602 } | 3601 } |
3603 } | 3602 } |
3604 | 3603 |
3605 | 3604 |
3606 } // namespace dart | 3605 } // namespace dart |
3607 #endif // !defined(DART_PRECOMPILED_RUNTIME) | 3606 #endif // !defined(DART_PRECOMPILED_RUNTIME) |
OLD | NEW |