Chromium Code Reviews| 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) { |
|
Benedikt Meurer
2015/10/13 19:12:10
Awesome! Thanks for making the checking generic.
|
| + // 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); |