Chromium Code Reviews| 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/block_scheduler.h" |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 26 #include "vm/flow_graph_type_propagator.h" | 26 #include "vm/flow_graph_type_propagator.h" |
| 27 #include "vm/il_printer.h" | 27 #include "vm/il_printer.h" |
| 28 #include "vm/longjump.h" | 28 #include "vm/longjump.h" |
| 29 #include "vm/object.h" | 29 #include "vm/object.h" |
| 30 #include "vm/object_store.h" | 30 #include "vm/object_store.h" |
| 31 #include "vm/os.h" | 31 #include "vm/os.h" |
| 32 #include "vm/parser.h" | 32 #include "vm/parser.h" |
| 33 #include "vm/regexp_parser.h" | 33 #include "vm/regexp_parser.h" |
| 34 #include "vm/regexp_assembler.h" | 34 #include "vm/regexp_assembler.h" |
| 35 #include "vm/scanner.h" | 35 #include "vm/scanner.h" |
| 36 #include "vm/service.h" | |
|
Cutch
2015/02/09 20:48:23
Is this needed?
srdjan
2015/02/09 23:05:03
Removed
| |
| 36 #include "vm/symbols.h" | 37 #include "vm/symbols.h" |
| 37 #include "vm/tags.h" | 38 #include "vm/tags.h" |
| 38 #include "vm/timer.h" | 39 #include "vm/timer.h" |
| 39 | 40 |
| 40 namespace dart { | 41 namespace dart { |
| 41 | 42 |
| 42 DEFINE_FLAG(bool, allocation_sinking, true, | 43 DEFINE_FLAG(bool, allocation_sinking, true, |
| 43 "Attempt to sink temporary allocations to side exits"); | 44 "Attempt to sink temporary allocations to side exits"); |
| 44 DEFINE_FLAG(bool, common_subexpression_elimination, true, | 45 DEFINE_FLAG(bool, common_subexpression_elimination, true, |
| 45 "Do common subexpression elimination."); | 46 "Do common subexpression elimination."); |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 58 "Print the deopt-id to ICData map in optimizing compiler."); | 59 "Print the deopt-id to ICData map in optimizing compiler."); |
| 59 DEFINE_FLAG(bool, range_analysis, true, "Enable range analysis"); | 60 DEFINE_FLAG(bool, range_analysis, true, "Enable range analysis"); |
| 60 DEFINE_FLAG(bool, reorder_basic_blocks, true, "Enable basic-block reordering."); | 61 DEFINE_FLAG(bool, reorder_basic_blocks, true, "Enable basic-block reordering."); |
| 61 DEFINE_FLAG(bool, trace_compiler, false, "Trace compiler operations."); | 62 DEFINE_FLAG(bool, trace_compiler, false, "Trace compiler operations."); |
| 62 DEFINE_FLAG(bool, trace_bailout, false, "Print bailout from ssa compiler."); | 63 DEFINE_FLAG(bool, trace_bailout, false, "Print bailout from ssa compiler."); |
| 63 DEFINE_FLAG(bool, use_inlining, true, "Enable call-site inlining"); | 64 DEFINE_FLAG(bool, use_inlining, true, "Enable call-site inlining"); |
| 64 DEFINE_FLAG(bool, verify_compiler, false, | 65 DEFINE_FLAG(bool, verify_compiler, false, |
| 65 "Enable compiler verification assertions"); | 66 "Enable compiler verification assertions"); |
| 66 | 67 |
| 67 DECLARE_FLAG(bool, trace_failed_optimization_attempts); | 68 DECLARE_FLAG(bool, trace_failed_optimization_attempts); |
| 69 DECLARE_FLAG(bool, trace_inlining_intervals); | |
| 70 DECLARE_FLAG(bool, trace_irregexp); | |
| 68 DECLARE_FLAG(bool, trace_patching); | 71 DECLARE_FLAG(bool, trace_patching); |
| 69 DECLARE_FLAG(bool, trace_irregexp); | |
| 70 | 72 |
| 71 // TODO(zerny): Factor out unoptimizing/optimizing pipelines and remove | 73 // TODO(zerny): Factor out unoptimizing/optimizing pipelines and remove |
| 72 // separate helpers functions & `optimizing` args. | 74 // separate helpers functions & `optimizing` args. |
| 73 class CompilationPipeline : public ZoneAllocated { | 75 class CompilationPipeline : public ZoneAllocated { |
| 74 public: | 76 public: |
| 75 static CompilationPipeline* New(Isolate* isolate, const Function& function); | 77 static CompilationPipeline* New(Isolate* isolate, const Function& function); |
| 76 | 78 |
| 77 virtual void ParseFunction(ParsedFunction* parsed_function) = 0; | 79 virtual void ParseFunction(ParsedFunction* parsed_function) = 0; |
| 78 virtual FlowGraph* BuildFlowGraph( | 80 virtual FlowGraph* BuildFlowGraph( |
| 79 ParsedFunction* parsed_function, | 81 ParsedFunction* parsed_function, |
| (...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 454 flow_graph->ComputeSSA(0, NULL); | 456 flow_graph->ComputeSSA(0, NULL); |
| 455 DEBUG_ASSERT(flow_graph->VerifyUseLists()); | 457 DEBUG_ASSERT(flow_graph->VerifyUseLists()); |
| 456 if (print_flow_graph) { | 458 if (print_flow_graph) { |
| 457 FlowGraphPrinter::PrintGraph("After SSA", flow_graph); | 459 FlowGraphPrinter::PrintGraph("After SSA", flow_graph); |
| 458 } | 460 } |
| 459 } | 461 } |
| 460 | 462 |
| 461 // Maps inline_id_to_function[inline_id] -> function. Top scope | 463 // Maps inline_id_to_function[inline_id] -> function. Top scope |
| 462 // function has inline_id 0. The map is populated by the inliner. | 464 // function has inline_id 0. The map is populated by the inliner. |
| 463 GrowableArray<const Function*> inline_id_to_function; | 465 GrowableArray<const Function*> inline_id_to_function; |
| 466 // For a given inlining-id(index) specifies the caller's inlining-id. | |
| 467 GrowableArray<intptr_t> caller_inline_id; | |
| 464 inline_id_to_function.Add(&function); | 468 inline_id_to_function.Add(&function); |
| 469 // Top scope function has no caller (-1). | |
| 470 caller_inline_id.Add(-1); | |
| 465 // Collect all instance fields that are loaded in the graph and | 471 // Collect all instance fields that are loaded in the graph and |
| 466 // have non-generic type feedback attached to them that can | 472 // have non-generic type feedback attached to them that can |
| 467 // potentially affect optimizations. | 473 // potentially affect optimizations. |
| 468 if (optimized) { | 474 if (optimized) { |
| 469 TimerScope timer(FLAG_compiler_stats, | 475 TimerScope timer(FLAG_compiler_stats, |
| 470 &CompilerStats::graphoptimizer_timer, | 476 &CompilerStats::graphoptimizer_timer, |
| 471 isolate); | 477 isolate); |
| 472 | 478 |
| 473 FlowGraphOptimizer optimizer(flow_graph); | 479 FlowGraphOptimizer optimizer(flow_graph); |
| 474 optimizer.ApplyICData(); | 480 optimizer.ApplyICData(); |
| 475 DEBUG_ASSERT(flow_graph->VerifyUseLists()); | 481 DEBUG_ASSERT(flow_graph->VerifyUseLists()); |
| 476 | 482 |
| 477 // Optimize (a << b) & c patterns, merge operations. | 483 // Optimize (a << b) & c patterns, merge operations. |
| 478 // Run early in order to have more opportunity to optimize left shifts. | 484 // Run early in order to have more opportunity to optimize left shifts. |
| 479 optimizer.TryOptimizePatterns(); | 485 optimizer.TryOptimizePatterns(); |
| 480 DEBUG_ASSERT(flow_graph->VerifyUseLists()); | 486 DEBUG_ASSERT(flow_graph->VerifyUseLists()); |
| 481 | 487 |
| 482 FlowGraphInliner::SetInliningId(*flow_graph, 0); | 488 FlowGraphInliner::SetInliningId(flow_graph, 0); |
| 483 | 489 |
| 484 // Inlining (mutates the flow graph) | 490 // Inlining (mutates the flow graph) |
| 485 if (FLAG_use_inlining) { | 491 if (FLAG_use_inlining) { |
| 486 TimerScope timer(FLAG_compiler_stats, | 492 TimerScope timer(FLAG_compiler_stats, |
| 487 &CompilerStats::graphinliner_timer); | 493 &CompilerStats::graphinliner_timer); |
| 488 // Propagate types to create more inlining opportunities. | 494 // Propagate types to create more inlining opportunities. |
| 489 FlowGraphTypePropagator::Propagate(flow_graph); | 495 FlowGraphTypePropagator::Propagate(flow_graph); |
| 490 DEBUG_ASSERT(flow_graph->VerifyUseLists()); | 496 DEBUG_ASSERT(flow_graph->VerifyUseLists()); |
| 491 | 497 |
| 492 // Use propagated class-ids to create more inlining opportunities. | 498 // Use propagated class-ids to create more inlining opportunities. |
| 493 optimizer.ApplyClassIds(); | 499 optimizer.ApplyClassIds(); |
| 494 DEBUG_ASSERT(flow_graph->VerifyUseLists()); | 500 DEBUG_ASSERT(flow_graph->VerifyUseLists()); |
| 495 | 501 |
| 496 FlowGraphInliner inliner(flow_graph, &inline_id_to_function); | 502 FlowGraphInliner inliner(flow_graph, |
| 503 &inline_id_to_function, | |
| 504 &caller_inline_id); | |
| 497 inliner.Inline(); | 505 inliner.Inline(); |
| 498 // Use lists are maintained and validated by the inliner. | 506 // Use lists are maintained and validated by the inliner. |
| 499 DEBUG_ASSERT(flow_graph->VerifyUseLists()); | 507 DEBUG_ASSERT(flow_graph->VerifyUseLists()); |
| 500 } | 508 } |
| 501 | 509 |
| 502 // Propagate types and eliminate more type tests. | 510 // Propagate types and eliminate more type tests. |
| 503 FlowGraphTypePropagator::Propagate(flow_graph); | 511 FlowGraphTypePropagator::Propagate(flow_graph); |
| 504 DEBUG_ASSERT(flow_graph->VerifyUseLists()); | 512 DEBUG_ASSERT(flow_graph->VerifyUseLists()); |
| 505 | 513 |
| 506 // Use propagated class-ids to optimize further. | 514 // Use propagated class-ids to optimize further. |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 679 // Perform register allocation on the SSA graph. | 687 // Perform register allocation on the SSA graph. |
| 680 FlowGraphAllocator allocator(*flow_graph); | 688 FlowGraphAllocator allocator(*flow_graph); |
| 681 allocator.AllocateRegisters(); | 689 allocator.AllocateRegisters(); |
| 682 if (reorder_blocks) block_scheduler.ReorderBlocks(); | 690 if (reorder_blocks) block_scheduler.ReorderBlocks(); |
| 683 | 691 |
| 684 if (print_flow_graph) { | 692 if (print_flow_graph) { |
| 685 FlowGraphPrinter::PrintGraph("After Optimizations", flow_graph); | 693 FlowGraphPrinter::PrintGraph("After Optimizations", flow_graph); |
| 686 } | 694 } |
| 687 } | 695 } |
| 688 | 696 |
| 697 ASSERT(inline_id_to_function.length() == caller_inline_id.length()); | |
| 689 Assembler assembler(use_far_branches); | 698 Assembler assembler(use_far_branches); |
| 690 FlowGraphCompiler graph_compiler(&assembler, flow_graph, | 699 FlowGraphCompiler graph_compiler(&assembler, flow_graph, |
| 691 *parsed_function, optimized, | 700 *parsed_function, optimized, |
| 692 inline_id_to_function); | 701 inline_id_to_function, |
| 702 caller_inline_id); | |
| 693 { | 703 { |
| 694 TimerScope timer(FLAG_compiler_stats, | 704 TimerScope timer(FLAG_compiler_stats, |
| 695 &CompilerStats::graphcompiler_timer, | 705 &CompilerStats::graphcompiler_timer, |
| 696 isolate); | 706 isolate); |
| 697 graph_compiler.CompileGraph(); | 707 graph_compiler.CompileGraph(); |
| 698 pipeline->FinalizeCompilation(); | 708 pipeline->FinalizeCompilation(); |
| 699 } | 709 } |
| 700 { | 710 { |
| 701 TimerScope timer(FLAG_compiler_stats, | 711 TimerScope timer(FLAG_compiler_stats, |
| 702 &CompilerStats::codefinalizer_timer, | 712 &CompilerStats::codefinalizer_timer, |
| 703 isolate); | 713 isolate); |
| 704 const Code& code = Code::Handle( | 714 const Code& code = Code::Handle( |
| 705 Code::FinalizeCode(function, &assembler, optimized)); | 715 Code::FinalizeCode(function, &assembler, optimized)); |
| 706 code.set_is_optimized(optimized); | 716 code.set_is_optimized(optimized); |
| 707 code.set_inlined_intervals(graph_compiler.inlined_code_intervals()); | 717 code.set_inlined_intervals(graph_compiler.inlined_code_intervals()); |
| 718 code.set_inlined_id_to_function( | |
| 719 Array::Handle(graph_compiler.InliningIdToFunction())); | |
| 708 graph_compiler.FinalizePcDescriptors(code); | 720 graph_compiler.FinalizePcDescriptors(code); |
| 709 graph_compiler.FinalizeDeoptInfo(code); | 721 graph_compiler.FinalizeDeoptInfo(code); |
| 710 graph_compiler.FinalizeStackmaps(code); | 722 graph_compiler.FinalizeStackmaps(code); |
| 711 graph_compiler.FinalizeVarDescriptors(code); | 723 graph_compiler.FinalizeVarDescriptors(code); |
| 712 graph_compiler.FinalizeExceptionHandlers(code); | 724 graph_compiler.FinalizeExceptionHandlers(code); |
| 713 graph_compiler.FinalizeStaticCallTargetsTable(code); | 725 graph_compiler.FinalizeStaticCallTargetsTable(code); |
| 714 | 726 |
| 715 if (optimized) { | 727 if (optimized) { |
| 716 if (osr_id == Isolate::kNoDeoptId) { | 728 if (osr_id == Isolate::kNoDeoptId) { |
| 717 CodePatcher::PatchEntry(Code::Handle(function.CurrentCode())); | 729 CodePatcher::PatchEntry(Code::Handle(function.CurrentCode())); |
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 930 code.raw()); | 942 code.raw()); |
| 931 } else { | 943 } else { |
| 932 OS::Print(" 0x%" Px ": %s, %p\n", | 944 OS::Print(" 0x%" Px ": %s, %p\n", |
| 933 start + offset.Value(), | 945 start + offset.Value(), |
| 934 function.ToFullyQualifiedCString(), | 946 function.ToFullyQualifiedCString(), |
| 935 code.raw()); | 947 code.raw()); |
| 936 } | 948 } |
| 937 } | 949 } |
| 938 OS::Print("}\n"); | 950 OS::Print("}\n"); |
| 939 } | 951 } |
| 952 if (optimized && FLAG_trace_inlining_intervals) { | |
| 953 code.DumpInlinedIntervals(); | |
| 954 } | |
| 940 } | 955 } |
| 941 | 956 |
| 942 | 957 |
| 943 static RawError* CompileFunctionHelper(CompilationPipeline* pipeline, | 958 static RawError* CompileFunctionHelper(CompilationPipeline* pipeline, |
| 944 const Function& function, | 959 const Function& function, |
| 945 bool optimized, | 960 bool optimized, |
| 946 intptr_t osr_id) { | 961 intptr_t osr_id) { |
| 947 Thread* thread = Thread::Current(); | 962 Thread* thread = Thread::Current(); |
| 948 Isolate* isolate = thread->isolate(); | 963 Isolate* isolate = thread->isolate(); |
| 949 StackZone stack_zone(isolate); | 964 StackZone stack_zone(isolate); |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1003 if (FLAG_disassemble && FlowGraphPrinter::ShouldPrint(function)) { | 1018 if (FLAG_disassemble && FlowGraphPrinter::ShouldPrint(function)) { |
| 1004 DisassembleCode(function, optimized); | 1019 DisassembleCode(function, optimized); |
| 1005 } else if (FLAG_disassemble_optimized && | 1020 } else if (FLAG_disassemble_optimized && |
| 1006 optimized && | 1021 optimized && |
| 1007 FlowGraphPrinter::ShouldPrint(function)) { | 1022 FlowGraphPrinter::ShouldPrint(function)) { |
| 1008 // TODO(fschneider): Print unoptimized code along with the optimized code. | 1023 // TODO(fschneider): Print unoptimized code along with the optimized code. |
| 1009 OS::Print("*** BEGIN CODE\n"); | 1024 OS::Print("*** BEGIN CODE\n"); |
| 1010 DisassembleCode(function, true); | 1025 DisassembleCode(function, true); |
| 1011 OS::Print("*** END CODE\n"); | 1026 OS::Print("*** END CODE\n"); |
| 1012 } | 1027 } |
| 1013 | |
| 1014 return Error::null(); | 1028 return Error::null(); |
| 1015 } else { | 1029 } else { |
| 1016 Error& error = Error::Handle(); | 1030 Error& error = Error::Handle(); |
| 1017 // We got an error during compilation. | 1031 // We got an error during compilation. |
| 1018 error = isolate->object_store()->sticky_error(); | 1032 error = isolate->object_store()->sticky_error(); |
| 1019 isolate->object_store()->clear_sticky_error(); | 1033 isolate->object_store()->clear_sticky_error(); |
| 1020 return error.raw(); | 1034 return error.raw(); |
| 1021 } | 1035 } |
| 1022 UNREACHABLE(); | 1036 UNREACHABLE(); |
| 1023 return Error::null(); | 1037 return Error::null(); |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1209 const Object& result = | 1223 const Object& result = |
| 1210 PassiveObject::Handle(isolate->object_store()->sticky_error()); | 1224 PassiveObject::Handle(isolate->object_store()->sticky_error()); |
| 1211 isolate->object_store()->clear_sticky_error(); | 1225 isolate->object_store()->clear_sticky_error(); |
| 1212 return result.raw(); | 1226 return result.raw(); |
| 1213 } | 1227 } |
| 1214 UNREACHABLE(); | 1228 UNREACHABLE(); |
| 1215 return Object::null(); | 1229 return Object::null(); |
| 1216 } | 1230 } |
| 1217 | 1231 |
| 1218 } // namespace dart | 1232 } // namespace dart |
| OLD | NEW |