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

Unified Diff: src/compiler/schedule.cc

Issue 1912093005: [turbofan] Single entry into deferred regions (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 8 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 | « src/compiler/schedule.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/compiler/schedule.cc
diff --git a/src/compiler/schedule.cc b/src/compiler/schedule.cc
index 08e078ef5ac89654445c78e33a7a03451a3e7cf2..6bd1a17be0603476585442eaea760ce2b1ad3eb4 100644
--- a/src/compiler/schedule.cc
+++ b/src/compiler/schedule.cc
@@ -315,41 +315,87 @@ void Schedule::InsertSwitch(BasicBlock* block, BasicBlock* end, Node* sw,
SetControlInput(block, sw);
}
-void Schedule::EnsureSplitEdgeForm() {
+void Schedule::EnsureCFGWellFormedness() {
// 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;
- }
- }
+ if (block->PredecessorCount() > 1) {
+ if (block != end_) {
+ EnsureSplitEdgeForm(block);
+ }
+ if (block->deferred()) {
+ EnsureDeferredCodeSingleEntryPoint(block);
+ }
+ }
+ }
+}
+
+void Schedule::EnsureSplitEdgeForm(BasicBlock* block) {
+ DCHECK(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::EnsureDeferredCodeSingleEntryPoint(BasicBlock* block) {
+ // If a deferred block has multiple predecessors, they have to
+ // all be deferred. Otherwise, we can run into a situation where a range
+ // that spills only in deferred blocks inserts its spill in the block, but
+ // other ranges need moves inserted by ResolveControlFlow in the predecessors,
+ // which may clobber the register of this range.
+ // To ensure that, when a deferred block has multiple predecessors, and some
+ // are not deferred, we add a non-deferred block to collect all such edges.
+
+ DCHECK(block->deferred() && block->PredecessorCount() > 1);
+ bool all_deferred = true;
+ for (auto current_pred = block->predecessors().begin();
+ current_pred != block->predecessors().end(); ++current_pred) {
+ BasicBlock* pred = *current_pred;
+ if (!pred->deferred()) {
+ all_deferred = false;
+ break;
+ }
+ }
+
+ if (all_deferred) return;
+ BasicBlock* merger = NewBasicBlock();
+ merger->set_control(BasicBlock::kGoto);
+ merger->successors().push_back(block);
+ for (auto current_pred = block->predecessors().begin();
+ current_pred != block->predecessors().end(); ++current_pred) {
+ BasicBlock* pred = *current_pred;
+ merger->predecessors().push_back(pred);
+ pred->successors().clear();
+ pred->successors().push_back(merger);
+ }
+ merger->set_deferred(false);
+ block->predecessors().clear();
+ block->predecessors().push_back(merger);
+}
+
void Schedule::PropagateDeferredMark() {
// Push forward the deferred block marks through newly inserted blocks and
// other improperly marked blocks until a fixed point is reached.
« no previous file with comments | « src/compiler/schedule.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698