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 |