Index: src/compiler/schedule.cc |
diff --git a/src/compiler/schedule.cc b/src/compiler/schedule.cc |
index 455fcd120e1eab065205813328910517361af44e..c8853a0f8ab466bfd9be70521ea27c42ff37aecf 100644 |
--- a/src/compiler/schedule.cc |
+++ b/src/compiler/schedule.cc |
@@ -298,6 +298,64 @@ void Schedule::InsertSwitch(BasicBlock* block, BasicBlock* end, Node* sw, |
SetControlInput(block, sw); |
} |
+void Schedule::EnsureSplitEdgeForm() { |
+ // Make a copy of all the blocks for the iteration, since adding the split |
+ // edges will allocate new blocks. |
+ BasicBlockVector all_blocks_copy(all_blocks_); |
+ |
+ // Insert missing split edge blocks. |
+ for (auto block : all_blocks_copy) { |
+ if (block->PredecessorCount() > 1 && block != end_) { |
+ for (auto current_pred = block->predecessors().begin(); |
+ current_pred != block->predecessors().end(); ++current_pred) { |
+ BasicBlock* pred = *current_pred; |
+ if (pred->SuccessorCount() > 1) { |
+ // Found a predecessor block with multiple successors. |
+ BasicBlock* split_edge_block = NewBasicBlock(); |
+ split_edge_block->set_control(BasicBlock::kGoto); |
+ split_edge_block->successors().push_back(block); |
+ split_edge_block->predecessors().push_back(pred); |
+ split_edge_block->set_deferred(pred->deferred()); |
+ *current_pred = split_edge_block; |
+ // Find a corresponding successor in the previous block, replace it |
+ // with the split edge block... but only do it once, since we only |
+ // replace the previous blocks in the current block one at a time. |
+ for (auto successor = pred->successors().begin(); |
+ successor != pred->successors().end(); ++successor) { |
+ if (*successor == block) { |
+ *successor = split_edge_block; |
+ break; |
+ } |
+ } |
+ } |
+ } |
+ } |
+ } |
+} |
+ |
+void Schedule::PropagateDeferredMark() { |
+ // Push forward the deferred block marks through newly inserted blocks and |
+ // other improperly marked blocks until a fixed point is reached. |
+ // TODO(danno): optimize the propagation |
+ bool done = false; |
+ while (!done) { |
+ done = true; |
+ for (auto block : all_blocks_) { |
+ if (!block->deferred()) { |
+ bool deferred = block->PredecessorCount() > 0; |
+ for (auto pred : block->predecessors()) { |
+ if (!pred->deferred()) { |
+ deferred = false; |
+ } |
+ } |
+ if (deferred) { |
+ block->set_deferred(true); |
+ done = false; |
+ } |
+ } |
+ } |
+ } |
+} |
void Schedule::AddSuccessor(BasicBlock* block, BasicBlock* succ) { |
block->AddSuccessor(succ); |
@@ -331,15 +389,24 @@ void Schedule::SetBlockForNode(BasicBlock* block, Node* node) { |
std::ostream& operator<<(std::ostream& os, const Schedule& s) { |
- for (BasicBlock* block : *s.rpo_order()) { |
- os << "--- BLOCK B" << block->rpo_number(); |
+ for (BasicBlock* block : |
+ ((s.RpoBlockCount() == 0) ? *s.all_blocks() : *s.rpo_order())) { |
+ if (block->rpo_number() == -1) { |
+ os << "--- BLOCK B" << block->id().ToInt() << " (block id)"; |
+ } else { |
+ os << "--- BLOCK B" << block->rpo_number(); |
+ } |
if (block->deferred()) os << " (deferred)"; |
if (block->PredecessorCount() != 0) os << " <- "; |
bool comma = false; |
for (BasicBlock const* predecessor : block->predecessors()) { |
if (comma) os << ", "; |
comma = true; |
- os << "B" << predecessor->rpo_number(); |
+ if (predecessor->rpo_number() == -1) { |
+ os << "B" << predecessor->id().ToInt(); |
+ } else { |
+ os << "B" << predecessor->rpo_number(); |
+ } |
} |
os << " ---\n"; |
for (Node* node : *block) { |
@@ -364,7 +431,11 @@ std::ostream& operator<<(std::ostream& os, const Schedule& s) { |
for (BasicBlock const* successor : block->successors()) { |
if (comma) os << ", "; |
comma = true; |
- os << "B" << successor->rpo_number(); |
+ if (successor->rpo_number() == -1) { |
+ os << "B" << successor->id().ToInt(); |
+ } else { |
+ os << "B" << successor->rpo_number(); |
+ } |
} |
os << "\n"; |
} |