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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/flow_graph.h ('k') | runtime/vm/intermediate_language.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/flow_graph.cc
diff --git a/runtime/vm/flow_graph.cc b/runtime/vm/flow_graph.cc
index 1964a81e64331ae42df08de622514a56ad02e065..14a49eb5281d3b8cd5ce8eb2263433cb4bbf0554 100644
--- a/runtime/vm/flow_graph.cc
+++ b/runtime/vm/flow_graph.cc
@@ -149,22 +149,84 @@ Instruction* FlowGraph::AppendTo(Instruction* prev,
}
+// A block entry wrapper including an index of the next successor to be read.
+class PostorderBlockEntryWrapper {
+ public:
+ explicit PostorderBlockEntryWrapper(BlockEntryInstr* block)
+ : block_(block),
+ next_successor_ix_(block->last_instruction()->SuccessorCount() - 1) { }
+
+ bool HasNextSuccessor() const { return next_successor_ix_ >= 0; }
+ BlockEntryInstr* NextSuccessor() {
+ return block_->last_instruction()->SuccessorAt(next_successor_ix_--);
+ }
+
+ BlockEntryInstr* block() const { return block_; }
+
+ private:
+ BlockEntryInstr* block_;
+ intptr_t next_successor_ix_;
+
+ DISALLOW_ALLOCATION();
+};
+
+
+// Iterative graph postorder traversal. DiscoverBlocks() must have been called
+// before this in order to set up BlockEntryInstr::last_instruction().
+static void BuildPostorder(Isolate* isolate,
+ BlockEntryInstr* graph_entry,
+ GrowableArray<BlockEntryInstr*>* postorder,
+ intptr_t num_blocks) {
+ GrowableArray<PostorderBlockEntryWrapper> block_stack;
+ block_stack.Add(PostorderBlockEntryWrapper(graph_entry));
+
+ BitVector visited(isolate, num_blocks);
+ while (!block_stack.is_empty()) {
+ PostorderBlockEntryWrapper &last = block_stack.Last();
+ BlockEntryInstr* block = last.block();
+ visited.Add(block->preorder_number());
+ if (last.HasNextSuccessor()) {
+ // Process successors one-by-one.
+ BlockEntryInstr* succ = last.NextSuccessor();
+ if (!visited.Contains(succ->preorder_number())) {
+ block_stack.Add(PostorderBlockEntryWrapper(succ));
+ }
+ } else {
+ // All successors have been processed, pop the current block entry node
+ // and add it to the postorder list.
+ block_stack.RemoveLast();
+ block->set_postorder_number(postorder->length());
+ postorder->Add(block);
+ }
+ }
+}
+
+
void FlowGraph::DiscoverBlocks() {
// Initialize state.
preorder_.Clear();
postorder_.Clear();
reverse_postorder_.Clear();
parent_.Clear();
- // Perform a depth-first traversal of the graph to build preorder and
- // postorder block orders.
- graph_entry_->DiscoverBlocks(NULL, // Entry block predecessor.
+
+ // Perform an iterative depth-first traversal of the graph to build preorder
+ // block order, spanning-tree parents, and predecessors for each block entry.
+ 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
+ block_stack.Add(BlockEntryEdge(NULL, graph_entry()));
+ while (!block_stack.is_empty()) {
+ BlockEntryEdge pair = block_stack.RemoveLast();
+ pair.child->DiscoverBlocks(pair.parent,
&preorder_,
- &postorder_,
&parent_,
- variable_count(),
- num_non_copied_params());
+ &block_stack);
+ }
+
+ // Create an array of blocks in postorder.
+ 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.
+ BuildPostorder(isolate(), graph_entry(), &postorder_, block_count);
+ ASSERT(postorder_.length() == preorder_.length());
+
// Create an array of blocks in reverse postorder.
- intptr_t block_count = postorder_.length();
for (intptr_t i = 0; i < block_count; ++i) {
reverse_postorder_.Add(postorder_[block_count - i - 1]);
}
« 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