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 |