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 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
188 NodeProperties::ChangeOp(branch, common()->Dead()); | 188 NodeProperties::ChangeOp(branch, common()->Dead()); |
189 return Replace(control); | 189 return Replace(control); |
190 } | 190 } |
191 } | 191 } |
192 return NoChange(); | 192 return NoChange(); |
193 } | 193 } |
194 | 194 |
195 | 195 |
196 Reduction CommonOperatorReducer::ReduceEffectPhi(Node* node) { | 196 Reduction CommonOperatorReducer::ReduceEffectPhi(Node* node) { |
197 DCHECK_EQ(IrOpcode::kEffectPhi, node->opcode()); | 197 DCHECK_EQ(IrOpcode::kEffectPhi, node->opcode()); |
198 int const input_count = node->InputCount() - 1; | 198 Node::Inputs inputs = node->inputs(); |
199 DCHECK_LE(1, input_count); | 199 int const effect_input_count = inputs.count() - 1; |
200 Node* const merge = node->InputAt(input_count); | 200 DCHECK_LE(1, effect_input_count); |
| 201 Node* const merge = inputs[effect_input_count]; |
201 DCHECK(IrOpcode::IsMergeOpcode(merge->opcode())); | 202 DCHECK(IrOpcode::IsMergeOpcode(merge->opcode())); |
202 DCHECK_EQ(input_count, merge->InputCount()); | 203 DCHECK_EQ(effect_input_count, merge->InputCount()); |
203 Node* const effect = node->InputAt(0); | 204 Node* const effect = inputs[0]; |
204 DCHECK_NE(node, effect); | 205 DCHECK_NE(node, effect); |
205 for (int i = 1; i < input_count; ++i) { | 206 for (int i = 1; i < effect_input_count; ++i) { |
206 Node* const input = node->InputAt(i); | 207 Node* const input = inputs[i]; |
207 if (input == node) { | 208 if (input == node) { |
208 // Ignore redundant inputs. | 209 // Ignore redundant inputs. |
209 DCHECK_EQ(IrOpcode::kLoop, merge->opcode()); | 210 DCHECK_EQ(IrOpcode::kLoop, merge->opcode()); |
210 continue; | 211 continue; |
211 } | 212 } |
212 if (input != effect) return NoChange(); | 213 if (input != effect) return NoChange(); |
213 } | 214 } |
214 // We might now be able to further reduce the {merge} node. | 215 // We might now be able to further reduce the {merge} node. |
215 Revisit(merge); | 216 Revisit(merge); |
216 return Replace(effect); | 217 return Replace(effect); |
217 } | 218 } |
218 | 219 |
219 | 220 |
220 Reduction CommonOperatorReducer::ReducePhi(Node* node) { | 221 Reduction CommonOperatorReducer::ReducePhi(Node* node) { |
221 DCHECK_EQ(IrOpcode::kPhi, node->opcode()); | 222 DCHECK_EQ(IrOpcode::kPhi, node->opcode()); |
222 int const input_count = node->InputCount() - 1; | 223 Node::Inputs inputs = node->inputs(); |
223 DCHECK_LE(1, input_count); | 224 int const value_input_count = inputs.count() - 1; |
224 Node* const merge = node->InputAt(input_count); | 225 DCHECK_LE(1, value_input_count); |
| 226 Node* const merge = inputs[value_input_count]; |
225 DCHECK(IrOpcode::IsMergeOpcode(merge->opcode())); | 227 DCHECK(IrOpcode::IsMergeOpcode(merge->opcode())); |
226 DCHECK_EQ(input_count, merge->InputCount()); | 228 DCHECK_EQ(value_input_count, merge->InputCount()); |
227 if (input_count == 2) { | 229 if (value_input_count == 2) { |
228 Node* vtrue = node->InputAt(0); | 230 Node* vtrue = inputs[0]; |
229 Node* vfalse = node->InputAt(1); | 231 Node* vfalse = inputs[1]; |
230 Node* if_true = merge->InputAt(0); | 232 Node::Inputs merge_inputs = merge->inputs(); |
231 Node* if_false = merge->InputAt(1); | 233 Node* if_true = merge_inputs[0]; |
| 234 Node* if_false = merge_inputs[1]; |
232 if (if_true->opcode() != IrOpcode::kIfTrue) { | 235 if (if_true->opcode() != IrOpcode::kIfTrue) { |
233 std::swap(if_true, if_false); | 236 std::swap(if_true, if_false); |
234 std::swap(vtrue, vfalse); | 237 std::swap(vtrue, vfalse); |
235 } | 238 } |
236 if (if_true->opcode() == IrOpcode::kIfTrue && | 239 if (if_true->opcode() == IrOpcode::kIfTrue && |
237 if_false->opcode() == IrOpcode::kIfFalse && | 240 if_false->opcode() == IrOpcode::kIfFalse && |
238 if_true->InputAt(0) == if_false->InputAt(0)) { | 241 if_true->InputAt(0) == if_false->InputAt(0)) { |
239 Node* const branch = if_true->InputAt(0); | 242 Node* const branch = if_true->InputAt(0); |
240 // Check that the branch is not dead already. | 243 // Check that the branch is not dead already. |
241 if (branch->opcode() != IrOpcode::kBranch) return NoChange(); | 244 if (branch->opcode() != IrOpcode::kBranch) return NoChange(); |
(...skipping 16 matching lines...) Expand all Loading... |
258 Float64BinopMatcher mvfalse(vfalse); | 261 Float64BinopMatcher mvfalse(vfalse); |
259 if (mvfalse.left().IsZero() && mvfalse.right().Equals(vtrue)) { | 262 if (mvfalse.left().IsZero() && mvfalse.right().Equals(vtrue)) { |
260 // We might now be able to further reduce the {merge} node. | 263 // We might now be able to further reduce the {merge} node. |
261 Revisit(merge); | 264 Revisit(merge); |
262 return Change(node, machine()->Float64Abs(), vtrue); | 265 return Change(node, machine()->Float64Abs(), vtrue); |
263 } | 266 } |
264 } | 267 } |
265 } | 268 } |
266 } | 269 } |
267 } | 270 } |
268 Node* const value = node->InputAt(0); | 271 Node* const value = inputs[0]; |
269 DCHECK_NE(node, value); | 272 DCHECK_NE(node, value); |
270 for (int i = 1; i < input_count; ++i) { | 273 for (int i = 1; i < value_input_count; ++i) { |
271 Node* const input = node->InputAt(i); | 274 Node* const input = inputs[i]; |
272 if (input == node) { | 275 if (input == node) { |
273 // Ignore redundant inputs. | 276 // Ignore redundant inputs. |
274 DCHECK_EQ(IrOpcode::kLoop, merge->opcode()); | 277 DCHECK_EQ(IrOpcode::kLoop, merge->opcode()); |
275 continue; | 278 continue; |
276 } | 279 } |
277 if (input != value) return NoChange(); | 280 if (input != value) return NoChange(); |
278 } | 281 } |
279 // We might now be able to further reduce the {merge} node. | 282 // We might now be able to further reduce the {merge} node. |
280 Revisit(merge); | 283 Revisit(merge); |
281 return Replace(value); | 284 return Replace(value); |
(...skipping 11 matching lines...) Expand all Loading... |
293 // hence checkpoints can be cut out of the effect chain flowing into it. | 296 // hence checkpoints can be cut out of the effect chain flowing into it. |
294 effect = NodeProperties::GetEffectInput(effect); | 297 effect = NodeProperties::GetEffectInput(effect); |
295 NodeProperties::ReplaceEffectInput(node, effect); | 298 NodeProperties::ReplaceEffectInput(node, effect); |
296 changed = true; | 299 changed = true; |
297 } | 300 } |
298 if (value->opcode() == IrOpcode::kPhi && | 301 if (value->opcode() == IrOpcode::kPhi && |
299 NodeProperties::GetControlInput(value) == control && | 302 NodeProperties::GetControlInput(value) == control && |
300 effect->opcode() == IrOpcode::kEffectPhi && | 303 effect->opcode() == IrOpcode::kEffectPhi && |
301 NodeProperties::GetControlInput(effect) == control && | 304 NodeProperties::GetControlInput(effect) == control && |
302 control->opcode() == IrOpcode::kMerge) { | 305 control->opcode() == IrOpcode::kMerge) { |
303 int const control_input_count = control->InputCount(); | 306 Node::Inputs control_inputs = control->inputs(); |
304 DCHECK_NE(0, control_input_count); | 307 Node::Inputs value_inputs = value->inputs(); |
305 DCHECK_EQ(control_input_count, value->InputCount() - 1); | 308 Node::Inputs effect_inputs = effect->inputs(); |
306 DCHECK_EQ(control_input_count, effect->InputCount() - 1); | 309 DCHECK_NE(0, control_inputs.count()); |
| 310 DCHECK_EQ(control_inputs.count(), value_inputs.count() - 1); |
| 311 DCHECK_EQ(control_inputs.count(), effect_inputs.count() - 1); |
307 DCHECK_EQ(IrOpcode::kEnd, graph()->end()->opcode()); | 312 DCHECK_EQ(IrOpcode::kEnd, graph()->end()->opcode()); |
308 DCHECK_NE(0, graph()->end()->InputCount()); | 313 DCHECK_NE(0, graph()->end()->InputCount()); |
309 for (int i = 0; i < control_input_count; ++i) { | 314 for (int i = 0; i < control_inputs.count(); ++i) { |
310 // Create a new {Return} and connect it to {end}. We don't need to mark | 315 // Create a new {Return} and connect it to {end}. We don't need to mark |
311 // {end} as revisit, because we mark {node} as {Dead} below, which was | 316 // {end} as revisit, because we mark {node} as {Dead} below, which was |
312 // previously connected to {end}, so we know for sure that at some point | 317 // previously connected to {end}, so we know for sure that at some point |
313 // the reducer logic will visit {end} again. | 318 // the reducer logic will visit {end} again. |
314 Node* ret = graph()->NewNode(common()->Return(), node->InputAt(0), | 319 Node* ret = graph()->NewNode(common()->Return(), node->InputAt(0), |
315 value->InputAt(i), effect->InputAt(i), | 320 value_inputs[i], effect_inputs[i], |
316 control->InputAt(i)); | 321 control_inputs[i]); |
317 NodeProperties::MergeControlToEnd(graph(), common(), ret); | 322 NodeProperties::MergeControlToEnd(graph(), common(), ret); |
318 } | 323 } |
319 // Mark the merge {control} and return {node} as {dead}. | 324 // Mark the merge {control} and return {node} as {dead}. |
320 Replace(control, dead()); | 325 Replace(control, dead()); |
321 return Replace(dead()); | 326 return Replace(dead()); |
322 } | 327 } |
323 return changed ? Changed(node) : NoChange(); | 328 return changed ? Changed(node) : NoChange(); |
324 } | 329 } |
325 | 330 |
326 | 331 |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
382 node->ReplaceInput(0, a); | 387 node->ReplaceInput(0, a); |
383 node->ReplaceInput(1, b); | 388 node->ReplaceInput(1, b); |
384 node->TrimInputCount(2); | 389 node->TrimInputCount(2); |
385 NodeProperties::ChangeOp(node, op); | 390 NodeProperties::ChangeOp(node, op); |
386 return Changed(node); | 391 return Changed(node); |
387 } | 392 } |
388 | 393 |
389 } // namespace compiler | 394 } // namespace compiler |
390 } // namespace internal | 395 } // namespace internal |
391 } // namespace v8 | 396 } // namespace v8 |
OLD | NEW |