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

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

Issue 10916228: Inline monomorphic calls. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Incorporated review comments. Created 8 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
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.h" 5 #include "vm/flow_graph.h"
6 6
7 #include "vm/bit_vector.h" 7 #include "vm/bit_vector.h"
8 #include "vm/flow_graph_builder.h" 8 #include "vm/flow_graph_builder.h"
9 #include "vm/intermediate_language.h" 9 #include "vm/intermediate_language.h"
10 #include "vm/longjump.h" 10 #include "vm/longjump.h"
(...skipping 738 matching lines...) Expand 10 before | Expand all | Expand 10 after
749 // Helper to link two instructions in the graph. 749 // Helper to link two instructions in the graph.
750 static void Link(Instruction* prev, Instruction* next) { 750 static void Link(Instruction* prev, Instruction* next) {
751 ASSERT(prev != next); 751 ASSERT(prev != next);
752 prev->set_next(next); 752 prev->set_next(next);
753 next->set_previous(prev); 753 next->set_previous(prev);
754 } 754 }
755 755
756 756
757 // Inline a flow graph at a call site. 757 // Inline a flow graph at a call site.
758 // 758 //
759 // Assumes the callee graph was computed with BuildGraphForInlining and 759 // Assumes the callee graph was computed by BuildGraph with an inlining context
760 // transformed to SSA with ComputeSSAForInlining, and that the use lists have 760 // and transformed to SSA with ComputeSSA with a correct virtual register
761 // been correctly computed. 761 // number, and that the use lists have been correctly computed.
762 // 762 //
763 // After inlining the caller graph will correctly have adjusted the pre/post 763 // After inlining the caller graph will correctly have adjusted the pre/post
764 // orders, the dominator tree and the use lists. 764 // orders, the dominator tree and the use lists.
765 void FlowGraph::InlineCall(StaticCallInstr* call, FlowGraph* callee_graph) { 765 void FlowGraph::InlineCall(Definition* call, FlowGraph* callee_graph) {
766 ASSERT(callee_graph->exits() != NULL); 766 ASSERT(callee_graph->exits() != NULL);
767 ASSERT(callee_graph->graph_entry()->SuccessorCount() == 1); 767 ASSERT(callee_graph->graph_entry()->SuccessorCount() == 1);
768 ASSERT(callee_graph->max_virtual_register_number() > 768 ASSERT(callee_graph->max_virtual_register_number() >
769 max_virtual_register_number()); 769 max_virtual_register_number());
770 770
771 // TODO(zerny): Implement support for callee graphs with control flow. 771 // TODO(zerny): Implement support for callee graphs with control flow.
772 ASSERT(callee_graph->preorder().length() == 2); 772 ASSERT(callee_graph->preorder().length() == 2);
773 773
774 // Adjust the SSA temp index by the callee graph's index. 774 // Adjust the SSA temp index by the callee graph's index.
775 current_ssa_temp_index_ = callee_graph->max_virtual_register_number(); 775 current_ssa_temp_index_ = callee_graph->max_virtual_register_number();
776 776
777 BlockEntryInstr* caller_entry = GetBlockEntry(call);
777 TargetEntryInstr* callee_entry = callee_graph->graph_entry()->normal_entry(); 778 TargetEntryInstr* callee_entry = callee_graph->graph_entry()->normal_entry();
778 ZoneGrowableArray<ReturnInstr*>* callee_exits = callee_graph->exits(); 779 ZoneGrowableArray<ReturnInstr*>* callee_exits = callee_graph->exits();
779 780
780 // 1. Insert the callee graph into the caller graph. 781 // 1. Insert the callee graph into the caller graph.
781 if (callee_exits->length() == 1) { 782 if (callee_exits->is_empty()) {
783 // If no normal exits exist, inline and truncate the block after inlining.
784 Link(call->previous(), callee_entry->next());
785 caller_entry->set_last_instruction(callee_entry->last_instruction());
786 } else if (callee_exits->length() == 1) {
782 ReturnInstr* exit = (*callee_exits)[0]; 787 ReturnInstr* exit = (*callee_exits)[0];
783 // TODO(zerny): Support one exit graph containing control flow. 788 // TODO(zerny): Support one exit graph containing control flow.
784 ASSERT(callee_entry == GetBlockEntry(exit)); 789 ASSERT(callee_entry == GetBlockEntry(exit));
785 // For just one exit, replace the uses and remove the call from the graph. 790 // For just one exit, replace the uses and remove the call from the graph.
786 call->ReplaceUsesWith(exit->value()->definition()); 791 call->ReplaceUsesWith(exit->value()->definition());
787 Link(call->previous(), callee_entry->next()); 792 Link(call->previous(), callee_entry->next());
788 Link(exit->previous(), call->next()); 793 Link(exit->previous(), call->next());
789 } else { 794 } else {
790 // TODO(zerny): Support multiple exits. 795 // TODO(zerny): Support multiple exits.
791 UNREACHABLE(); 796 UNREACHABLE();
792 } 797 }
793 798
794 // TODO(zerny): Adjust pre/post orders. 799 // TODO(zerny): Adjust pre/post orders.
795 // TODO(zerny): Update dominator tree. 800 // TODO(zerny): Update dominator tree.
796
797 // Remove original arguments to the call.
798 for (intptr_t i = 0; i < call->ArgumentCount(); ++i) {
799 PushArgumentInstr* push = call->ArgumentAt(i);
800 push->ReplaceUsesWith(push->value()->definition());
801 push->RemoveFromGraph();
802 }
803 } 801 }
804 802
805 803
806 } // namespace dart 804 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698