Index: src/compiler/scheduler.cc |
diff --git a/src/compiler/scheduler.cc b/src/compiler/scheduler.cc |
index aa9a7cfdb2ec79371274b03668c4d4dc25f6b1c6..2c53acf1e520f783b79f6fb52aa9348f14872ebe 100644 |
--- a/src/compiler/scheduler.cc |
+++ b/src/compiler/scheduler.cc |
@@ -1394,6 +1394,8 @@ class ScheduleLateNodeVisitor { |
// Schedule the node or a floating control structure. |
if (IrOpcode::IsMergeOpcode(node->opcode())) { |
ScheduleFloatingControl(block, node); |
+ } else if (node->opcode() == IrOpcode::kFinishRegion) { |
+ ScheduleRegion(block, node); |
} else { |
ScheduleNode(block, node); |
} |
@@ -1572,6 +1574,34 @@ class ScheduleLateNodeVisitor { |
scheduler_->FuseFloatingControl(block, node); |
} |
+ void ScheduleRegion(BasicBlock* block, Node* region_end) { |
+ // We only allow regions of instructions connected into a linear |
+ // effect chain. The only value allowed to be produced by a node |
+ // in the chain must be the value consumed by the FinishRegion node. |
+ |
+ // We schedule back to front; we first schedule FinishRegion. |
+ CHECK_EQ(IrOpcode::kFinishRegion, region_end->opcode()); |
+ ScheduleNode(block, region_end); |
+ |
+ // Schedule the chain. |
+ Node* node = NodeProperties::GetEffectInput(region_end); |
+ while (node->opcode() != IrOpcode::kBeginRegion) { |
+ DCHECK_EQ(0, scheduler_->GetData(node)->unscheduled_count_); |
+ DCHECK_EQ(1, node->op()->EffectInputCount()); |
+ DCHECK_EQ(1, node->op()->EffectOutputCount()); |
+ DCHECK_EQ(0, node->op()->ControlOutputCount()); |
+ // The value output (if there is any) must be consumed |
+ // by the EndRegion node. |
+ DCHECK(node->op()->ValueOutputCount() == 0 || |
+ node == region_end->InputAt(0)); |
+ ScheduleNode(block, node); |
+ node = NodeProperties::GetEffectInput(node); |
+ } |
+ // Schedule the BeginRegion node. |
+ DCHECK_EQ(0, scheduler_->GetData(node)->unscheduled_count_); |
+ ScheduleNode(block, node); |
+ } |
+ |
void ScheduleNode(BasicBlock* block, Node* node) { |
schedule_->PlanNode(block, node); |
scheduler_->scheduled_nodes_[block->id().ToSize()].push_back(node); |