Chromium Code Reviews| Index: src/compiler/common-operator-reducer.cc |
| diff --git a/src/compiler/common-operator-reducer.cc b/src/compiler/common-operator-reducer.cc |
| index 694c36edcc8d0f7876618be43fb213ea2737849a..5db582ef85015fd038d328fe071ac51d296553ea 100644 |
| --- a/src/compiler/common-operator-reducer.cc |
| +++ b/src/compiler/common-operator-reducer.cc |
| @@ -43,6 +43,16 @@ Decision DecideCondition(Node* const cond) { |
| } // namespace |
| +CommonOperatorReducer::CommonOperatorReducer(Editor* editor, Graph* graph, |
| + CommonOperatorBuilder* common, |
| + MachineOperatorBuilder* machine) |
| + : AdvancedReducer(editor), |
| + graph_(graph), |
| + common_(common), |
| + machine_(machine), |
| + dead_(graph->NewNode(common->Dead())) {} |
| + |
| + |
| Reduction CommonOperatorReducer::Reduce(Node* node) { |
| switch (node->opcode()) { |
| case IrOpcode::kBranch: |
| @@ -53,6 +63,8 @@ Reduction CommonOperatorReducer::Reduce(Node* node) { |
| return ReduceEffectPhi(node); |
| case IrOpcode::kPhi: |
| return ReducePhi(node); |
| + case IrOpcode::kReturn: |
| + return ReduceReturn(node); |
| case IrOpcode::kSelect: |
| return ReduceSelect(node); |
| default: |
| @@ -91,20 +103,19 @@ Reduction CommonOperatorReducer::ReduceBranch(Node* node) { |
| Decision const decision = DecideCondition(cond); |
| if (decision == Decision::kUnknown) return NoChange(); |
| Node* const control = node->InputAt(1); |
| - if (!dead_.is_set()) dead_.set(graph()->NewNode(common()->Dead())); |
| for (Node* const use : node->uses()) { |
| switch (use->opcode()) { |
| case IrOpcode::kIfTrue: |
| - Replace(use, (decision == Decision::kTrue) ? control : dead_.get()); |
| + Replace(use, (decision == Decision::kTrue) ? control : dead()); |
| break; |
| case IrOpcode::kIfFalse: |
| - Replace(use, (decision == Decision::kFalse) ? control : dead_.get()); |
| + Replace(use, (decision == Decision::kFalse) ? control : dead()); |
| break; |
| default: |
| UNREACHABLE(); |
| } |
| } |
| - return Replace(dead_.get()); |
| + return Replace(dead()); |
| } |
| @@ -253,6 +264,41 @@ Reduction CommonOperatorReducer::ReducePhi(Node* node) { |
| } |
| +Reduction CommonOperatorReducer::ReduceReturn(Node* node) { |
| + DCHECK_EQ(IrOpcode::kReturn, node->opcode()); |
| + Node* const value = node->InputAt(0); |
| + Node* const effect = node->InputAt(1); |
| + Node* const control = node->InputAt(2); |
| + if (value->opcode() == IrOpcode::kPhi && |
| + value->InputAt(value->InputCount() - 1) == control && |
|
Jarin
2015/06/26 07:55:31
Please use NodeProperties::GetControlInput here.
Benedikt Meurer
2015/06/26 07:56:59
Done.
|
| + effect->opcode() == IrOpcode::kEffectPhi && |
| + effect->InputAt(effect->InputCount() - 1) == control && |
| + control->opcode() == IrOpcode::kMerge) { |
| + int const control_input_count = control->InputCount(); |
| + DCHECK_NE(0, control_input_count); |
| + DCHECK_EQ(control_input_count, value->InputCount() - 1); |
| + DCHECK_EQ(control_input_count, effect->InputCount() - 1); |
| + Node* const end = graph()->end(); |
| + DCHECK_EQ(IrOpcode::kEnd, end->opcode()); |
| + DCHECK_NE(0, end->InputCount()); |
| + for (int i = 0; i < control_input_count; ++i) { |
| + // Create a new {Return} and connect it to {end}. We don't need to mark |
| + // {end} as revisit, because we mark {node} as {Dead} below, which was |
| + // previously connected to {end}, so we know for sure that at some point |
| + // the reducer logic will visit {end} again. |
| + Node* ret = graph()->NewNode(common()->Return(), value->InputAt(i), |
| + effect->InputAt(i), control->InputAt(i)); |
| + end->set_op(common()->End(end->InputCount() + 1)); |
| + end->AppendInput(graph()->zone(), ret); |
| + } |
| + // Mark the merge {control} and return {node} as {dead}. |
| + Replace(control, dead()); |
| + return Replace(dead()); |
| + } |
| + return NoChange(); |
| +} |
| + |
| + |
| Reduction CommonOperatorReducer::ReduceSelect(Node* node) { |
| DCHECK_EQ(IrOpcode::kSelect, node->opcode()); |
| Node* const cond = node->InputAt(0); |