| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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/compiler.h" | 5 #include "vm/compiler.h" |
| 6 | 6 |
| 7 #include "vm/assembler.h" | 7 #include "vm/assembler.h" |
| 8 | 8 |
| 9 #include "vm/ast_printer.h" | 9 #include "vm/ast_printer.h" |
| 10 #include "vm/block_scheduler.h" |
| 10 #include "vm/code_generator.h" | 11 #include "vm/code_generator.h" |
| 11 #include "vm/code_patcher.h" | 12 #include "vm/code_patcher.h" |
| 12 #include "vm/dart_entry.h" | 13 #include "vm/dart_entry.h" |
| 13 #include "vm/debugger.h" | 14 #include "vm/debugger.h" |
| 14 #include "vm/deopt_instructions.h" | 15 #include "vm/deopt_instructions.h" |
| 15 #include "vm/exceptions.h" | 16 #include "vm/exceptions.h" |
| 16 #include "vm/flags.h" | 17 #include "vm/flags.h" |
| 17 #include "vm/flow_graph.h" | 18 #include "vm/flow_graph.h" |
| 18 #include "vm/flow_graph_allocator.h" | 19 #include "vm/flow_graph_allocator.h" |
| 19 #include "vm/flow_graph_builder.h" | 20 #include "vm/flow_graph_builder.h" |
| (...skipping 25 matching lines...) Expand all Loading... |
| 45 "Do loop invariant code motion."); | 46 "Do loop invariant code motion."); |
| 46 DEFINE_FLAG(bool, propagate_types, true, "Do static type propagation."); | 47 DEFINE_FLAG(bool, propagate_types, true, "Do static type propagation."); |
| 47 DEFINE_FLAG(bool, allocation_sinking, true, | 48 DEFINE_FLAG(bool, allocation_sinking, true, |
| 48 "attempt to sink temporary allocations to side exits"); | 49 "attempt to sink temporary allocations to side exits"); |
| 49 DEFINE_FLAG(int, deoptimization_counter_threshold, 16, | 50 DEFINE_FLAG(int, deoptimization_counter_threshold, 16, |
| 50 "How many times we allow deoptimization before we disallow optimization."); | 51 "How many times we allow deoptimization before we disallow optimization."); |
| 51 DEFINE_FLAG(int, deoptimization_counter_licm_threshold, 8, | 52 DEFINE_FLAG(int, deoptimization_counter_licm_threshold, 8, |
| 52 "How many times we allow deoptimization before we disable LICM."); | 53 "How many times we allow deoptimization before we disable LICM."); |
| 53 DEFINE_FLAG(bool, use_inlining, true, "Enable call-site inlining"); | 54 DEFINE_FLAG(bool, use_inlining, true, "Enable call-site inlining"); |
| 54 DEFINE_FLAG(bool, range_analysis, true, "Enable range analysis"); | 55 DEFINE_FLAG(bool, range_analysis, true, "Enable range analysis"); |
| 56 DEFINE_FLAG(bool, reorder_basic_blocks, true, "Enable basic-block reordering."); |
| 55 DEFINE_FLAG(bool, verify_compiler, false, | 57 DEFINE_FLAG(bool, verify_compiler, false, |
| 56 "Enable compiler verification assertions"); | 58 "Enable compiler verification assertions"); |
| 57 DECLARE_FLAG(bool, print_flow_graph); | 59 DECLARE_FLAG(bool, print_flow_graph); |
| 58 DECLARE_FLAG(bool, print_flow_graph_optimized); | 60 DECLARE_FLAG(bool, print_flow_graph_optimized); |
| 59 DECLARE_FLAG(bool, trace_failed_optimization_attempts); | 61 DECLARE_FLAG(bool, trace_failed_optimization_attempts); |
| 60 | 62 |
| 61 // Compile a function. Should call only if the function has not been compiled. | 63 // Compile a function. Should call only if the function has not been compiled. |
| 62 // Arg0: function object. | 64 // Arg0: function object. |
| 63 DEFINE_RUNTIME_ENTRY(CompileFunction, 1) { | 65 DEFINE_RUNTIME_ENTRY(CompileFunction, 1) { |
| 64 ASSERT(arguments.ArgCount() == kCompileFunctionRuntimeEntry.argument_count()); | 66 ASSERT(arguments.ArgCount() == kCompileFunctionRuntimeEntry.argument_count()); |
| (...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 298 | 300 |
| 299 if (FLAG_print_flow_graph || | 301 if (FLAG_print_flow_graph || |
| 300 (optimized && FLAG_print_flow_graph_optimized)) { | 302 (optimized && FLAG_print_flow_graph_optimized)) { |
| 301 if (osr_id == Isolate::kNoDeoptId) { | 303 if (osr_id == Isolate::kNoDeoptId) { |
| 302 FlowGraphPrinter::PrintGraph("Before Optimizations", flow_graph); | 304 FlowGraphPrinter::PrintGraph("Before Optimizations", flow_graph); |
| 303 } else { | 305 } else { |
| 304 FlowGraphPrinter::PrintGraph("For OSR", flow_graph); | 306 FlowGraphPrinter::PrintGraph("For OSR", flow_graph); |
| 305 } | 307 } |
| 306 } | 308 } |
| 307 | 309 |
| 310 BlockScheduler block_scheduler(flow_graph); |
| 311 if (optimized && FLAG_reorder_basic_blocks) { |
| 312 block_scheduler.AssignEdgeWeights(); |
| 313 } |
| 314 |
| 308 if (optimized) { | 315 if (optimized) { |
| 309 TimerScope timer(FLAG_compiler_stats, | 316 TimerScope timer(FLAG_compiler_stats, |
| 310 &CompilerStats::ssa_timer, | 317 &CompilerStats::ssa_timer, |
| 311 isolate); | 318 isolate); |
| 312 // Transform to SSA (virtual register 0 and no inlining arguments). | 319 // Transform to SSA (virtual register 0 and no inlining arguments). |
| 313 flow_graph->ComputeSSA(0, NULL); | 320 flow_graph->ComputeSSA(0, NULL); |
| 314 DEBUG_ASSERT(flow_graph->VerifyUseLists()); | 321 DEBUG_ASSERT(flow_graph->VerifyUseLists()); |
| 315 if (FLAG_print_flow_graph || FLAG_print_flow_graph_optimized) { | 322 if (FLAG_print_flow_graph || FLAG_print_flow_graph_optimized) { |
| 316 FlowGraphPrinter::PrintGraph("After SSA", flow_graph); | 323 FlowGraphPrinter::PrintGraph("After SSA", flow_graph); |
| 317 } | 324 } |
| 318 } | 325 } |
| 319 | 326 |
| 320 | |
| 321 // Collect all instance fields that are loaded in the graph and | 327 // Collect all instance fields that are loaded in the graph and |
| 322 // have non-generic type feedback attached to them that can | 328 // have non-generic type feedback attached to them that can |
| 323 // potentially affect optimizations. | 329 // potentially affect optimizations. |
| 324 GrowableArray<const Field*> guarded_fields(10); | 330 GrowableArray<const Field*> guarded_fields(10); |
| 325 if (optimized) { | 331 if (optimized) { |
| 326 TimerScope timer(FLAG_compiler_stats, | 332 TimerScope timer(FLAG_compiler_stats, |
| 327 &CompilerStats::graphoptimizer_timer, | 333 &CompilerStats::graphoptimizer_timer, |
| 328 isolate); | 334 isolate); |
| 329 | 335 |
| 330 FlowGraphOptimizer optimizer(flow_graph, &guarded_fields); | 336 FlowGraphOptimizer optimizer(flow_graph, &guarded_fields); |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 497 // Remove all MaterializeObject instructions inserted by allocation | 503 // Remove all MaterializeObject instructions inserted by allocation |
| 498 // sinking from the flow graph and let them float on the side | 504 // sinking from the flow graph and let them float on the side |
| 499 // referenced only from environments. Register allocator will consider | 505 // referenced only from environments. Register allocator will consider |
| 500 // them as part of a deoptimization environment. | 506 // them as part of a deoptimization environment. |
| 501 sinking->DetachMaterializations(); | 507 sinking->DetachMaterializations(); |
| 502 } | 508 } |
| 503 | 509 |
| 504 // Perform register allocation on the SSA graph. | 510 // Perform register allocation on the SSA graph. |
| 505 FlowGraphAllocator allocator(*flow_graph); | 511 FlowGraphAllocator allocator(*flow_graph); |
| 506 allocator.AllocateRegisters(); | 512 allocator.AllocateRegisters(); |
| 513 if (FLAG_reorder_basic_blocks) block_scheduler.ReorderBlocks(); |
| 507 | 514 |
| 508 if (FLAG_print_flow_graph || FLAG_print_flow_graph_optimized) { | 515 if (FLAG_print_flow_graph || FLAG_print_flow_graph_optimized) { |
| 509 FlowGraphPrinter::PrintGraph("After Optimizations", flow_graph); | 516 FlowGraphPrinter::PrintGraph("After Optimizations", flow_graph); |
| 510 } | 517 } |
| 511 } | 518 } |
| 512 | 519 |
| 513 Assembler assembler(use_far_branches); | 520 Assembler assembler(use_far_branches); |
| 514 FlowGraphCompiler graph_compiler(&assembler, | 521 FlowGraphCompiler graph_compiler(&assembler, flow_graph, optimized); |
| 515 *flow_graph, | |
| 516 optimized); | |
| 517 { | 522 { |
| 518 TimerScope timer(FLAG_compiler_stats, | 523 TimerScope timer(FLAG_compiler_stats, |
| 519 &CompilerStats::graphcompiler_timer, | 524 &CompilerStats::graphcompiler_timer, |
| 520 isolate); | 525 isolate); |
| 521 graph_compiler.CompileGraph(); | 526 graph_compiler.CompileGraph(); |
| 522 } | 527 } |
| 523 { | 528 { |
| 524 TimerScope timer(FLAG_compiler_stats, | 529 TimerScope timer(FLAG_compiler_stats, |
| 525 &CompilerStats::codefinalizer_timer, | 530 &CompilerStats::codefinalizer_timer, |
| 526 isolate); | 531 isolate); |
| (...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 919 Object::Handle(isolate->object_store()->sticky_error()); | 924 Object::Handle(isolate->object_store()->sticky_error()); |
| 920 isolate->object_store()->clear_sticky_error(); | 925 isolate->object_store()->clear_sticky_error(); |
| 921 isolate->set_long_jump_base(base); | 926 isolate->set_long_jump_base(base); |
| 922 return result.raw(); | 927 return result.raw(); |
| 923 } | 928 } |
| 924 UNREACHABLE(); | 929 UNREACHABLE(); |
| 925 return Object::null(); | 930 return Object::null(); |
| 926 } | 931 } |
| 927 | 932 |
| 928 } // namespace dart | 933 } // namespace dart |
| OLD | NEW |