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

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

Issue 1149713002: With --noopt run unoptimized code through optimizer, more optimizations can be done later. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: m Created 5 years, 6 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
« no previous file with comments | « runtime/vm/compiler.h ('k') | runtime/vm/constant_propagator.cc » ('j') | no next file with comments »
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 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
62 DEFINE_FLAG(bool, trace_bailout, false, "Print bailout from ssa compiler."); 62 DEFINE_FLAG(bool, trace_bailout, false, "Print bailout from ssa compiler.");
63 DEFINE_FLAG(bool, use_inlining, true, "Enable call-site inlining"); 63 DEFINE_FLAG(bool, use_inlining, true, "Enable call-site inlining");
64 DEFINE_FLAG(bool, verify_compiler, false, 64 DEFINE_FLAG(bool, verify_compiler, false,
65 "Enable compiler verification assertions"); 65 "Enable compiler verification assertions");
66 66
67 DECLARE_FLAG(bool, trace_failed_optimization_attempts); 67 DECLARE_FLAG(bool, trace_failed_optimization_attempts);
68 DECLARE_FLAG(bool, trace_inlining_intervals); 68 DECLARE_FLAG(bool, trace_inlining_intervals);
69 DECLARE_FLAG(bool, trace_irregexp); 69 DECLARE_FLAG(bool, trace_irregexp);
70 DECLARE_FLAG(bool, trace_patching); 70 DECLARE_FLAG(bool, trace_patching);
71 71
72
73 bool Compiler::always_optimize_ = false;
74 bool Compiler::guess_other_cid_ = true;
75
76
72 // TODO(zerny): Factor out unoptimizing/optimizing pipelines and remove 77 // TODO(zerny): Factor out unoptimizing/optimizing pipelines and remove
73 // separate helpers functions & `optimizing` args. 78 // separate helpers functions & `optimizing` args.
74 class CompilationPipeline : public ZoneAllocated { 79 class CompilationPipeline : public ZoneAllocated {
75 public: 80 public:
76 static CompilationPipeline* New(Zone* zone, const Function& function); 81 static CompilationPipeline* New(Zone* zone, const Function& function);
77 82
78 virtual void ParseFunction(ParsedFunction* parsed_function) = 0; 83 virtual void ParseFunction(ParsedFunction* parsed_function) = 0;
79 virtual FlowGraph* BuildFlowGraph( 84 virtual FlowGraph* BuildFlowGraph(
80 Zone* zone, 85 Zone* zone,
81 ParsedFunction* parsed_function, 86 ParsedFunction* parsed_function,
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
147 } 152 }
148 153
149 virtual void FinalizeCompilation() { 154 virtual void FinalizeCompilation() {
150 backtrack_goto_->ComputeOffsetTable(); 155 backtrack_goto_->ComputeOffsetTable();
151 } 156 }
152 157
153 private: 158 private:
154 IndirectGotoInstr* backtrack_goto_; 159 IndirectGotoInstr* backtrack_goto_;
155 }; 160 };
156 161
162
157 CompilationPipeline* CompilationPipeline::New(Zone* zone, 163 CompilationPipeline* CompilationPipeline::New(Zone* zone,
158 const Function& function) { 164 const Function& function) {
159 if (function.IsIrregexpFunction()) { 165 if (function.IsIrregexpFunction()) {
160 return new(zone) IrregexpCompilationPipeline(); 166 return new(zone) IrregexpCompilationPipeline();
161 } else { 167 } else {
162 return new(zone) DartCompilationPipeline(); 168 return new(zone) DartCompilationPipeline();
163 } 169 }
164 } 170 }
165 171
166 172
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after
402 // constructor and unregisters itself upon destruction. 408 // constructor and unregisters itself upon destruction.
403 CHA cha(thread); 409 CHA cha(thread);
404 410
405 // TimerScope needs an isolate to be properly terminated in case of a 411 // TimerScope needs an isolate to be properly terminated in case of a
406 // LongJump. 412 // LongJump.
407 { 413 {
408 CSTAT_TIMER_SCOPE(isolate, graphbuilder_timer); 414 CSTAT_TIMER_SCOPE(isolate, graphbuilder_timer);
409 ZoneGrowableArray<const ICData*>* ic_data_array = 415 ZoneGrowableArray<const ICData*>* ic_data_array =
410 new(zone) ZoneGrowableArray<const ICData*>(); 416 new(zone) ZoneGrowableArray<const ICData*>();
411 if (optimized) { 417 if (optimized) {
412 ASSERT(function.HasCode());
413 // Extract type feedback before the graph is built, as the graph 418 // Extract type feedback before the graph is built, as the graph
414 // builder uses it to attach it to nodes. 419 // builder uses it to attach it to nodes.
415 ASSERT(function.deoptimization_counter() < 420 ASSERT(function.deoptimization_counter() <
416 FLAG_deoptimization_counter_threshold); 421 FLAG_deoptimization_counter_threshold);
417 function.RestoreICDataMap(ic_data_array); 422 function.RestoreICDataMap(ic_data_array);
418 if (FLAG_print_ic_data_map) { 423 if (FLAG_print_ic_data_map) {
419 for (intptr_t i = 0; i < ic_data_array->length(); i++) { 424 for (intptr_t i = 0; i < ic_data_array->length(); i++) {
420 if ((*ic_data_array)[i] != NULL) { 425 if ((*ic_data_array)[i] != NULL) {
421 ISL_Print("%" Pd " ", i); 426 ISL_Print("%" Pd " ", i);
422 FlowGraphPrinter::PrintICData(*(*ic_data_array)[i]); 427 FlowGraphPrinter::PrintICData(*(*ic_data_array)[i]);
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
469 // Collect all instance fields that are loaded in the graph and 474 // Collect all instance fields that are loaded in the graph and
470 // have non-generic type feedback attached to them that can 475 // have non-generic type feedback attached to them that can
471 // potentially affect optimizations. 476 // potentially affect optimizations.
472 if (optimized) { 477 if (optimized) {
473 inline_id_to_function.Add(&function); 478 inline_id_to_function.Add(&function);
474 // Top scope function has no caller (-1). 479 // Top scope function has no caller (-1).
475 caller_inline_id.Add(-1); 480 caller_inline_id.Add(-1);
476 CSTAT_TIMER_SCOPE(isolate, graphoptimizer_timer); 481 CSTAT_TIMER_SCOPE(isolate, graphoptimizer_timer);
477 482
478 FlowGraphOptimizer optimizer(flow_graph); 483 FlowGraphOptimizer optimizer(flow_graph);
484 if (Compiler::always_optimize()) {
485 optimizer.PopulateWithICData();
486 }
479 optimizer.ApplyICData(); 487 optimizer.ApplyICData();
480 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 488 DEBUG_ASSERT(flow_graph->VerifyUseLists());
481 489
482 // Optimize (a << b) & c patterns, merge operations. 490 // Optimize (a << b) & c patterns, merge operations.
483 // Run early in order to have more opportunity to optimize left shifts. 491 // Run early in order to have more opportunity to optimize left shifts.
484 optimizer.TryOptimizePatterns(); 492 optimizer.TryOptimizePatterns();
485 DEBUG_ASSERT(flow_graph->VerifyUseLists()); 493 DEBUG_ASSERT(flow_graph->VerifyUseLists());
486 494
487 FlowGraphInliner::SetInliningId(flow_graph, 0); 495 FlowGraphInliner::SetInliningId(flow_graph, 0);
488 496
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after
731 739
732 graph_compiler.FinalizePcDescriptors(code); 740 graph_compiler.FinalizePcDescriptors(code);
733 code.set_deopt_info_array(deopt_info_array); 741 code.set_deopt_info_array(deopt_info_array);
734 742
735 graph_compiler.FinalizeStackmaps(code); 743 graph_compiler.FinalizeStackmaps(code);
736 graph_compiler.FinalizeVarDescriptors(code); 744 graph_compiler.FinalizeVarDescriptors(code);
737 graph_compiler.FinalizeExceptionHandlers(code); 745 graph_compiler.FinalizeExceptionHandlers(code);
738 graph_compiler.FinalizeStaticCallTargetsTable(code); 746 graph_compiler.FinalizeStaticCallTargetsTable(code);
739 747
740 if (optimized) { 748 if (optimized) {
741 if (osr_id == Isolate::kNoDeoptId) { 749 // We may not have previous code if 'always_optimize' is set.
750 if ((osr_id == Isolate::kNoDeoptId) && function.HasCode()) {
742 CodePatcher::PatchEntry(Code::Handle(function.CurrentCode())); 751 CodePatcher::PatchEntry(Code::Handle(function.CurrentCode()));
743 if (FLAG_trace_compiler || FLAG_trace_patching) { 752 if (FLAG_trace_compiler || FLAG_trace_patching) {
744 if (FLAG_trace_compiler) { 753 if (FLAG_trace_compiler) {
745 ISL_Print(" "); 754 ISL_Print(" ");
746 } 755 }
747 ISL_Print("Patch unoptimized '%s' entry point %#" Px "\n", 756 ISL_Print("Patch unoptimized '%s' entry point %#" Px "\n",
748 function.ToFullyQualifiedCString(), 757 function.ToFullyQualifiedCString(),
749 Code::Handle(function.unoptimized_code()).EntryPoint()); 758 Code::Handle(function.unoptimized_code()).EntryPoint());
750 } 759 }
751 } 760 }
752 function.AttachCode(code); 761 function.AttachCode(code);
753 762
754 // Register code with the classes it depends on because of CHA. 763 // Register code with the classes it depends on because of CHA.
755 for (intptr_t i = 0; 764 for (intptr_t i = 0;
756 i < thread->cha()->leaf_classes().length(); 765 i < thread->cha()->leaf_classes().length();
757 ++i) { 766 ++i) {
758 thread->cha()->leaf_classes()[i]->RegisterCHACode(code); 767 thread->cha()->leaf_classes()[i]->RegisterCHACode(code);
759 } 768 }
760 769
761 for (intptr_t i = 0; 770 for (intptr_t i = 0;
762 i < flow_graph->guarded_fields()->length(); 771 i < flow_graph->guarded_fields()->length();
763 i++) { 772 i++) {
764 const Field* field = (*flow_graph->guarded_fields())[i]; 773 const Field* field = (*flow_graph->guarded_fields())[i];
765 field->RegisterDependentCode(code); 774 field->RegisterDependentCode(code);
766 } 775 }
767 } else { // not optimized. 776 } else { // not optimized.
768 if (function.ic_data_array() == Array::null()) { 777 if (!Compiler::always_optimize() &&
778 (function.ic_data_array() == Array::null())) {
769 function.SaveICDataMap(graph_compiler.deopt_id_to_ic_data()); 779 function.SaveICDataMap(graph_compiler.deopt_id_to_ic_data());
770 } 780 }
771 function.set_unoptimized_code(code); 781 function.set_unoptimized_code(code);
772 function.AttachCode(code); 782 function.AttachCode(code);
773 ASSERT(CodePatcher::CodeIsPatchable(code)); 783 ASSERT(CodePatcher::CodeIsPatchable(code));
774 } 784 }
775 if (parsed_function->HasDeferredPrefixes()) { 785 if (parsed_function->HasDeferredPrefixes()) {
776 ZoneGrowableArray<const LibraryPrefix*>* prefixes = 786 ZoneGrowableArray<const LibraryPrefix*>* prefixes =
777 parsed_function->deferred_prefixes(); 787 parsed_function->deferred_prefixes();
778 for (intptr_t i = 0; i < prefixes->length(); i++) { 788 for (intptr_t i = 0; i < prefixes->length(); i++) {
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
966 Thread* const thread = Thread::Current(); 976 Thread* const thread = Thread::Current();
967 Isolate* const isolate = thread->isolate(); 977 Isolate* const isolate = thread->isolate();
968 StackZone stack_zone(isolate); 978 StackZone stack_zone(isolate);
969 Zone* const zone = stack_zone.GetZone(); 979 Zone* const zone = stack_zone.GetZone();
970 TIMERSCOPE(isolate, time_compilation); 980 TIMERSCOPE(isolate, time_compilation);
971 Timer per_compile_timer(FLAG_trace_compiler, "Compilation time"); 981 Timer per_compile_timer(FLAG_trace_compiler, "Compilation time");
972 per_compile_timer.Start(); 982 per_compile_timer.Start();
973 983
974 // Restore unoptimized code if needed. 984 // Restore unoptimized code if needed.
975 if (optimized) { 985 if (optimized) {
976 const Error& error = Error::Handle( 986 if (!Compiler::always_optimize()) {
977 zone, Compiler::EnsureUnoptimizedCode(Thread::Current(), function)); 987 const Error& error = Error::Handle(
978 if (!error.IsNull()) { 988 zone, Compiler::EnsureUnoptimizedCode(Thread::Current(), function));
979 return error.raw(); 989 if (!error.IsNull()) {
990 return error.raw();
991 }
980 } 992 }
981 } 993 }
982 994
983 ParsedFunction* parsed_function = new(zone) ParsedFunction( 995 ParsedFunction* parsed_function = new(zone) ParsedFunction(
984 thread, Function::ZoneHandle(zone, function.raw())); 996 thread, Function::ZoneHandle(zone, function.raw()));
985 if (FLAG_trace_compiler) { 997 if (FLAG_trace_compiler) {
986 ISL_Print("Compiling %s%sfunction: '%s' @ token %" Pd ", size %" Pd "\n", 998 ISL_Print("Compiling %s%sfunction: '%s' @ token %" Pd ", size %" Pd "\n",
987 (osr_id == Isolate::kNoDeoptId ? "" : "osr "), 999 (osr_id == Isolate::kNoDeoptId ? "" : "osr "),
988 (optimized ? "optimized " : ""), 1000 (optimized ? "optimized " : ""),
989 function.ToFullyQualifiedCString(), 1001 function.ToFullyQualifiedCString(),
990 function.token_pos(), 1002 function.token_pos(),
991 (function.end_token_pos() - function.token_pos())); 1003 (function.end_token_pos() - function.token_pos()));
992 } 1004 }
993 { 1005 {
994 HANDLESCOPE(isolate); 1006 HANDLESCOPE(isolate);
995 pipeline->ParseFunction(parsed_function); 1007 pipeline->ParseFunction(parsed_function);
996 } 1008 }
997 1009
998 const bool success = CompileParsedFunctionHelper(pipeline, 1010 const bool success = CompileParsedFunctionHelper(pipeline,
999 parsed_function, 1011 parsed_function,
1000 optimized, 1012 optimized,
1001 osr_id); 1013 osr_id);
1002 if (!success) { 1014 if (!success) {
1003 if (optimized) { 1015 if (optimized) {
1004 // Optimizer bailed out. Disable optimizations and to never try again. 1016 ASSERT(!Compiler::always_optimize()); // Optimized is the only code.
1017 // Optimizer bailed out. Disable optimizations and never try again.
1005 if (FLAG_trace_compiler) { 1018 if (FLAG_trace_compiler) {
1006 ISL_Print("--> disabling optimizations for '%s'\n", 1019 ISL_Print("--> disabling optimizations for '%s'\n",
1007 function.ToFullyQualifiedCString()); 1020 function.ToFullyQualifiedCString());
1008 } else if (FLAG_trace_failed_optimization_attempts) { 1021 } else if (FLAG_trace_failed_optimization_attempts) {
1009 ISL_Print("Cannot optimize: %s\n", 1022 ISL_Print("Cannot optimize: %s\n",
1010 function.ToFullyQualifiedCString()); 1023 function.ToFullyQualifiedCString());
1011 } 1024 }
1012 function.SetIsOptimizable(false); 1025 function.SetIsOptimizable(false);
1013 return Error::null(); 1026 return Error::null();
1014 } 1027 }
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1051 UNREACHABLE(); 1064 UNREACHABLE();
1052 return Error::null(); 1065 return Error::null();
1053 } 1066 }
1054 1067
1055 1068
1056 RawError* Compiler::CompileFunction(Thread* thread, 1069 RawError* Compiler::CompileFunction(Thread* thread,
1057 const Function& function) { 1070 const Function& function) {
1058 VMTagScope tagScope(thread->isolate(), VMTag::kCompileUnoptimizedTagId); 1071 VMTagScope tagScope(thread->isolate(), VMTag::kCompileUnoptimizedTagId);
1059 CompilationPipeline* pipeline = 1072 CompilationPipeline* pipeline =
1060 CompilationPipeline::New(thread->zone(), function); 1073 CompilationPipeline::New(thread->zone(), function);
1061 return CompileFunctionHelper(pipeline, function, false, Isolate::kNoDeoptId); 1074
1075 const bool optimized =
1076 Compiler::always_optimize() && function.IsOptimizable();
1077
1078 return CompileFunctionHelper(pipeline, function, optimized,
1079 Isolate::kNoDeoptId);
1062 } 1080 }
1063 1081
1064 1082
1065 RawError* Compiler::EnsureUnoptimizedCode(Thread* thread, 1083 RawError* Compiler::EnsureUnoptimizedCode(Thread* thread,
1066 const Function& function) { 1084 const Function& function) {
1067 if (function.unoptimized_code() != Object::null()) { 1085 if (function.unoptimized_code() != Object::null()) {
1068 return Error::null(); 1086 return Error::null();
1069 } 1087 }
1070 Code& original_code = Code::ZoneHandle(thread->zone()); 1088 Code& original_code = Code::ZoneHandle(thread->zone());
1071 if (function.HasCode()) { 1089 if (function.HasCode()) {
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after
1306 const Object& result = 1324 const Object& result =
1307 PassiveObject::Handle(isolate->object_store()->sticky_error()); 1325 PassiveObject::Handle(isolate->object_store()->sticky_error());
1308 isolate->object_store()->clear_sticky_error(); 1326 isolate->object_store()->clear_sticky_error();
1309 return result.raw(); 1327 return result.raw();
1310 } 1328 }
1311 UNREACHABLE(); 1329 UNREACHABLE();
1312 return Object::null(); 1330 return Object::null();
1313 } 1331 }
1314 1332
1315 } // namespace dart 1333 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/compiler.h ('k') | runtime/vm/constant_propagator.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698