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

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

Issue 10893027: Inlining of static calls with trivial function bodies. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: 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"
11 #include "vm/growable_array.h"
11 12
12 namespace dart { 13 namespace dart {
13 14
14 FlowGraph::FlowGraph(const FlowGraphBuilder& builder, 15 FlowGraph::FlowGraph(const FlowGraphBuilder& builder,
15 GraphEntryInstr* graph_entry) 16 GraphEntryInstr* graph_entry)
16 : parent_(), 17 : parent_(),
17 assigned_vars_(), 18 assigned_vars_(),
18 current_ssa_temp_index_(0), 19 current_ssa_temp_index_(0),
19 parsed_function_(builder.parsed_function()), 20 parsed_function_(builder.parsed_function()),
20 copied_parameter_count_(builder.copied_parameter_count()), 21 copied_parameter_count_(builder.copied_parameter_count()),
21 non_copied_parameter_count_(builder.non_copied_parameter_count()), 22 non_copied_parameter_count_(builder.non_copied_parameter_count()),
22 stack_local_count_(builder.stack_local_count()), 23 stack_local_count_(builder.stack_local_count()),
23 graph_entry_(graph_entry), 24 graph_entry_(graph_entry),
24 preorder_(), 25 preorder_(),
25 postorder_(), 26 postorder_(),
26 reverse_postorder_() { 27 reverse_postorder_(),
28 exits_(NULL) {
27 DiscoverBlocks(); 29 DiscoverBlocks();
28 } 30 }
29 31
30 32
31 void FlowGraph::DiscoverBlocks() { 33 void FlowGraph::DiscoverBlocks() {
32 // Initialize state. 34 // Initialize state.
33 preorder_.TruncateTo(0); 35 preorder_.TruncateTo(0);
34 postorder_.TruncateTo(0); 36 postorder_.TruncateTo(0);
35 reverse_postorder_.TruncateTo(0); 37 reverse_postorder_.TruncateTo(0);
36 parent_.TruncateTo(0); 38 parent_.TruncateTo(0);
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after
290 InsertPhis(preorder_, assigned_vars_, dominance_frontier); 292 InsertPhis(preorder_, assigned_vars_, dominance_frontier);
291 GrowableArray<PhiInstr*> live_phis; 293 GrowableArray<PhiInstr*> live_phis;
292 // Rename uses to reference inserted phis where appropriate. 294 // Rename uses to reference inserted phis where appropriate.
293 // Collect phis that reach a non-environment use. 295 // Collect phis that reach a non-environment use.
294 Rename(&live_phis); 296 Rename(&live_phis);
295 // Propagate alive mark transitively from alive phis. 297 // Propagate alive mark transitively from alive phis.
296 MarkLivePhis(&live_phis); 298 MarkLivePhis(&live_phis);
297 } 299 }
298 300
299 301
302 void FlowGraph::ComputeSSAForInlining(
303 intptr_t callers_max_virtual_register_number) {
304 current_ssa_temp_index_ = callers_max_virtual_register_number;
305 ComputeSSA();
306 }
307
308
300 // Compute immediate dominators and the dominance frontier for each basic 309 // Compute immediate dominators and the dominance frontier for each basic
301 // block. As a side effect of the algorithm, sets the immediate dominator 310 // block. As a side effect of the algorithm, sets the immediate dominator
302 // of each basic block. 311 // of each basic block.
303 // 312 //
304 // preorder: an input list of basic block entries in preorder. The 313 // preorder: an input list of basic block entries in preorder. The
305 // algorithm relies on the block ordering. 314 // algorithm relies on the block ordering.
306 // 315 //
307 // parent: an input parameter encoding a depth-first spanning tree of 316 // parent: an input parameter encoding a depth-first spanning tree of
308 // the control flow graph. The array maps the preorder block 317 // the control flow graph. The array maps the preorder block
309 // number of a block to the preorder block number of its spanning 318 // number of a block to the preorder block number of its spanning
(...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after
676 const char* function_name = parsed_function_.function().ToCString(); 685 const char* function_name = parsed_function_.function().ToCString();
677 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; 686 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1;
678 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); 687 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len);
679 OS::SNPrint(chars, len, kFormat, function_name, reason); 688 OS::SNPrint(chars, len, kFormat, function_name, reason);
680 const Error& error = Error::Handle( 689 const Error& error = Error::Handle(
681 LanguageError::New(String::Handle(String::New(chars)))); 690 LanguageError::New(String::Handle(String::New(chars))));
682 Isolate::Current()->long_jump_base()->Jump(1, error); 691 Isolate::Current()->long_jump_base()->Jump(1, error);
683 } 692 }
684 693
685 694
695 // Helper to get the block-entry ancestor of an instruction.
Kevin Millikin (Google) 2012/08/29 14:01:04 'ancestor' makes me think of trees.
zerny-google 2012/08/30 07:31:40 Done.
696 static BlockEntryInstr* GetBlockEntry(Instruction* instr) {
697 while (!instr->IsBlockEntry()) instr = instr->previous();
698 return instr->AsBlockEntry();
699 }
700
701
702 // Helper to link two instruction in the graph.
srdjan 2012/08/29 21:31:33 s/instruction/instructions/
zerny-google 2012/08/30 07:31:40 Done.
703 static void Link(Instruction* prev, Instruction* next) {
704 ASSERT(prev != next);
705 prev->set_next(next);
706 next->set_previous(prev);
707 }
708
709
710 // Inline a flow graph at a call site.
711 //
712 // Assumes the callee graph was computed with BuildGraphForInlining and
713 // transformed to SSA with ComputeSSAForInlining, and that the use lists have
714 // been correctly computed.
715 //
716 // After inlining the caller graph will correctly have adjusted the pre/post
717 // orders, the dominator tree and the use lists.
718 void FlowGraph::InlineCall(BindInstr* caller_instr,
719 StaticCallComp* caller_comp,
720 FlowGraph* callee_graph) {
721 ASSERT(callee_graph->exits() != NULL);
722 ASSERT(callee_graph->graph_entry()->SuccessorCount() == 1);
723 ASSERT(callee_graph->max_virtual_register_number() >
724 max_virtual_register_number());
725
726 // TODO(zerny): Implement support for callee graphs with control flow.
727 ASSERT(callee_graph->preorder().length() == 2);
728
729 // Adjust the SSA temp index by the callee graph's index.
730 current_ssa_temp_index_ = callee_graph->max_virtual_register_number();
731
732 TargetEntryInstr* callee_entry = callee_graph->graph_entry()->normal_entry();
733 ZoneGrowableArray<ReturnInstr*>* callee_exits = callee_graph->exits();
734
735 // 1. Insert the callee graph into the caller graph.
736 if (callee_exits->length() == 1) {
737 ReturnInstr* exit = (*callee_exits)[0];
738 // TODO(zerny): Support one exit graph containing control flow.
739 ASSERT(callee_entry == GetBlockEntry(exit));
740 // For just one exit, replace the uses and remove the call from the graph.
741 caller_instr->ReplaceUsesWith(exit->value());
742 Link(caller_instr->previous(), callee_entry->next());
743 Link(exit->previous(), caller_instr->next());
744 } else {
745 // TODO(zerny): Support multiple exits.
746 UNREACHABLE();
747 }
748
749 // TODO(zerny): Adjust pre/post orders.
750 // TODO(zerny): Update dominator tree.
751
752 // Remove original arguments to the call.
753 for (intptr_t i = 0; i < caller_comp->ArgumentCount(); ++i) {
754 PushArgumentInstr* push = caller_comp->ArgumentAt(i);
755 push->ReplaceUsesWith(push->value());
756 push->RemoveFromGraph();
757 }
758 }
759
760
686 } // namespace dart 761 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698