| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/compiler/common-operator-reducer.h" | 5 #include "src/compiler/common-operator-reducer.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "src/compiler/common-operator.h" | 9 #include "src/compiler/common-operator.h" |
| 10 #include "src/compiler/graph.h" | 10 #include "src/compiler/graph.h" |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 50 graph_(graph), | 50 graph_(graph), |
| 51 common_(common), | 51 common_(common), |
| 52 machine_(machine), | 52 machine_(machine), |
| 53 dead_(graph->NewNode(common->Dead())) {} | 53 dead_(graph->NewNode(common->Dead())) {} |
| 54 | 54 |
| 55 | 55 |
| 56 Reduction CommonOperatorReducer::Reduce(Node* node) { | 56 Reduction CommonOperatorReducer::Reduce(Node* node) { |
| 57 switch (node->opcode()) { | 57 switch (node->opcode()) { |
| 58 case IrOpcode::kBranch: | 58 case IrOpcode::kBranch: |
| 59 return ReduceBranch(node); | 59 return ReduceBranch(node); |
| 60 case IrOpcode::kDeoptimizeIf: |
| 61 case IrOpcode::kDeoptimizeUnless: |
| 62 return ReduceDeoptimizeConditional(node); |
| 60 case IrOpcode::kMerge: | 63 case IrOpcode::kMerge: |
| 61 return ReduceMerge(node); | 64 return ReduceMerge(node); |
| 62 case IrOpcode::kEffectPhi: | 65 case IrOpcode::kEffectPhi: |
| 63 return ReduceEffectPhi(node); | 66 return ReduceEffectPhi(node); |
| 64 case IrOpcode::kPhi: | 67 case IrOpcode::kPhi: |
| 65 return ReducePhi(node); | 68 return ReducePhi(node); |
| 66 case IrOpcode::kReturn: | 69 case IrOpcode::kReturn: |
| 67 return ReduceReturn(node); | 70 return ReduceReturn(node); |
| 68 case IrOpcode::kSelect: | 71 case IrOpcode::kSelect: |
| 69 return ReduceSelect(node); | 72 return ReduceSelect(node); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 116 case IrOpcode::kIfFalse: | 119 case IrOpcode::kIfFalse: |
| 117 Replace(use, (decision == Decision::kFalse) ? control : dead()); | 120 Replace(use, (decision == Decision::kFalse) ? control : dead()); |
| 118 break; | 121 break; |
| 119 default: | 122 default: |
| 120 UNREACHABLE(); | 123 UNREACHABLE(); |
| 121 } | 124 } |
| 122 } | 125 } |
| 123 return Replace(dead()); | 126 return Replace(dead()); |
| 124 } | 127 } |
| 125 | 128 |
| 129 Reduction CommonOperatorReducer::ReduceDeoptimizeConditional(Node* node) { |
| 130 DCHECK(node->opcode() == IrOpcode::kDeoptimizeIf || |
| 131 node->opcode() == IrOpcode::kDeoptimizeUnless); |
| 132 bool condition_is_true = node->opcode() == IrOpcode::kDeoptimizeUnless; |
| 133 Node* condition = NodeProperties::GetValueInput(node, 0); |
| 134 Node* frame_state = NodeProperties::GetValueInput(node, 1); |
| 135 Node* effect = NodeProperties::GetEffectInput(node); |
| 136 Node* control = NodeProperties::GetControlInput(node); |
| 137 // Swap DeoptimizeIf/DeoptimizeUnless on {node} if {cond} is a BooleaNot |
| 138 // and use the input to BooleanNot as new condition for {node}. Note we |
| 139 // assume that {cond} was already properly optimized before we get here |
| 140 // (as guaranteed by the graph reduction logic). |
| 141 if (condition->opcode() == IrOpcode::kBooleanNot) { |
| 142 NodeProperties::ReplaceValueInput(node, condition->InputAt(0), 0); |
| 143 NodeProperties::ChangeOp(node, condition_is_true |
| 144 ? common()->DeoptimizeIf() |
| 145 : common()->DeoptimizeUnless()); |
| 146 return Changed(node); |
| 147 } |
| 148 Decision const decision = DecideCondition(condition); |
| 149 if (decision == Decision::kUnknown) return NoChange(); |
| 150 if (condition_is_true == (decision == Decision::kTrue)) { |
| 151 return Replace(control); |
| 152 } |
| 153 control = graph()->NewNode(common()->Deoptimize(DeoptimizeKind::kEager), |
| 154 frame_state, effect, control); |
| 155 // TODO(bmeurer): This should be on the AdvancedReducer somehow. |
| 156 NodeProperties::MergeControlToEnd(graph(), common(), control); |
| 157 Revisit(graph()->end()); |
| 158 return Replace(dead()); |
| 159 } |
| 126 | 160 |
| 127 Reduction CommonOperatorReducer::ReduceMerge(Node* node) { | 161 Reduction CommonOperatorReducer::ReduceMerge(Node* node) { |
| 128 DCHECK_EQ(IrOpcode::kMerge, node->opcode()); | 162 DCHECK_EQ(IrOpcode::kMerge, node->opcode()); |
| 129 // | 163 // |
| 130 // Check if this is a merge that belongs to an unused diamond, which means | 164 // Check if this is a merge that belongs to an unused diamond, which means |
| 131 // that: | 165 // that: |
| 132 // | 166 // |
| 133 // a) the {Merge} has no {Phi} or {EffectPhi} uses, and | 167 // a) the {Merge} has no {Phi} or {EffectPhi} uses, and |
| 134 // b) the {Merge} has two inputs, one {IfTrue} and one {IfFalse}, which are | 168 // b) the {Merge} has two inputs, one {IfTrue} and one {IfFalse}, which are |
| 135 // both owned by the Merge, and | 169 // both owned by the Merge, and |
| (...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 386 node->ReplaceInput(0, a); | 420 node->ReplaceInput(0, a); |
| 387 node->ReplaceInput(1, b); | 421 node->ReplaceInput(1, b); |
| 388 node->TrimInputCount(2); | 422 node->TrimInputCount(2); |
| 389 NodeProperties::ChangeOp(node, op); | 423 NodeProperties::ChangeOp(node, op); |
| 390 return Changed(node); | 424 return Changed(node); |
| 391 } | 425 } |
| 392 | 426 |
| 393 } // namespace compiler | 427 } // namespace compiler |
| 394 } // namespace internal | 428 } // namespace internal |
| 395 } // namespace v8 | 429 } // namespace v8 |
| OLD | NEW |