| 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 |