Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(878)

Side by Side Diff: runtime/vm/compiler.cc

Issue 904763003: Redesign inlining interval computation. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | runtime/vm/disassembler.cc » ('j') | runtime/vm/flow_graph_inliner.cc » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/disassembler.cc » ('j') | runtime/vm/flow_graph_inliner.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698