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

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: Review update. 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
« no previous file with comments | « 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 228 matching lines...) Expand 10 before | Expand all | Expand 10 after
239 239
240 DISALLOW_COPY_AND_ASSIGN(CallSites); 240 DISALLOW_COPY_AND_ASSIGN(CallSites);
241 }; 241 };
242 242
243 243
244 class CallSiteInliner : public ValueObject { 244 class CallSiteInliner : public ValueObject {
245 public: 245 public:
246 explicit CallSiteInliner(FlowGraph* flow_graph) 246 explicit CallSiteInliner(FlowGraph* flow_graph)
247 : caller_graph_(flow_graph), 247 : caller_graph_(flow_graph),
248 next_ssa_temp_index_(flow_graph->max_virtual_register_number()), 248 next_ssa_temp_index_(flow_graph->max_virtual_register_number()),
249 inlined_(false),
250 initial_size_(flow_graph->InstructionCount()), 249 initial_size_(flow_graph->InstructionCount()),
251 inlined_size_(0), 250 inlined_size_(0),
252 inlining_depth_(1), 251 inlining_depth_(1),
253 collected_call_sites_(NULL), 252 collected_call_sites_(NULL),
254 inlining_call_sites_(NULL), 253 inlining_call_sites_(NULL),
255 function_cache_() { } 254 function_cache_() { }
256 255
257 // Inlining heuristics based on Cooper et al. 2008. 256 // Inlining heuristics based on Cooper et al. 2008.
258 bool ShouldWeInline(intptr_t loop_depth, 257 bool ShouldWeInline(intptr_t loop_depth,
259 intptr_t instr_count, 258 intptr_t instr_count,
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
298 InlineStaticCalls(); 297 InlineStaticCalls();
299 InlineClosureCalls(); 298 InlineClosureCalls();
300 InlineInstanceCalls(); 299 InlineInstanceCalls();
301 // Increment the inlining depth. Checked before recursive inlining. 300 // Increment the inlining depth. Checked before recursive inlining.
302 ++inlining_depth_; 301 ++inlining_depth_;
303 } 302 }
304 collected_call_sites_ = NULL; 303 collected_call_sites_ = NULL;
305 inlining_call_sites_ = NULL; 304 inlining_call_sites_ = NULL;
306 } 305 }
307 306
308 bool inlined() const { return inlined_; } 307 intptr_t inlined_instructions() const { return inlined_size_; }
309
310 double GrowthFactor() const {
311 return static_cast<double>(inlined_size_) /
312 static_cast<double>(initial_size_);
313 }
314 308
315 private: 309 private:
316 bool TryInlining(const Function& function, 310 bool TryInlining(const Function& function,
317 const Array& argument_names, 311 const Array& argument_names,
318 GrowableArray<Value*>* arguments, 312 GrowableArray<Value*>* arguments,
319 Definition* call) { 313 Definition* call) {
320 TRACE_INLINING(OS::Print(" => %s (deopt count %d)\n", 314 TRACE_INLINING(OS::Print(" => %s (deopt count %d)\n",
321 function.ToCString(), 315 function.ToCString(),
322 function.deoptimization_counter())); 316 function.deoptimization_counter()));
323 317
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
496 490
497 { 491 {
498 TimerScope timer(FLAG_compiler_stats, 492 TimerScope timer(FLAG_compiler_stats,
499 &CompilerStats::graphinliner_subst_timer, 493 &CompilerStats::graphinliner_subst_timer,
500 isolate); 494 isolate);
501 495
502 // Plug result in the caller graph. 496 // Plug result in the caller graph.
503 caller_graph_->InlineCall(call, callee_graph); 497 caller_graph_->InlineCall(call, callee_graph);
504 next_ssa_temp_index_ = caller_graph_->max_virtual_register_number(); 498 next_ssa_temp_index_ = caller_graph_->max_virtual_register_number();
505 499
506 // Remove push arguments of the call.
507 for (intptr_t i = 0; i < call->ArgumentCount(); ++i) {
508 PushArgumentInstr* push = call->ArgumentAt(i);
509 push->ReplaceUsesWith(push->value()->definition());
510 push->RemoveFromGraph();
511 }
512
513 // Replace each stub with the actual argument or the caller's constant. 500 // Replace each stub with the actual argument or the caller's constant.
514 // Nulls denote optional parameters for which no actual was given. 501 // Nulls denote optional parameters for which no actual was given.
515 for (intptr_t i = 0; i < arguments->length(); ++i) { 502 for (intptr_t i = 0; i < arguments->length(); ++i) {
516 Definition* stub = param_stubs[i]; 503 Definition* stub = param_stubs[i];
517 Value* actual = (*arguments)[i]; 504 Value* actual = (*arguments)[i];
518 if (actual != NULL) stub->ReplaceUsesWith(actual->definition()); 505 if (actual != NULL) stub->ReplaceUsesWith(actual->definition());
519 } 506 }
520
521 // Replace remaining constants with uses by constants in the caller's
522 // initial definitions.
523 GrowableArray<Definition*>* defns =
524 callee_graph->graph_entry()->initial_definitions();
525 for (intptr_t i = 0; i < defns->length(); ++i) {
526 ConstantInstr* constant = (*defns)[i]->AsConstant();
527 if (constant == NULL ||
528 ((constant->input_use_list() == NULL) &&
529 (constant->env_use_list() == NULL))) {
530 continue;
531 }
532 constant->ReplaceUsesWith(
533 caller_graph_->AddConstantToInitialDefinitions(constant->value()));
534 }
535 } 507 }
536 508
537 TRACE_INLINING(OS::Print(" Success\n")); 509 TRACE_INLINING(OS::Print(
510 " Success (inlined %"Pd" instructions)\n", size));
538 511
539 // Add the function to the cache. 512 // Add the function to the cache.
540 if (!in_cache) function_cache_.Add(parsed_function); 513 if (!in_cache) function_cache_.Add(parsed_function);
541 514
542 // Check that inlining maintains use lists. 515 // Check that inlining maintains use lists.
543 DEBUG_ASSERT(!FLAG_verify_compiler || caller_graph_->ValidateUseLists()); 516 DEBUG_ASSERT(!FLAG_verify_compiler || caller_graph_->ValidateUseLists());
544 517
545 // Build succeeded so we restore the bailout jump. 518 // Build succeeded so we restore the bailout jump.
546 inlined_ = true;
547 inlined_size_ += size; 519 inlined_size_ += size;
548 isolate->set_long_jump_base(base); 520 isolate->set_long_jump_base(base);
549 isolate->set_deopt_id(prev_deopt_id); 521 isolate->set_deopt_id(prev_deopt_id);
550 isolate->set_ic_data_array(prev_ic_data.raw()); 522 isolate->set_ic_data_array(prev_ic_data.raw());
551 return true; 523 return true;
552 } else { 524 } else {
553 Error& error = Error::Handle(); 525 Error& error = Error::Handle();
554 error = isolate->object_store()->sticky_error(); 526 error = isolate->object_store()->sticky_error();
555 isolate->object_store()->clear_sticky_error(); 527 isolate->object_store()->clear_sticky_error();
556 isolate->set_long_jump_base(base); 528 isolate->set_long_jump_base(base);
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
732 } else { 704 } else {
733 param_stubs->Add( 705 param_stubs->Add(
734 GetDefaultValue(i - fixed_param_count, parsed_function)); 706 GetDefaultValue(i - fixed_param_count, parsed_function));
735 } 707 }
736 } 708 }
737 } 709 }
738 710
739 711
740 FlowGraph* caller_graph_; 712 FlowGraph* caller_graph_;
741 intptr_t next_ssa_temp_index_; 713 intptr_t next_ssa_temp_index_;
742 bool inlined_;
743 intptr_t initial_size_; 714 intptr_t initial_size_;
744 intptr_t inlined_size_; 715 intptr_t inlined_size_;
745 intptr_t inlining_depth_; 716 intptr_t inlining_depth_;
746 CallSites* collected_call_sites_; 717 CallSites* collected_call_sites_;
747 CallSites* inlining_call_sites_; 718 CallSites* inlining_call_sites_;
748 GrowableArray<ParsedFunction*> function_cache_; 719 GrowableArray<ParsedFunction*> function_cache_;
749 720
750 DISALLOW_COPY_AND_ASSIGN(CallSiteInliner); 721 DISALLOW_COPY_AND_ASSIGN(CallSiteInliner);
751 }; 722 };
752 723
(...skipping 13 matching lines...) Expand all
766 if (FLAG_trace_inlining && FLAG_print_flow_graph) { 737 if (FLAG_trace_inlining && FLAG_print_flow_graph) {
767 OS::Print("Before Inlining of %s\n", flow_graph_-> 738 OS::Print("Before Inlining of %s\n", flow_graph_->
768 parsed_function().function().ToFullyQualifiedCString()); 739 parsed_function().function().ToFullyQualifiedCString());
769 FlowGraphPrinter printer(*flow_graph_); 740 FlowGraphPrinter printer(*flow_graph_);
770 printer.PrintBlocks(); 741 printer.PrintBlocks();
771 } 742 }
772 743
773 CallSiteInliner inliner(flow_graph_); 744 CallSiteInliner inliner(flow_graph_);
774 inliner.InlineCalls(); 745 inliner.InlineCalls();
775 746
776 if (inliner.inlined()) { 747 if (inliner.inlined_instructions() > 0) {
777 flow_graph_->RepairGraphAfterInlining(); 748 flow_graph_->RepairGraphAfterInlining();
778 if (FLAG_trace_inlining) { 749 if (FLAG_trace_inlining) {
779 OS::Print("Inlining growth factor: %f\n", inliner.GrowthFactor()); 750 OS::Print("Inlined %"Pd" instructions\n", inliner.inlined_instructions());
780 if (FLAG_print_flow_graph) { 751 if (FLAG_print_flow_graph) {
781 OS::Print("After Inlining of %s\n", flow_graph_-> 752 OS::Print("After Inlining of %s\n", flow_graph_->
782 parsed_function().function().ToFullyQualifiedCString()); 753 parsed_function().function().ToFullyQualifiedCString());
783 FlowGraphPrinter printer(*flow_graph_); 754 FlowGraphPrinter printer(*flow_graph_);
784 printer.PrintBlocks(); 755 printer.PrintBlocks();
785 } 756 }
786 } 757 }
787 } 758 }
788 } 759 }
789 760
790 } // namespace dart 761 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698