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

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

Issue 617933003: Iterative graph traversal in FlowGraph::DiscoverBlocks() (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 2 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
« no previous file with comments | « runtime/vm/flow_graph.h ('k') | runtime/vm/intermediate_language.h » ('j') | 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.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/growable_array.h" 10 #include "vm/growable_array.h"
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
142 if (use_kind == kValue) { 142 if (use_kind == kValue) {
143 ASSERT(instr->IsDefinition()); 143 ASSERT(instr->IsDefinition());
144 AllocateSSAIndexes(instr->AsDefinition()); 144 AllocateSSAIndexes(instr->AsDefinition());
145 } 145 }
146 ASSERT(instr->env() == NULL); 146 ASSERT(instr->env() == NULL);
147 if (env != NULL) env->DeepCopyTo(isolate(), instr); 147 if (env != NULL) env->DeepCopyTo(isolate(), instr);
148 return prev->AppendInstruction(instr); 148 return prev->AppendInstruction(instr);
149 } 149 }
150 150
151 151
152 // A block entry wrapper including an index of the next successor to be read.
153 class PostorderBlockEntryWrapper {
154 public:
155 explicit PostorderBlockEntryWrapper(BlockEntryInstr* block)
156 : block_(block),
157 next_successor_ix_(block->last_instruction()->SuccessorCount() - 1) { }
158
159 bool HasNextSuccessor() const { return next_successor_ix_ >= 0; }
160 BlockEntryInstr* NextSuccessor() {
161 return block_->last_instruction()->SuccessorAt(next_successor_ix_--);
162 }
163
164 BlockEntryInstr* block() const { return block_; }
165
166 private:
167 BlockEntryInstr* block_;
168 intptr_t next_successor_ix_;
169
170 DISALLOW_ALLOCATION();
171 };
172
173
174 // Iterative graph postorder traversal. DiscoverBlocks() must have been called
175 // before this in order to set up BlockEntryInstr::last_instruction().
176 static void BuildPostorder(Isolate* isolate,
177 BlockEntryInstr* graph_entry,
178 GrowableArray<BlockEntryInstr*>* postorder,
179 intptr_t num_blocks) {
180 GrowableArray<PostorderBlockEntryWrapper> block_stack;
181 block_stack.Add(PostorderBlockEntryWrapper(graph_entry));
182
183 BitVector visited(isolate, num_blocks);
184 while (!block_stack.is_empty()) {
185 PostorderBlockEntryWrapper &last = block_stack.Last();
186 BlockEntryInstr* block = last.block();
187 visited.Add(block->preorder_number());
188 if (last.HasNextSuccessor()) {
189 // Process successors one-by-one.
190 BlockEntryInstr* succ = last.NextSuccessor();
191 if (!visited.Contains(succ->preorder_number())) {
192 block_stack.Add(PostorderBlockEntryWrapper(succ));
193 }
194 } else {
195 // All successors have been processed, pop the current block entry node
196 // and add it to the postorder list.
197 block_stack.RemoveLast();
198 block->set_postorder_number(postorder->length());
199 postorder->Add(block);
200 }
201 }
202 }
203
204
152 void FlowGraph::DiscoverBlocks() { 205 void FlowGraph::DiscoverBlocks() {
153 // Initialize state. 206 // Initialize state.
154 preorder_.Clear(); 207 preorder_.Clear();
155 postorder_.Clear(); 208 postorder_.Clear();
156 reverse_postorder_.Clear(); 209 reverse_postorder_.Clear();
157 parent_.Clear(); 210 parent_.Clear();
158 // Perform a depth-first traversal of the graph to build preorder and 211
159 // postorder block orders. 212 // Perform an iterative depth-first traversal of the graph to build preorder
160 graph_entry_->DiscoverBlocks(NULL, // Entry block predecessor. 213 // block order, spanning-tree parents, and predecessors for each block entry.
214 GrowableArray<BlockEntryEdge> block_stack;
Vyacheslav Egorov (Google) 2014/10/07 12:43:17 I would really like to have this block_stack die a
jgruber1 2014/10/08 15:11:29 Done. I didn't realize the array memory sticks aro
215 block_stack.Add(BlockEntryEdge(NULL, graph_entry()));
216 while (!block_stack.is_empty()) {
217 BlockEntryEdge pair = block_stack.RemoveLast();
218 pair.child->DiscoverBlocks(pair.parent,
161 &preorder_, 219 &preorder_,
162 &postorder_,
163 &parent_, 220 &parent_,
164 variable_count(), 221 &block_stack);
165 num_non_copied_params()); 222 }
223
224 // Create an array of blocks in postorder.
225 const intptr_t block_count = preorder_.length();
Vyacheslav Egorov (Google) 2014/10/07 12:43:17 Maybe I am missing something but I think you can b
jgruber1 2014/10/08 15:11:29 Good point, done.
226 BuildPostorder(isolate(), graph_entry(), &postorder_, block_count);
227 ASSERT(postorder_.length() == preorder_.length());
228
166 // Create an array of blocks in reverse postorder. 229 // Create an array of blocks in reverse postorder.
167 intptr_t block_count = postorder_.length();
168 for (intptr_t i = 0; i < block_count; ++i) { 230 for (intptr_t i = 0; i < block_count; ++i) {
169 reverse_postorder_.Add(postorder_[block_count - i - 1]); 231 reverse_postorder_.Add(postorder_[block_count - i - 1]);
170 } 232 }
171 233
172 // Block effects are using postorder numbering. Discard computed information. 234 // Block effects are using postorder numbering. Discard computed information.
173 block_effects_ = NULL; 235 block_effects_ = NULL;
174 loop_headers_ = NULL; 236 loop_headers_ = NULL;
175 loop_invariant_loads_ = NULL; 237 loop_invariant_loads_ = NULL;
176 } 238 }
177 239
(...skipping 1077 matching lines...) Expand 10 before | Expand all | Expand 10 after
1255 } 1317 }
1256 1318
1257 1319
1258 bool BlockEffects::IsSideEffectFreePath(BlockEntryInstr* from, 1320 bool BlockEffects::IsSideEffectFreePath(BlockEntryInstr* from,
1259 BlockEntryInstr* to) const { 1321 BlockEntryInstr* to) const {
1260 return available_at_[to->postorder_number()]->Contains( 1322 return available_at_[to->postorder_number()]->Contains(
1261 from->postorder_number()); 1323 from->postorder_number());
1262 } 1324 }
1263 1325
1264 } // namespace dart 1326 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph.h ('k') | runtime/vm/intermediate_language.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698