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/graph-inl.h" | 5 #include "src/compiler/graph-inl.h" |
6 #include "src/compiler/js-typed-lowering.h" | 6 #include "src/compiler/js-typed-lowering.h" |
7 #include "src/compiler/node-aux-data-inl.h" | 7 #include "src/compiler/node-aux-data-inl.h" |
8 #include "src/compiler/node-properties-inl.h" | 8 #include "src/compiler/node-properties-inl.h" |
9 #include "src/types.h" | 9 #include "src/types.h" |
10 | 10 |
11 namespace v8 { | 11 namespace v8 { |
12 namespace internal { | 12 namespace internal { |
13 namespace compiler { | 13 namespace compiler { |
14 | 14 |
15 // TODO(turbofan): js-typed-lowering improvements possible | 15 // TODO(turbofan): js-typed-lowering improvements possible |
16 // - immediately put in type bounds for all new nodes | 16 // - immediately put in type bounds for all new nodes |
17 // - relax effects from generic but not-side-effecting operations | 17 // - relax effects from generic but not-side-effecting operations |
18 // - relax effects for ToNumber(mixed) | 18 // - relax effects for ToNumber(mixed) |
19 | 19 |
| 20 // Replace value uses of {node} with {value} and effect uses of {node} with |
| 21 // {effect}. If {effect == NULL}, then use the effect input to {node}. |
| 22 // TODO(titzer): move into a GraphEditor? |
| 23 static void ReplaceUses(Node* node, Node* value, Node* effect) { |
| 24 if (value == effect) { |
| 25 // Effect and value updates are the same; no special iteration needed. |
| 26 if (value != node) node->ReplaceUses(value); |
| 27 return; |
| 28 } |
| 29 |
| 30 if (effect == NULL) effect = NodeProperties::GetEffectInput(node); |
| 31 |
| 32 // The iteration requires distinguishing between value and effect edges. |
| 33 UseIter iter = node->uses().begin(); |
| 34 while (iter != node->uses().end()) { |
| 35 if (NodeProperties::IsEffectEdge(iter.edge())) { |
| 36 iter = iter.UpdateToAndIncrement(effect); |
| 37 } else { |
| 38 iter = iter.UpdateToAndIncrement(value); |
| 39 } |
| 40 } |
| 41 } |
| 42 |
20 | 43 |
21 // Relax the effects of {node} by immediately replacing effect uses of {node} | 44 // Relax the effects of {node} by immediately replacing effect uses of {node} |
22 // with the effect input to {node}. | 45 // with the effect input to {node}. |
23 // TODO(turbofan): replace the effect input to {node} with {graph->start()}. | 46 // TODO(turbofan): replace the effect input to {node} with {graph->start()}. |
24 // TODO(titzer): move into a GraphEditor? | 47 // TODO(titzer): move into a GraphEditor? |
25 static void RelaxEffects(Node* node) { | 48 static void RelaxEffects(Node* node) { ReplaceUses(node, node, NULL); } |
26 NodeProperties::ReplaceWithValue(node, node, NULL); | |
27 } | |
28 | 49 |
29 | 50 |
30 Reduction JSTypedLowering::ReplaceEagerly(Node* old, Node* node) { | 51 Reduction JSTypedLowering::ReplaceEagerly(Node* old, Node* node) { |
31 NodeProperties::ReplaceWithValue(old, node, node); | 52 ReplaceUses(old, node, node); |
32 return Reducer::Changed(node); | 53 return Reducer::Changed(node); |
33 } | 54 } |
34 | 55 |
35 | 56 |
36 // A helper class to simplify the process of reducing a single binop node with a | 57 // A helper class to simplify the process of reducing a single binop node with a |
37 // JSOperator. This class manages the rewriting of context, control, and effect | 58 // JSOperator. This class manages the rewriting of context, control, and effect |
38 // dependencies during lowering of a binop and contains numerous helper | 59 // dependencies during lowering of a binop and contains numerous helper |
39 // functions for matching the types of inputs to an operation. | 60 // functions for matching the types of inputs to an operation. |
40 class JSBinopReduction { | 61 class JSBinopReduction { |
41 public: | 62 public: |
(...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
494 cmp->ReplaceInput(0, input); | 515 cmp->ReplaceInput(0, input); |
495 return Changed(inv); | 516 return Changed(inv); |
496 } | 517 } |
497 // TODO(turbofan): js-typed-lowering of ToBoolean(string) | 518 // TODO(turbofan): js-typed-lowering of ToBoolean(string) |
498 return NoChange(); | 519 return NoChange(); |
499 } | 520 } |
500 | 521 |
501 | 522 |
502 static Reduction ReplaceWithReduction(Node* node, Reduction reduction) { | 523 static Reduction ReplaceWithReduction(Node* node, Reduction reduction) { |
503 if (reduction.Changed()) { | 524 if (reduction.Changed()) { |
504 NodeProperties::ReplaceWithValue(node, reduction.replacement()); | 525 ReplaceUses(node, reduction.replacement(), NULL); |
505 return reduction; | 526 return reduction; |
506 } | 527 } |
507 return Reducer::NoChange(); | 528 return Reducer::NoChange(); |
508 } | 529 } |
509 | 530 |
510 | 531 |
511 Reduction JSTypedLowering::Reduce(Node* node) { | 532 Reduction JSTypedLowering::Reduce(Node* node) { |
512 switch (node->opcode()) { | 533 switch (node->opcode()) { |
513 case IrOpcode::kJSEqual: | 534 case IrOpcode::kJSEqual: |
514 return ReduceJSEqual(node, false); | 535 return ReduceJSEqual(node, false); |
(...skipping 30 matching lines...) Expand all Loading... |
545 return ReduceNumberBinop(node, simplified()->NumberDivide()); | 566 return ReduceNumberBinop(node, simplified()->NumberDivide()); |
546 case IrOpcode::kJSModulus: | 567 case IrOpcode::kJSModulus: |
547 return ReduceNumberBinop(node, simplified()->NumberModulus()); | 568 return ReduceNumberBinop(node, simplified()->NumberModulus()); |
548 case IrOpcode::kJSUnaryNot: { | 569 case IrOpcode::kJSUnaryNot: { |
549 Reduction result = ReduceJSToBooleanInput(node->InputAt(0)); | 570 Reduction result = ReduceJSToBooleanInput(node->InputAt(0)); |
550 Node* value; | 571 Node* value; |
551 if (result.Changed()) { | 572 if (result.Changed()) { |
552 // !x => BooleanNot(x) | 573 // !x => BooleanNot(x) |
553 value = | 574 value = |
554 graph()->NewNode(simplified()->BooleanNot(), result.replacement()); | 575 graph()->NewNode(simplified()->BooleanNot(), result.replacement()); |
555 NodeProperties::ReplaceWithValue(node, value); | 576 ReplaceUses(node, value, NULL); |
556 return Changed(value); | 577 return Changed(value); |
557 } else { | 578 } else { |
558 // !x => BooleanNot(JSToBoolean(x)) | 579 // !x => BooleanNot(JSToBoolean(x)) |
559 value = graph()->NewNode(simplified()->BooleanNot(), node); | 580 value = graph()->NewNode(simplified()->BooleanNot(), node); |
560 node->set_op(javascript()->ToBoolean()); | 581 node->set_op(javascript()->ToBoolean()); |
561 NodeProperties::ReplaceWithValue(node, value, node); | 582 ReplaceUses(node, value, node); |
562 // Note: ReplaceUses() smashes all uses, so smash it back here. | 583 // Note: ReplaceUses() smashes all uses, so smash it back here. |
563 value->ReplaceInput(0, node); | 584 value->ReplaceInput(0, node); |
564 return ReplaceWith(value); | 585 return ReplaceWith(value); |
565 } | 586 } |
566 } | 587 } |
567 case IrOpcode::kJSToBoolean: | 588 case IrOpcode::kJSToBoolean: |
568 return ReplaceWithReduction(node, | 589 return ReplaceWithReduction(node, |
569 ReduceJSToBooleanInput(node->InputAt(0))); | 590 ReduceJSToBooleanInput(node->InputAt(0))); |
570 case IrOpcode::kJSToNumber: | 591 case IrOpcode::kJSToNumber: |
571 return ReplaceWithReduction(node, | 592 return ReplaceWithReduction(node, |
572 ReduceJSToNumberInput(node->InputAt(0))); | 593 ReduceJSToNumberInput(node->InputAt(0))); |
573 case IrOpcode::kJSToString: | 594 case IrOpcode::kJSToString: |
574 return ReplaceWithReduction(node, | 595 return ReplaceWithReduction(node, |
575 ReduceJSToStringInput(node->InputAt(0))); | 596 ReduceJSToStringInput(node->InputAt(0))); |
576 default: | 597 default: |
577 break; | 598 break; |
578 } | 599 } |
579 return NoChange(); | 600 return NoChange(); |
580 } | 601 } |
581 } | 602 } |
582 } | 603 } |
583 } // namespace v8::internal::compiler | 604 } // namespace v8::internal::compiler |
OLD | NEW |