| OLD | NEW |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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/branch-elimination.h" | 5 #include "src/compiler/branch-elimination.h" |
| 6 | 6 |
| 7 #include "src/compiler/js-graph.h" | 7 #include "src/compiler/js-graph.h" |
| 8 #include "src/compiler/node-properties.h" | 8 #include "src/compiler/node-properties.h" |
| 9 #include "src/compiler/simplified-operator.h" | 9 #include "src/compiler/simplified-operator.h" |
| 10 | 10 |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 85 bool condition_is_true = node->opcode() == IrOpcode::kDeoptimizeUnless; | 85 bool condition_is_true = node->opcode() == IrOpcode::kDeoptimizeUnless; |
| 86 Node* condition = NodeProperties::GetValueInput(node, 0); | 86 Node* condition = NodeProperties::GetValueInput(node, 0); |
| 87 Node* frame_state = NodeProperties::GetValueInput(node, 1); | 87 Node* frame_state = NodeProperties::GetValueInput(node, 1); |
| 88 Node* effect = NodeProperties::GetEffectInput(node); | 88 Node* effect = NodeProperties::GetEffectInput(node); |
| 89 Node* control = NodeProperties::GetControlInput(node); | 89 Node* control = NodeProperties::GetControlInput(node); |
| 90 ControlPathConditions const* conditions = node_conditions_.Get(control); | 90 ControlPathConditions const* conditions = node_conditions_.Get(control); |
| 91 // If we do not know anything about the predecessor, do not propagate just | 91 // If we do not know anything about the predecessor, do not propagate just |
| 92 // yet because we will have to recompute anyway once we compute the | 92 // yet because we will have to recompute anyway once we compute the |
| 93 // predecessor. | 93 // predecessor. |
| 94 if (conditions == nullptr) { | 94 if (conditions == nullptr) { |
| 95 DCHECK_NULL(node_conditions_.Get(node)); | 95 return UpdateConditions(node, conditions); |
| 96 return NoChange(); | |
| 97 } | 96 } |
| 98 Maybe<bool> condition_value = conditions->LookupCondition(condition); | 97 Maybe<bool> condition_value = conditions->LookupCondition(condition); |
| 99 if (condition_value.IsJust()) { | 98 if (condition_value.IsJust()) { |
| 100 // If we know the condition we can discard the branch. | 99 // If we know the condition we can discard the branch. |
| 101 if (condition_is_true == condition_value.FromJust()) { | 100 if (condition_is_true == condition_value.FromJust()) { |
| 102 // We don't update the conditions here, because we're replacing {node} | 101 // We don't update the conditions here, because we're replacing {node} |
| 103 // with the {control} node that already contains the right information. | 102 // with the {control} node that already contains the right information. |
| 104 ReplaceWithValue(node, dead(), effect, control); | 103 ReplaceWithValue(node, dead(), effect, control); |
| 105 } else { | 104 } else { |
| 106 control = graph()->NewNode(common()->Deoptimize(DeoptimizeKind::kEager), | 105 control = graph()->NewNode(common()->Deoptimize(DeoptimizeKind::kEager), |
| 107 frame_state, effect, control); | 106 frame_state, effect, control); |
| 108 // TODO(bmeurer): This should be on the AdvancedReducer somehow. | 107 // TODO(bmeurer): This should be on the AdvancedReducer somehow. |
| 109 NodeProperties::MergeControlToEnd(graph(), common(), control); | 108 NodeProperties::MergeControlToEnd(graph(), common(), control); |
| 110 Revisit(graph()->end()); | 109 Revisit(graph()->end()); |
| 111 } | 110 } |
| 112 return Replace(dead()); | 111 return Replace(dead()); |
| 113 } | 112 } |
| 114 return UpdateConditions( | 113 return UpdateConditions( |
| 115 node, conditions->AddCondition(zone_, condition, condition_is_true)); | 114 node, conditions->AddCondition(zone_, condition, condition_is_true)); |
| 116 } | 115 } |
| 117 | 116 |
| 118 Reduction BranchElimination::ReduceIf(Node* node, bool is_true_branch) { | 117 Reduction BranchElimination::ReduceIf(Node* node, bool is_true_branch) { |
| 119 // Add the condition to the list arriving from the input branch. | 118 // Add the condition to the list arriving from the input branch. |
| 120 Node* branch = NodeProperties::GetControlInput(node, 0); | 119 Node* branch = NodeProperties::GetControlInput(node, 0); |
| 121 const ControlPathConditions* from_branch = node_conditions_.Get(branch); | 120 const ControlPathConditions* from_branch = node_conditions_.Get(branch); |
| 122 // If we do not know anything about the predecessor, do not propagate just | 121 // If we do not know anything about the predecessor, do not propagate just |
| 123 // yet because we will have to recompute anyway once we compute the | 122 // yet because we will have to recompute anyway once we compute the |
| 124 // predecessor. | 123 // predecessor. |
| 125 if (from_branch == nullptr) { | 124 if (from_branch == nullptr) { |
| 126 DCHECK(node_conditions_.Get(node) == nullptr); | 125 return UpdateConditions(node, nullptr); |
| 127 return NoChange(); | |
| 128 } | 126 } |
| 129 Node* condition = branch->InputAt(0); | 127 Node* condition = branch->InputAt(0); |
| 130 return UpdateConditions( | 128 return UpdateConditions( |
| 131 node, from_branch->AddCondition(zone_, condition, is_true_branch)); | 129 node, from_branch->AddCondition(zone_, condition, is_true_branch)); |
| 132 } | 130 } |
| 133 | 131 |
| 134 | 132 |
| 135 Reduction BranchElimination::ReduceLoop(Node* node) { | 133 Reduction BranchElimination::ReduceLoop(Node* node) { |
| 136 // Here we rely on having only reducible loops: | 134 // Here we rely on having only reducible loops: |
| 137 // The loop entry edge always dominates the header, so we can just use | 135 // The loop entry edge always dominates the header, so we can just use |
| 138 // the information from the loop entry edge. | 136 // the information from the loop entry edge. |
| 139 return TakeConditionsFromFirstControl(node); | 137 return TakeConditionsFromFirstControl(node); |
| 140 } | 138 } |
| 141 | 139 |
| 142 | 140 |
| 143 Reduction BranchElimination::ReduceMerge(Node* node) { | 141 Reduction BranchElimination::ReduceMerge(Node* node) { |
| 144 // Shortcut for the case when we do not know anything about some | 142 // Shortcut for the case when we do not know anything about some |
| 145 // input. | 143 // input. |
| 146 for (int i = 0; i < node->InputCount(); i++) { | 144 for (int i = 0; i < node->InputCount(); i++) { |
| 147 if (node_conditions_.Get(node->InputAt(i)) == nullptr) { | 145 if (node_conditions_.Get(node->InputAt(i)) == nullptr) { |
| 148 DCHECK(node_conditions_.Get(node) == nullptr); | 146 return UpdateConditions(node, nullptr); |
| 149 return NoChange(); | |
| 150 } | 147 } |
| 151 } | 148 } |
| 152 | 149 |
| 153 const ControlPathConditions* first = node_conditions_.Get(node->InputAt(0)); | 150 const ControlPathConditions* first = node_conditions_.Get(node->InputAt(0)); |
| 154 // Make a copy of the first input's conditions and merge with the conditions | 151 // Make a copy of the first input's conditions and merge with the conditions |
| 155 // from other inputs. | 152 // from other inputs. |
| 156 ControlPathConditions* conditions = | 153 ControlPathConditions* conditions = |
| 157 new (zone_->New(sizeof(ControlPathConditions))) | 154 new (zone_->New(sizeof(ControlPathConditions))) |
| 158 ControlPathConditions(*first); | 155 ControlPathConditions(*first); |
| 159 for (int i = 1; i < node->InputCount(); i++) { | 156 for (int i = 1; i < node->InputCount(); i++) { |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 202 return UpdateConditions(node, from_input); | 199 return UpdateConditions(node, from_input); |
| 203 } | 200 } |
| 204 | 201 |
| 205 | 202 |
| 206 Reduction BranchElimination::UpdateConditions( | 203 Reduction BranchElimination::UpdateConditions( |
| 207 Node* node, const ControlPathConditions* conditions) { | 204 Node* node, const ControlPathConditions* conditions) { |
| 208 const ControlPathConditions* original = node_conditions_.Get(node); | 205 const ControlPathConditions* original = node_conditions_.Get(node); |
| 209 // Only signal that the node has Changed if the condition information has | 206 // Only signal that the node has Changed if the condition information has |
| 210 // changed. | 207 // changed. |
| 211 if (conditions != original) { | 208 if (conditions != original) { |
| 212 if (original == nullptr || *conditions != *original) { | 209 if (conditions == nullptr || original == nullptr || |
| 210 *conditions != *original) { |
| 213 node_conditions_.Set(node, conditions); | 211 node_conditions_.Set(node, conditions); |
| 214 return Changed(node); | 212 return Changed(node); |
| 215 } | 213 } |
| 216 } | 214 } |
| 217 return NoChange(); | 215 return NoChange(); |
| 218 } | 216 } |
| 219 | 217 |
| 220 | 218 |
| 221 // static | 219 // static |
| 222 const BranchElimination::ControlPathConditions* | 220 const BranchElimination::ControlPathConditions* |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 304 | 302 |
| 305 Graph* BranchElimination::graph() const { return jsgraph()->graph(); } | 303 Graph* BranchElimination::graph() const { return jsgraph()->graph(); } |
| 306 | 304 |
| 307 CommonOperatorBuilder* BranchElimination::common() const { | 305 CommonOperatorBuilder* BranchElimination::common() const { |
| 308 return jsgraph()->common(); | 306 return jsgraph()->common(); |
| 309 } | 307 } |
| 310 | 308 |
| 311 } // namespace compiler | 309 } // namespace compiler |
| 312 } // namespace internal | 310 } // namespace internal |
| 313 } // namespace v8 | 311 } // namespace v8 |
| OLD | NEW |