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