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

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

Issue 22839003: Polymorphic inlining for some recognized methods in the optimizing compiler. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 4 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
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/compiler.h" 7 #include "vm/compiler.h"
8 #include "vm/flags.h" 8 #include "vm/flags.h"
9 #include "vm/flow_graph.h" 9 #include "vm/flow_graph.h"
10 #include "vm/flow_graph_builder.h" 10 #include "vm/flow_graph_builder.h"
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
158 void Collect(const FlowGraph& graph) { 158 void Collect(const FlowGraph& graph) {
159 call_site_count_ = 0; 159 call_site_count_ = 0;
160 instruction_count_ = 0; 160 instruction_count_ = 0;
161 for (BlockIterator block_it = graph.postorder_iterator(); 161 for (BlockIterator block_it = graph.postorder_iterator();
162 !block_it.Done(); 162 !block_it.Done();
163 block_it.Advance()) { 163 block_it.Advance()) {
164 for (ForwardInstructionIterator it(block_it.Current()); 164 for (ForwardInstructionIterator it(block_it.Current());
165 !it.Done(); 165 !it.Done();
166 it.Advance()) { 166 it.Advance()) {
167 ++instruction_count_; 167 ++instruction_count_;
168 if (it.Current()->IsStaticCall() || 168 Instruction* current = it.Current();
169 it.Current()->IsClosureCall() || 169 if (current->IsStaticCall() ||
170 it.Current()->IsPolymorphicInstanceCall()) { 170 current->IsClosureCall() ||
171 (current->IsPolymorphicInstanceCall() &&
172 !current->AsPolymorphicInstanceCall()->HasRecognizedTarget())) {
171 ++call_site_count_; 173 ++call_site_count_;
172 } 174 }
173 } 175 }
174 } 176 }
175 } 177 }
176 178
177 intptr_t call_site_count() const { return call_site_count_; } 179 intptr_t call_site_count() const { return call_site_count_; }
178 intptr_t instruction_count() const { return instruction_count_; } 180 intptr_t instruction_count() const { return instruction_count_; }
179 181
180 private: 182 private:
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
279 block_it.Advance()) { 281 block_it.Advance()) {
280 for (ForwardInstructionIterator it(block_it.Current()); 282 for (ForwardInstructionIterator it(block_it.Current());
281 !it.Done(); 283 !it.Done();
282 it.Advance()) { 284 it.Advance()) {
283 it.Current()->Accept(this); 285 it.Current()->Accept(this);
284 } 286 }
285 } 287 }
286 ComputeCallSiteRatio(static_call_start_ix, instance_call_start_ix); 288 ComputeCallSiteRatio(static_call_start_ix, instance_call_start_ix);
287 } 289 }
288 290
291 void FindRecognizedCallSites(FlowGraph* graph) {
Kevin Millikin (Google) 2013/08/13 11:47:40 Instead of a separate function which is a copy of
Florian Schneider 2013/08/14 12:30:24 Done.
292 ASSERT(graph != NULL);
293
294 const intptr_t instance_call_start_ix = instance_calls_.length();
295 const intptr_t static_call_start_ix = static_calls_.length();
296 for (BlockIterator block_it = graph->postorder_iterator();
297 !block_it.Done();
298 block_it.Advance()) {
299 for (ForwardInstructionIterator it(block_it.Current());
300 !it.Done();
301 it.Advance()) {
302 PolymorphicInstanceCallInstr* call =
303 it.Current()->AsPolymorphicInstanceCall();
304 if (call != NULL && call->HasRecognizedTarget()) {
srdjan 2013/08/12 21:49:47 Add ()
Florian Schneider 2013/08/14 12:30:24 Done.
305 instance_calls_.Add(InstanceCallInfo(call));
306 }
307 }
308 }
309 ComputeCallSiteRatio(static_call_start_ix, instance_call_start_ix);
310 }
311
289 void VisitClosureCall(ClosureCallInstr* call) { 312 void VisitClosureCall(ClosureCallInstr* call) {
290 closure_calls_.Add(call); 313 closure_calls_.Add(call);
291 } 314 }
292 315
293 void VisitPolymorphicInstanceCall(PolymorphicInstanceCallInstr* call) { 316 void VisitPolymorphicInstanceCall(PolymorphicInstanceCallInstr* call) {
294 instance_calls_.Add(InstanceCallInfo(call)); 317 instance_calls_.Add(InstanceCallInfo(call));
295 } 318 }
296 319
297 void VisitStaticCall(StaticCallInstr* call) { 320 void VisitStaticCall(StaticCallInstr* call) {
298 if (!call->function().IsInlineable()) return; 321 if (!call->function().IsInlineable()) return;
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
387 if ((const_arg_count >= FLAG_inlining_constant_arguments_count) && 410 if ((const_arg_count >= FLAG_inlining_constant_arguments_count) &&
388 (instr_count <= FLAG_inlining_constant_arguments_size_threshold)) { 411 (instr_count <= FLAG_inlining_constant_arguments_size_threshold)) {
389 return true; 412 return true;
390 } 413 }
391 if (MethodRecognizer::AlwaysInline(callee)) { 414 if (MethodRecognizer::AlwaysInline(callee)) {
392 return true; 415 return true;
393 } 416 }
394 return false; 417 return false;
395 } 418 }
396 419
397 // TODO(srdjan): Handle large 'skip_static_call_deopt_ids'. Currently
398 // max. size observed is 11 (dart2js).
Florian Schneider 2013/08/12 15:48:14 I think this TODO is obsolete.
399 void InlineCalls() { 420 void InlineCalls() {
400 // If inlining depth is less then one abort. 421 // If inlining depth is less then one abort.
401 if (FLAG_inlining_depth_threshold < 1) return; 422 if (FLAG_inlining_depth_threshold < 1) return;
402 if (caller_graph_->parsed_function().function().deoptimization_counter() >= 423 if (caller_graph_->parsed_function().function().deoptimization_counter() >=
403 FLAG_deoptimization_counter_inlining_threshold) { 424 FLAG_deoptimization_counter_inlining_threshold) {
404 return; 425 return;
405 } 426 }
406 // Create two call site collections to swap between. 427 // Create two call site collections to swap between.
407 CallSites sites1(caller_graph_); 428 CallSites sites1(caller_graph_);
408 CallSites sites2(caller_graph_); 429 CallSites sites2(caller_graph_);
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
628 "const args: %"Pd"\n", 649 "const args: %"Pd"\n",
629 size, 650 size,
630 call_site_count, 651 call_site_count,
631 constants_count)); 652 constants_count));
632 return false; 653 return false;
633 } 654 }
634 655
635 // If depth is less or equal to threshold recursively add call sites. 656 // If depth is less or equal to threshold recursively add call sites.
636 if (inlining_depth_ < FLAG_inlining_depth_threshold) { 657 if (inlining_depth_ < FLAG_inlining_depth_threshold) {
637 collected_call_sites_->FindCallSites(callee_graph); 658 collected_call_sites_->FindCallSites(callee_graph);
659 } else if (inlining_depth_ == FLAG_inlining_depth_threshold) {
Kevin Millikin (Google) 2013/08/13 11:47:40 In any case, even if you keep the separate functio
Florian Schneider 2013/08/14 12:30:24 Done. I use only one function. Also change CallSit
660 collected_call_sites_->FindRecognizedCallSites(callee_graph);
638 } 661 }
639 662
640 // Add the function to the cache. 663 // Add the function to the cache.
641 if (!in_cache) function_cache_.Add(parsed_function); 664 if (!in_cache) function_cache_.Add(parsed_function);
642 665
643 // Build succeeded so we restore the bailout jump. 666 // Build succeeded so we restore the bailout jump.
644 inlined_ = true; 667 inlined_ = true;
645 inlined_size_ += size; 668 inlined_size_ += size;
646 isolate->set_long_jump_base(base); 669 isolate->set_long_jump_base(base);
647 isolate->set_deopt_id(prev_deopt_id); 670 isolate->set_deopt_id(prev_deopt_id);
(...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after
1057 if (target.raw() == non_inlined_variants_[i].target->raw()) { 1080 if (target.raw() == non_inlined_variants_[i].target->raw()) {
1058 return true; 1081 return true;
1059 } 1082 }
1060 } 1083 }
1061 1084
1062 return false; 1085 return false;
1063 } 1086 }
1064 1087
1065 1088
1066 bool PolymorphicInliner::TryInlining(const Function& target) { 1089 bool PolymorphicInliner::TryInlining(const Function& target) {
1067 if (!target.is_optimizable()) {
Kevin Millikin (Google) 2013/08/13 11:47:40 Why remove this check?
Florian Schneider 2013/08/14 12:30:24 It's not strictly necessary, but I'll put it back
1068 return false;
1069 }
1070 GrowableArray<Value*> arguments(call_->ArgumentCount()); 1090 GrowableArray<Value*> arguments(call_->ArgumentCount());
1071 for (int i = 0; i < call_->ArgumentCount(); ++i) { 1091 for (int i = 0; i < call_->ArgumentCount(); ++i) {
1072 arguments.Add(call_->PushArgumentAt(i)->value()); 1092 arguments.Add(call_->PushArgumentAt(i)->value());
1073 } 1093 }
1074 InlinedCallData call_data(call_, &arguments); 1094 InlinedCallData call_data(call_, &arguments);
1075 if (!owner_->TryInlining(target, 1095 if (!owner_->TryInlining(target,
1076 call_->instance_call()->argument_names(), 1096 call_->instance_call()->argument_names(),
1077 &call_data)) { 1097 &call_data)) {
1078 return false; 1098 return false;
1079 } 1099 }
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after
1424 OS::Print("After Inlining of %s\n", flow_graph_-> 1444 OS::Print("After Inlining of %s\n", flow_graph_->
1425 parsed_function().function().ToFullyQualifiedCString()); 1445 parsed_function().function().ToFullyQualifiedCString());
1426 FlowGraphPrinter printer(*flow_graph_); 1446 FlowGraphPrinter printer(*flow_graph_);
1427 printer.PrintBlocks(); 1447 printer.PrintBlocks();
1428 } 1448 }
1429 } 1449 }
1430 } 1450 }
1431 } 1451 }
1432 1452
1433 } // namespace dart 1453 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698