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

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

Issue 23684059: Polymorphic inlining of [] operations. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 3 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 | « runtime/vm/flow_graph_builder.cc ('k') | runtime/vm/flow_graph_optimizer.h » ('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) 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/block_scheduler.h" 7 #include "vm/block_scheduler.h"
8 #include "vm/compiler.h" 8 #include "vm/compiler.h"
9 #include "vm/flags.h" 9 #include "vm/flags.h"
10 #include "vm/flow_graph.h" 10 #include "vm/flow_graph.h"
(...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after
357 PolymorphicInliner(CallSiteInliner* owner, 357 PolymorphicInliner(CallSiteInliner* owner,
358 PolymorphicInstanceCallInstr* call); 358 PolymorphicInstanceCallInstr* call);
359 359
360 void Inline(); 360 void Inline();
361 361
362 private: 362 private:
363 bool CheckInlinedDuplicate(const Function& target); 363 bool CheckInlinedDuplicate(const Function& target);
364 bool CheckNonInlinedDuplicate(const Function& target); 364 bool CheckNonInlinedDuplicate(const Function& target);
365 365
366 bool TryInlining(const Function& target); 366 bool TryInlining(const Function& target);
367 bool TryInlineRecognizedMethod(const Function& target);
367 368
368 TargetEntryInstr* BuildDecisionGraph(); 369 TargetEntryInstr* BuildDecisionGraph();
369 370
370 CallSiteInliner* const owner_; 371 CallSiteInliner* const owner_;
371 PolymorphicInstanceCallInstr* const call_; 372 PolymorphicInstanceCallInstr* const call_;
372 const intptr_t num_variants_; 373 const intptr_t num_variants_;
373 GrowableArray<CidTarget> variants_; 374 GrowableArray<CidTarget> variants_;
374 375
375 GrowableArray<CidTarget> inlined_variants_; 376 GrowableArray<CidTarget> inlined_variants_;
376 GrowableArray<CidTarget> non_inlined_variants_; 377 GrowableArray<CidTarget> non_inlined_variants_;
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after
674 error = isolate->object_store()->sticky_error(); 675 error = isolate->object_store()->sticky_error();
675 isolate->object_store()->clear_sticky_error(); 676 isolate->object_store()->clear_sticky_error();
676 isolate->set_long_jump_base(base); 677 isolate->set_long_jump_base(base);
677 isolate->set_deopt_id(prev_deopt_id); 678 isolate->set_deopt_id(prev_deopt_id);
678 TRACE_INLINING(OS::Print(" Bailout: %s\n", error.ToErrorCString())); 679 TRACE_INLINING(OS::Print(" Bailout: %s\n", error.ToErrorCString()));
679 return false; 680 return false;
680 } 681 }
681 } 682 }
682 683
683 private: 684 private:
685 friend class PolymorphicInliner;
686
684 void InlineCall(InlinedCallData* call_data) { 687 void InlineCall(InlinedCallData* call_data) {
685 TimerScope timer(FLAG_compiler_stats, 688 TimerScope timer(FLAG_compiler_stats,
686 &CompilerStats::graphinliner_subst_timer, 689 &CompilerStats::graphinliner_subst_timer,
687 Isolate::Current()); 690 Isolate::Current());
688 691
689 // For closure calls: Store context value. 692 // For closure calls: Store context value.
690 FlowGraph* callee_graph = call_data->callee_graph; 693 FlowGraph* callee_graph = call_data->callee_graph;
691 TargetEntryInstr* callee_entry = 694 TargetEntryInstr* callee_entry =
692 callee_graph->graph_entry()->normal_entry(); 695 callee_graph->graph_entry()->normal_entry();
693 ClosureCallInstr* closure_call = call_data->call->AsClosureCall(); 696 ClosureCallInstr* closure_call = call_data->call->AsClosureCall();
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after
1076 return true; 1079 return true;
1077 } 1080 }
1078 } 1081 }
1079 1082
1080 return false; 1083 return false;
1081 } 1084 }
1082 1085
1083 1086
1084 bool PolymorphicInliner::TryInlining(const Function& target) { 1087 bool PolymorphicInliner::TryInlining(const Function& target) {
1085 if (!target.is_optimizable()) { 1088 if (!target.is_optimizable()) {
1089 if (TryInlineRecognizedMethod(target)) {
1090 owner_->inlined_ = true;
1091 return true;
1092 }
1086 return false; 1093 return false;
1087 } 1094 }
1095
1088 GrowableArray<Value*> arguments(call_->ArgumentCount()); 1096 GrowableArray<Value*> arguments(call_->ArgumentCount());
1089 for (int i = 0; i < call_->ArgumentCount(); ++i) { 1097 for (int i = 0; i < call_->ArgumentCount(); ++i) {
1090 arguments.Add(call_->PushArgumentAt(i)->value()); 1098 arguments.Add(call_->PushArgumentAt(i)->value());
1091 } 1099 }
1092 InlinedCallData call_data(call_, &arguments); 1100 InlinedCallData call_data(call_, &arguments);
1093 if (!owner_->TryInlining(target, 1101 if (!owner_->TryInlining(target,
1094 call_->instance_call()->argument_names(), 1102 call_->instance_call()->argument_names(),
1095 &call_data)) { 1103 &call_data)) {
1096 return false; 1104 return false;
1097 } 1105 }
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1137 Instruction* second) { 1145 Instruction* second) {
1138 for (intptr_t i = second->InputCount() - 1; i >= 0; --i) { 1146 for (intptr_t i = second->InputCount() - 1; i >= 0; --i) {
1139 Value* input = second->InputAt(i); 1147 Value* input = second->InputAt(i);
1140 input->definition()->AddInputUse(input); 1148 input->definition()->AddInputUse(input);
1141 } 1149 }
1142 first->LinkTo(second); 1150 first->LinkTo(second);
1143 return second; 1151 return second;
1144 } 1152 }
1145 1153
1146 1154
1155 bool PolymorphicInliner::TryInlineRecognizedMethod(const Function& target) {
1156 FlowGraphOptimizer optimizer(owner_->caller_graph(),
1157 NULL); // No guarded fields needed.
1158 TargetEntryInstr* entry;
1159 Definition* last;
1160 if (optimizer.TryInlineRecognizedMethod(target,
1161 call_,
1162 call_->ic_data(),
1163 &entry, &last)) {
1164 // Create a graph fragment.
1165 InlineExitCollector* exit_collector =
1166 new InlineExitCollector(owner_->caller_graph(), call_);
1167
1168 ReturnInstr* result =
1169 new ReturnInstr(call_->instance_call()->token_pos(),
1170 new Value(last));
1171 owner_->caller_graph()->AppendTo(
1172 last,
1173 result,
1174 call_->env(), // Return can become deoptimization target.
1175 Definition::kEffect);
1176 entry->set_last_instruction(result);
1177 exit_collector->AddExit(result);
1178 GraphEntryInstr* graph_entry =
1179 new GraphEntryInstr(NULL, // No parsed function.
1180 entry,
1181 Isolate::kNoDeoptId); // No OSR id.
1182 // Update polymorphic inliner state.
1183 inlined_entries_.Add(graph_entry);
1184 exit_collector_->Union(exit_collector);
1185 return true;
1186 }
1187 return false;
1188 }
1189
1190
1147 // Build a DAG to dispatch to the inlined function bodies. Load the class 1191 // Build a DAG to dispatch to the inlined function bodies. Load the class
1148 // id of the receiver and make explicit comparisons for each inlined body, 1192 // id of the receiver and make explicit comparisons for each inlined body,
1149 // in frequency order. If all variants are inlined, the entry to the last 1193 // in frequency order. If all variants are inlined, the entry to the last
1150 // inlined body is guarded by a CheckClassId instruction which can deopt. 1194 // inlined body is guarded by a CheckClassId instruction which can deopt.
1151 // If not all variants are inlined, we add a PolymorphicInstanceCall 1195 // If not all variants are inlined, we add a PolymorphicInstanceCall
1152 // instruction to handle the non-inlined variants. 1196 // instruction to handle the non-inlined variants.
1153 TargetEntryInstr* PolymorphicInliner::BuildDecisionGraph() { 1197 TargetEntryInstr* PolymorphicInliner::BuildDecisionGraph() {
1154 // Start with a fresh target entry. 1198 // Start with a fresh target entry.
1155 TargetEntryInstr* entry = 1199 TargetEntryInstr* entry =
1156 new TargetEntryInstr(owner_->caller_graph()->allocate_block_id(), 1200 new TargetEntryInstr(owner_->caller_graph()->allocate_block_id(),
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after
1442 OS::Print("After Inlining of %s\n", flow_graph_-> 1486 OS::Print("After Inlining of %s\n", flow_graph_->
1443 parsed_function().function().ToFullyQualifiedCString()); 1487 parsed_function().function().ToFullyQualifiedCString());
1444 FlowGraphPrinter printer(*flow_graph_); 1488 FlowGraphPrinter printer(*flow_graph_);
1445 printer.PrintBlocks(); 1489 printer.PrintBlocks();
1446 } 1490 }
1447 } 1491 }
1448 } 1492 }
1449 } 1493 }
1450 1494
1451 } // namespace dart 1495 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_builder.cc ('k') | runtime/vm/flow_graph_optimizer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698