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 | 4 |
5 #include "vm/flow_graph_inliner.h" | 5 #include "vm/flow_graph_inliner.h" |
6 | 6 |
7 #include "vm/compiler.h" | 7 #include "vm/compiler.h" |
8 #include "vm/flags.h" | 8 #include "vm/flags.h" |
9 #include "vm/flow_graph.h" | 9 #include "vm/flow_graph.h" |
10 #include "vm/flow_graph_builder.h" | 10 #include "vm/flow_graph_builder.h" |
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
285 GrowableArray<ClosureCallInstr*> closure_calls_; | 285 GrowableArray<ClosureCallInstr*> closure_calls_; |
286 GrowableArray<InstanceCallInfo> instance_calls_; | 286 GrowableArray<InstanceCallInfo> instance_calls_; |
287 GrowableArray<intptr_t> skip_static_call_deopt_ids_; | 287 GrowableArray<intptr_t> skip_static_call_deopt_ids_; |
288 | 288 |
289 DISALLOW_COPY_AND_ASSIGN(CallSites); | 289 DISALLOW_COPY_AND_ASSIGN(CallSites); |
290 }; | 290 }; |
291 | 291 |
292 | 292 |
293 class CallSiteInliner : public ValueObject { | 293 class CallSiteInliner : public ValueObject { |
294 public: | 294 public: |
295 explicit CallSiteInliner(FlowGraph* flow_graph) | 295 CallSiteInliner(FlowGraph* flow_graph, GrowableArray<Field*>* guarded_fields) |
296 : caller_graph_(flow_graph), | 296 : caller_graph_(flow_graph), |
297 inlined_(false), | 297 inlined_(false), |
298 initial_size_(flow_graph->InstructionCount()), | 298 initial_size_(flow_graph->InstructionCount()), |
299 inlined_size_(0), | 299 inlined_size_(0), |
300 inlining_depth_(1), | 300 inlining_depth_(1), |
301 collected_call_sites_(NULL), | 301 collected_call_sites_(NULL), |
302 inlining_call_sites_(NULL), | 302 inlining_call_sites_(NULL), |
303 function_cache_() { } | 303 function_cache_(), |
| 304 guarded_fields_(guarded_fields) { } |
304 | 305 |
305 // Inlining heuristics based on Cooper et al. 2008. | 306 // Inlining heuristics based on Cooper et al. 2008. |
306 bool ShouldWeInline(intptr_t instr_count, | 307 bool ShouldWeInline(intptr_t instr_count, |
307 intptr_t call_site_count, | 308 intptr_t call_site_count, |
308 intptr_t const_arg_count) { | 309 intptr_t const_arg_count) { |
309 if (instr_count <= FLAG_inlining_size_threshold) { | 310 if (instr_count <= FLAG_inlining_size_threshold) { |
310 return true; | 311 return true; |
311 } | 312 } |
312 if (call_site_count <= FLAG_inlining_callee_call_sites_threshold) { | 313 if (call_site_count <= FLAG_inlining_callee_call_sites_threshold) { |
313 return true; | 314 return true; |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
494 callee_graph->ComputeSSA(caller_graph_->max_virtual_register_number(), | 495 callee_graph->ComputeSSA(caller_graph_->max_virtual_register_number(), |
495 ¶m_stubs); | 496 ¶m_stubs); |
496 DEBUG_ASSERT(callee_graph->VerifyUseLists()); | 497 DEBUG_ASSERT(callee_graph->VerifyUseLists()); |
497 } | 498 } |
498 | 499 |
499 { | 500 { |
500 TimerScope timer(FLAG_compiler_stats, | 501 TimerScope timer(FLAG_compiler_stats, |
501 &CompilerStats::graphinliner_opt_timer, | 502 &CompilerStats::graphinliner_opt_timer, |
502 isolate); | 503 isolate); |
503 // TODO(zerny): Do more optimization passes on the callee graph. | 504 // TODO(zerny): Do more optimization passes on the callee graph. |
504 FlowGraphOptimizer optimizer(callee_graph); | 505 FlowGraphOptimizer optimizer(callee_graph, guarded_fields_); |
505 optimizer.ApplyICData(); | 506 optimizer.ApplyICData(); |
506 DEBUG_ASSERT(callee_graph->VerifyUseLists()); | 507 DEBUG_ASSERT(callee_graph->VerifyUseLists()); |
507 } | 508 } |
508 | 509 |
509 if (FLAG_trace_inlining && | 510 if (FLAG_trace_inlining && |
510 (FLAG_print_flow_graph || FLAG_print_flow_graph_optimized)) { | 511 (FLAG_print_flow_graph || FLAG_print_flow_graph_optimized)) { |
511 OS::Print("Callee graph for inlining %s\n", | 512 OS::Print("Callee graph for inlining %s\n", |
512 function.ToFullyQualifiedCString()); | 513 function.ToFullyQualifiedCString()); |
513 FlowGraphPrinter printer(*callee_graph); | 514 FlowGraphPrinter printer(*callee_graph); |
514 printer.PrintBlocks(); | 515 printer.PrintBlocks(); |
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
827 | 828 |
828 | 829 |
829 FlowGraph* caller_graph_; | 830 FlowGraph* caller_graph_; |
830 bool inlined_; | 831 bool inlined_; |
831 intptr_t initial_size_; | 832 intptr_t initial_size_; |
832 intptr_t inlined_size_; | 833 intptr_t inlined_size_; |
833 intptr_t inlining_depth_; | 834 intptr_t inlining_depth_; |
834 CallSites* collected_call_sites_; | 835 CallSites* collected_call_sites_; |
835 CallSites* inlining_call_sites_; | 836 CallSites* inlining_call_sites_; |
836 GrowableArray<ParsedFunction*> function_cache_; | 837 GrowableArray<ParsedFunction*> function_cache_; |
| 838 GrowableArray<Field*>* guarded_fields_; |
837 | 839 |
838 DISALLOW_COPY_AND_ASSIGN(CallSiteInliner); | 840 DISALLOW_COPY_AND_ASSIGN(CallSiteInliner); |
839 }; | 841 }; |
840 | 842 |
841 | 843 |
842 void FlowGraphInliner::CollectGraphInfo(FlowGraph* flow_graph) { | 844 void FlowGraphInliner::CollectGraphInfo(FlowGraph* flow_graph) { |
843 GraphInfoCollector info; | 845 GraphInfoCollector info; |
844 info.Collect(*flow_graph); | 846 info.Collect(*flow_graph); |
845 const Function& function = flow_graph->parsed_function().function(); | 847 const Function& function = flow_graph->parsed_function().function(); |
846 function.set_optimized_instruction_count( | 848 function.set_optimized_instruction_count( |
(...skipping 20 matching lines...) Expand all Loading... |
867 flow_graph_->parsed_function().function().ToCString())); | 869 flow_graph_->parsed_function().function().ToCString())); |
868 | 870 |
869 if (FLAG_trace_inlining && | 871 if (FLAG_trace_inlining && |
870 (FLAG_print_flow_graph || FLAG_print_flow_graph_optimized)) { | 872 (FLAG_print_flow_graph || FLAG_print_flow_graph_optimized)) { |
871 OS::Print("Before Inlining of %s\n", flow_graph_-> | 873 OS::Print("Before Inlining of %s\n", flow_graph_-> |
872 parsed_function().function().ToFullyQualifiedCString()); | 874 parsed_function().function().ToFullyQualifiedCString()); |
873 FlowGraphPrinter printer(*flow_graph_); | 875 FlowGraphPrinter printer(*flow_graph_); |
874 printer.PrintBlocks(); | 876 printer.PrintBlocks(); |
875 } | 877 } |
876 | 878 |
877 CallSiteInliner inliner(flow_graph_); | 879 CallSiteInliner inliner(flow_graph_, guarded_fields_); |
878 inliner.InlineCalls(); | 880 inliner.InlineCalls(); |
879 | 881 |
880 if (inliner.inlined()) { | 882 if (inliner.inlined()) { |
881 flow_graph_->RepairGraphAfterInlining(); | 883 flow_graph_->RepairGraphAfterInlining(); |
882 if (FLAG_trace_inlining) { | 884 if (FLAG_trace_inlining) { |
883 OS::Print("Inlining growth factor: %f\n", inliner.GrowthFactor()); | 885 OS::Print("Inlining growth factor: %f\n", inliner.GrowthFactor()); |
884 if (FLAG_print_flow_graph || FLAG_print_flow_graph_optimized) { | 886 if (FLAG_print_flow_graph || FLAG_print_flow_graph_optimized) { |
885 OS::Print("After Inlining of %s\n", flow_graph_-> | 887 OS::Print("After Inlining of %s\n", flow_graph_-> |
886 parsed_function().function().ToFullyQualifiedCString()); | 888 parsed_function().function().ToFullyQualifiedCString()); |
887 FlowGraphPrinter printer(*flow_graph_); | 889 FlowGraphPrinter printer(*flow_graph_); |
888 printer.PrintBlocks(); | 890 printer.PrintBlocks(); |
889 } | 891 } |
890 } | 892 } |
891 } | 893 } |
892 } | 894 } |
893 | 895 |
894 } // namespace dart | 896 } // namespace dart |
OLD | NEW |