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

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

Issue 11262008: Remove push arguments and replace constants in FlowGraph::InlineCall. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Srdjan's DBCs from previous CL Created 8 years, 1 month 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
« runtime/vm/flow_graph.cc ('K') | « runtime/vm/flow_graph.cc ('k') | no next file » | 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/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 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
192 192
193 DISALLOW_COPY_AND_ASSIGN(CallSites); 193 DISALLOW_COPY_AND_ASSIGN(CallSites);
194 }; 194 };
195 195
196 196
197 class CallSiteInliner : public ValueObject { 197 class CallSiteInliner : public ValueObject {
198 public: 198 public:
199 explicit CallSiteInliner(FlowGraph* flow_graph) 199 explicit CallSiteInliner(FlowGraph* flow_graph)
200 : caller_graph_(flow_graph), 200 : caller_graph_(flow_graph),
201 next_ssa_temp_index_(flow_graph->max_virtual_register_number()), 201 next_ssa_temp_index_(flow_graph->max_virtual_register_number()),
202 inlined_(false),
203 initial_size_(flow_graph->InstructionCount()), 202 initial_size_(flow_graph->InstructionCount()),
204 inlined_size_(0), 203 inlined_size_(0),
205 inlining_depth_(1), 204 inlining_depth_(1),
206 collected_call_sites_(NULL), 205 collected_call_sites_(NULL),
207 inlining_call_sites_(NULL), 206 inlining_call_sites_(NULL),
208 function_cache_() { } 207 function_cache_() { }
209 208
210 void InlineCalls() { 209 void InlineCalls() {
211 // If inlining depth is less then one abort. 210 // If inlining depth is less then one abort.
212 if (FLAG_inlining_depth_threshold < 1) return; 211 if (FLAG_inlining_depth_threshold < 1) return;
(...skipping 16 matching lines...) Expand all
229 InlineStaticCalls(); 228 InlineStaticCalls();
230 InlineClosureCalls(); 229 InlineClosureCalls();
231 InlineInstanceCalls(); 230 InlineInstanceCalls();
232 // Increment the inlining depth. Checked before recursive inlining. 231 // Increment the inlining depth. Checked before recursive inlining.
233 ++inlining_depth_; 232 ++inlining_depth_;
234 } 233 }
235 collected_call_sites_ = NULL; 234 collected_call_sites_ = NULL;
236 inlining_call_sites_ = NULL; 235 inlining_call_sites_ = NULL;
237 } 236 }
238 237
239 bool inlined() const { return inlined_; } 238 intptr_t inlined_instructions() const { return inlined_size_; }
240
241 double GrowthFactor() const {
242 return static_cast<double>(inlined_size_) /
243 static_cast<double>(initial_size_);
244 }
245 239
246 private: 240 private:
247 bool TryInlining(const Function& function, 241 bool TryInlining(const Function& function,
248 const Array& argument_names, 242 const Array& argument_names,
249 GrowableArray<Value*>* arguments, 243 GrowableArray<Value*>* arguments,
250 Definition* call) { 244 Definition* call) {
251 TRACE_INLINING(OS::Print(" => %s (deopt count %d)\n", 245 TRACE_INLINING(OS::Print(" => %s (deopt count %d)\n",
252 function.ToCString(), 246 function.ToCString(),
253 function.deoptimization_counter())); 247 function.deoptimization_counter()));
254 248
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
387 381
388 if (FLAG_trace_inlining && FLAG_print_flow_graph) { 382 if (FLAG_trace_inlining && FLAG_print_flow_graph) {
389 OS::Print("Callee graph for inlining %s\n", 383 OS::Print("Callee graph for inlining %s\n",
390 function.ToFullyQualifiedCString()); 384 function.ToFullyQualifiedCString());
391 FlowGraphPrinter printer(*callee_graph); 385 FlowGraphPrinter printer(*callee_graph);
392 printer.PrintBlocks(); 386 printer.PrintBlocks();
393 } 387 }
394 388
395 // If result is more than size threshold then abort. 389 // If result is more than size threshold then abort.
396 // TODO(zerny): Do this after CP and dead code elimination. 390 // TODO(zerny): Do this after CP and dead code elimination.
397 intptr_t size = callee_graph->InstructionCount(); 391 const intptr_t size = callee_graph->InstructionCount();
398 if (size > FLAG_inlining_size_threshold) { 392 if (size > FLAG_inlining_size_threshold) {
399 function.set_is_inlinable(false); 393 function.set_is_inlinable(false);
400 isolate->set_long_jump_base(base); 394 isolate->set_long_jump_base(base);
401 isolate->set_deopt_id(prev_deopt_id); 395 isolate->set_deopt_id(prev_deopt_id);
402 isolate->set_ic_data_array(prev_ic_data.raw()); 396 isolate->set_ic_data_array(prev_ic_data.raw());
403 TRACE_INLINING(OS::Print(" Bailout: graph size %"Pd"\n", size)); 397 TRACE_INLINING(OS::Print(" Bailout: graph size %"Pd"\n", size));
404 return false; 398 return false;
405 } 399 }
406 400
407 // If depth is less or equal to threshold recursively add call sites. 401 // If depth is less or equal to threshold recursively add call sites.
408 if (inlining_depth_ < FLAG_inlining_depth_threshold) { 402 if (inlining_depth_ < FLAG_inlining_depth_threshold) {
409 collected_call_sites_->FindCallSites(callee_graph); 403 collected_call_sites_->FindCallSites(callee_graph);
410 } 404 }
411 405
412 { 406 {
413 TimerScope timer(FLAG_compiler_stats, 407 TimerScope timer(FLAG_compiler_stats,
414 &CompilerStats::graphinliner_subst_timer, 408 &CompilerStats::graphinliner_subst_timer,
415 isolate); 409 isolate);
416 410
417 // Plug result in the caller graph. 411 // Plug result in the caller graph.
418 caller_graph_->InlineCall(call, callee_graph); 412 caller_graph_->InlineCall(call, callee_graph);
419 next_ssa_temp_index_ = caller_graph_->max_virtual_register_number(); 413 next_ssa_temp_index_ = caller_graph_->max_virtual_register_number();
420 414
421 // Remove push arguments of the call.
422 for (intptr_t i = 0; i < call->ArgumentCount(); ++i) {
423 PushArgumentInstr* push = call->ArgumentAt(i);
424 push->ReplaceUsesWith(push->value()->definition());
425 push->RemoveFromGraph();
426 }
427
428 // Replace each stub with the actual argument or the caller's constant. 415 // Replace each stub with the actual argument or the caller's constant.
429 // Nulls denote optional parameters for which no actual was given. 416 // Nulls denote optional parameters for which no actual was given.
430 for (intptr_t i = 0; i < arguments->length(); ++i) { 417 for (intptr_t i = 0; i < arguments->length(); ++i) {
431 Definition* stub = param_stubs[i]; 418 Definition* stub = param_stubs[i];
432 Value* actual = (*arguments)[i]; 419 Value* actual = (*arguments)[i];
433 if (actual != NULL) stub->ReplaceUsesWith(actual->definition()); 420 if (actual != NULL) stub->ReplaceUsesWith(actual->definition());
434 } 421 }
435
436 // Replace remaining constants with uses by constants in the caller's
437 // initial definitions.
438 GrowableArray<Definition*>* defns =
439 callee_graph->graph_entry()->initial_definitions();
440 for (intptr_t i = 0; i < defns->length(); ++i) {
441 ConstantInstr* constant = (*defns)[i]->AsConstant();
442 if (constant == NULL ||
443 ((constant->input_use_list() == NULL) &&
444 (constant->env_use_list() == NULL))) {
445 continue;
446 }
447 constant->ReplaceUsesWith(
448 caller_graph_->AddConstantToInitialDefinitions(constant->value()));
449 }
450 } 422 }
451 423
452 TRACE_INLINING(OS::Print(" Success\n")); 424 TRACE_INLINING(OS::Print(
425 " Success (inlined %"Pd" instructions)\n", size));
453 426
454 // Add the function to the cache. 427 // Add the function to the cache.
455 if (!in_cache) function_cache_.Add(parsed_function); 428 if (!in_cache) function_cache_.Add(parsed_function);
456 429
457 // Check that inlining maintains use lists. 430 // Check that inlining maintains use lists.
458 DEBUG_ASSERT(!FLAG_verify_compiler || caller_graph_->ValidateUseLists()); 431 DEBUG_ASSERT(!FLAG_verify_compiler || caller_graph_->ValidateUseLists());
459 432
460 // Build succeeded so we restore the bailout jump. 433 // Build succeeded so we restore the bailout jump.
461 inlined_ = true;
462 inlined_size_ += size; 434 inlined_size_ += size;
463 isolate->set_long_jump_base(base); 435 isolate->set_long_jump_base(base);
464 isolate->set_deopt_id(prev_deopt_id); 436 isolate->set_deopt_id(prev_deopt_id);
465 isolate->set_ic_data_array(prev_ic_data.raw()); 437 isolate->set_ic_data_array(prev_ic_data.raw());
466 return true; 438 return true;
467 } else { 439 } else {
468 Error& error = Error::Handle(); 440 Error& error = Error::Handle();
469 error = isolate->object_store()->sticky_error(); 441 error = isolate->object_store()->sticky_error();
470 isolate->object_store()->clear_sticky_error(); 442 isolate->object_store()->clear_sticky_error();
471 isolate->set_long_jump_base(base); 443 isolate->set_long_jump_base(base);
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
647 } else { 619 } else {
648 param_stubs->Add( 620 param_stubs->Add(
649 GetDefaultValue(i - fixed_param_count, parsed_function)); 621 GetDefaultValue(i - fixed_param_count, parsed_function));
650 } 622 }
651 } 623 }
652 } 624 }
653 625
654 626
655 FlowGraph* caller_graph_; 627 FlowGraph* caller_graph_;
656 intptr_t next_ssa_temp_index_; 628 intptr_t next_ssa_temp_index_;
657 bool inlined_;
658 intptr_t initial_size_; 629 intptr_t initial_size_;
659 intptr_t inlined_size_; 630 intptr_t inlined_size_;
660 intptr_t inlining_depth_; 631 intptr_t inlining_depth_;
661 CallSites* collected_call_sites_; 632 CallSites* collected_call_sites_;
662 CallSites* inlining_call_sites_; 633 CallSites* inlining_call_sites_;
663 GrowableArray<ParsedFunction*> function_cache_; 634 GrowableArray<ParsedFunction*> function_cache_;
664 635
665 DISALLOW_COPY_AND_ASSIGN(CallSiteInliner); 636 DISALLOW_COPY_AND_ASSIGN(CallSiteInliner);
666 }; 637 };
667 638
(...skipping 13 matching lines...) Expand all
681 if (FLAG_trace_inlining && FLAG_print_flow_graph) { 652 if (FLAG_trace_inlining && FLAG_print_flow_graph) {
682 OS::Print("Before Inlining of %s\n", flow_graph_-> 653 OS::Print("Before Inlining of %s\n", flow_graph_->
683 parsed_function().function().ToFullyQualifiedCString()); 654 parsed_function().function().ToFullyQualifiedCString());
684 FlowGraphPrinter printer(*flow_graph_); 655 FlowGraphPrinter printer(*flow_graph_);
685 printer.PrintBlocks(); 656 printer.PrintBlocks();
686 } 657 }
687 658
688 CallSiteInliner inliner(flow_graph_); 659 CallSiteInliner inliner(flow_graph_);
689 inliner.InlineCalls(); 660 inliner.InlineCalls();
690 661
691 if (inliner.inlined()) { 662 if (inliner.inlined_instructions() > 0) {
692 flow_graph_->RepairGraphAfterInlining(); 663 flow_graph_->RepairGraphAfterInlining();
693 if (FLAG_trace_inlining) { 664 if (FLAG_trace_inlining) {
694 OS::Print("Inlining growth factor: %f\n", inliner.GrowthFactor()); 665 OS::Print("Inlined %"Pd" instructions\n", inliner.inlined_instructions());
695 if (FLAG_print_flow_graph) { 666 if (FLAG_print_flow_graph) {
696 OS::Print("After Inlining of %s\n", flow_graph_-> 667 OS::Print("After Inlining of %s\n", flow_graph_->
697 parsed_function().function().ToFullyQualifiedCString()); 668 parsed_function().function().ToFullyQualifiedCString());
698 FlowGraphPrinter printer(*flow_graph_); 669 FlowGraphPrinter printer(*flow_graph_);
699 printer.PrintBlocks(); 670 printer.PrintBlocks();
700 } 671 }
701 } 672 }
702 } 673 }
703 } 674 }
704 675
705 } // namespace dart 676 } // namespace dart
OLDNEW
« runtime/vm/flow_graph.cc ('K') | « runtime/vm/flow_graph.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698