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/code-factory.h" | 5 #include "src/code-factory.h" |
6 #include "src/compiler/access-builder.h" | 6 #include "src/compiler/access-builder.h" |
7 #include "src/compiler/js-graph.h" | 7 #include "src/compiler/js-graph.h" |
8 #include "src/compiler/js-typed-lowering.h" | 8 #include "src/compiler/js-typed-lowering.h" |
9 #include "src/compiler/linkage.h" | 9 #include "src/compiler/linkage.h" |
10 #include "src/compiler/node-matchers.h" | 10 #include "src/compiler/node-matchers.h" |
(...skipping 558 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
569 return NoChange(); | 569 return NoChange(); |
570 } | 570 } |
571 | 571 |
572 | 572 |
573 Reduction JSTypedLowering::ReduceJSStrictEqual(Node* node, bool invert) { | 573 Reduction JSTypedLowering::ReduceJSStrictEqual(Node* node, bool invert) { |
574 JSBinopReduction r(this, node); | 574 JSBinopReduction r(this, node); |
575 if (r.left() == r.right()) { | 575 if (r.left() == r.right()) { |
576 // x === x is always true if x != NaN | 576 // x === x is always true if x != NaN |
577 if (!r.left_type()->Maybe(Type::NaN())) { | 577 if (!r.left_type()->Maybe(Type::NaN())) { |
578 Node* replacement = jsgraph()->BooleanConstant(!invert); | 578 Node* replacement = jsgraph()->BooleanConstant(!invert); |
579 Replace(node, replacement); | 579 ReplaceWithValue(node, replacement); |
580 return Replace(replacement); | 580 return Replace(replacement); |
581 } | 581 } |
582 } | 582 } |
583 if (r.OneInputCannotBe(Type::NumberOrString())) { | 583 if (r.OneInputCannotBe(Type::NumberOrString())) { |
584 // For values with canonical representation (i.e. not string nor number) an | 584 // For values with canonical representation (i.e. not string nor number) an |
585 // empty type intersection means the values cannot be strictly equal. | 585 // empty type intersection means the values cannot be strictly equal. |
586 if (!r.left_type()->Maybe(r.right_type())) { | 586 if (!r.left_type()->Maybe(r.right_type())) { |
587 Node* replacement = jsgraph()->BooleanConstant(invert); | 587 Node* replacement = jsgraph()->BooleanConstant(invert); |
588 Replace(node, replacement); | 588 ReplaceWithValue(node, replacement); |
589 return Replace(replacement); | 589 return Replace(replacement); |
590 } | 590 } |
591 } | 591 } |
592 if (r.OneInputIs(Type::Undefined())) { | 592 if (r.OneInputIs(Type::Undefined())) { |
593 return r.ChangeToPureOperator( | 593 return r.ChangeToPureOperator( |
594 simplified()->ReferenceEqual(Type::Undefined()), invert); | 594 simplified()->ReferenceEqual(Type::Undefined()), invert); |
595 } | 595 } |
596 if (r.OneInputIs(Type::Null())) { | 596 if (r.OneInputIs(Type::Null())) { |
597 return r.ChangeToPureOperator(simplified()->ReferenceEqual(Type::Null()), | 597 return r.ChangeToPureOperator(simplified()->ReferenceEqual(Type::Null()), |
598 invert); | 598 invert); |
(...skipping 23 matching lines...) Expand all Loading... |
622 // TODO(turbofan): js-typed-lowering of StrictEqual(mixed types) | 622 // TODO(turbofan): js-typed-lowering of StrictEqual(mixed types) |
623 return NoChange(); | 623 return NoChange(); |
624 } | 624 } |
625 | 625 |
626 | 626 |
627 Reduction JSTypedLowering::ReduceJSUnaryNot(Node* node) { | 627 Reduction JSTypedLowering::ReduceJSUnaryNot(Node* node) { |
628 Node* const input = node->InputAt(0); | 628 Node* const input = node->InputAt(0); |
629 Type* const input_type = NodeProperties::GetType(input); | 629 Type* const input_type = NodeProperties::GetType(input); |
630 if (input_type->Is(Type::Boolean())) { | 630 if (input_type->Is(Type::Boolean())) { |
631 // JSUnaryNot(x:boolean) => BooleanNot(x) | 631 // JSUnaryNot(x:boolean) => BooleanNot(x) |
| 632 RelaxEffectsAndControls(node); |
632 node->TrimInputCount(1); | 633 node->TrimInputCount(1); |
633 NodeProperties::ChangeOp(node, simplified()->BooleanNot()); | 634 NodeProperties::ChangeOp(node, simplified()->BooleanNot()); |
634 return Changed(node); | 635 return Changed(node); |
635 } else if (input_type->Is(Type::OrderedNumber())) { | 636 } else if (input_type->Is(Type::OrderedNumber())) { |
636 // JSUnaryNot(x:number) => NumberEqual(x,#0) | 637 // JSUnaryNot(x:number) => NumberEqual(x,#0) |
| 638 RelaxEffectsAndControls(node); |
637 node->ReplaceInput(1, jsgraph()->ZeroConstant()); | 639 node->ReplaceInput(1, jsgraph()->ZeroConstant()); |
| 640 node->TrimInputCount(2); |
638 NodeProperties::ChangeOp(node, simplified()->NumberEqual()); | 641 NodeProperties::ChangeOp(node, simplified()->NumberEqual()); |
639 return Changed(node); | 642 return Changed(node); |
640 } else if (input_type->Is(Type::String())) { | 643 } else if (input_type->Is(Type::String())) { |
641 // JSUnaryNot(x:string) => NumberEqual(x.length,#0) | 644 // JSUnaryNot(x:string) => NumberEqual(x.length,#0) |
642 FieldAccess const access = AccessBuilder::ForStringLength(graph()->zone()); | 645 FieldAccess const access = AccessBuilder::ForStringLength(graph()->zone()); |
643 // It is safe for the load to be effect-free (i.e. not linked into effect | 646 // It is safe for the load to be effect-free (i.e. not linked into effect |
644 // chain) because we assume String::length to be immutable. | 647 // chain) because we assume String::length to be immutable. |
645 Node* length = graph()->NewNode(simplified()->LoadField(access), input, | 648 Node* length = graph()->NewNode(simplified()->LoadField(access), input, |
646 graph()->start(), graph()->start()); | 649 graph()->start(), graph()->start()); |
647 ReplaceWithValue(node, node, length); | 650 ReplaceWithValue(node, node, length); |
648 node->ReplaceInput(0, length); | 651 node->ReplaceInput(0, length); |
649 node->ReplaceInput(1, jsgraph()->ZeroConstant()); | 652 node->ReplaceInput(1, jsgraph()->ZeroConstant()); |
| 653 node->TrimInputCount(2); |
650 NodeProperties::ChangeOp(node, simplified()->NumberEqual()); | 654 NodeProperties::ChangeOp(node, simplified()->NumberEqual()); |
651 return Changed(node); | 655 return Changed(node); |
652 } | 656 } |
653 return NoChange(); | 657 return NoChange(); |
654 } | 658 } |
655 | 659 |
656 | 660 |
657 Reduction JSTypedLowering::ReduceJSToBoolean(Node* node) { | 661 Reduction JSTypedLowering::ReduceJSToBoolean(Node* node) { |
658 Node* const input = node->InputAt(0); | 662 Node* const input = node->InputAt(0); |
659 Type* const input_type = NodeProperties::GetType(input); | 663 Type* const input_type = NodeProperties::GetType(input); |
660 if (input_type->Is(Type::Boolean())) { | 664 if (input_type->Is(Type::Boolean())) { |
661 // JSToBoolean(x:boolean) => x | 665 // JSToBoolean(x:boolean) => x |
| 666 ReplaceWithValue(node, input); |
662 return Replace(input); | 667 return Replace(input); |
663 } else if (input_type->Is(Type::OrderedNumber())) { | 668 } else if (input_type->Is(Type::OrderedNumber())) { |
664 // JSToBoolean(x:ordered-number) => BooleanNot(NumberEqual(x,#0)) | 669 // JSToBoolean(x:ordered-number) => BooleanNot(NumberEqual(x,#0)) |
| 670 RelaxEffectsAndControls(node); |
665 node->ReplaceInput(0, graph()->NewNode(simplified()->NumberEqual(), input, | 671 node->ReplaceInput(0, graph()->NewNode(simplified()->NumberEqual(), input, |
666 jsgraph()->ZeroConstant())); | 672 jsgraph()->ZeroConstant())); |
667 node->TrimInputCount(1); | 673 node->TrimInputCount(1); |
668 NodeProperties::ChangeOp(node, simplified()->BooleanNot()); | 674 NodeProperties::ChangeOp(node, simplified()->BooleanNot()); |
669 return Changed(node); | 675 return Changed(node); |
670 } else if (input_type->Is(Type::String())) { | 676 } else if (input_type->Is(Type::String())) { |
671 // JSToBoolean(x:string) => NumberLessThan(#0,x.length) | 677 // JSToBoolean(x:string) => NumberLessThan(#0,x.length) |
672 FieldAccess const access = AccessBuilder::ForStringLength(graph()->zone()); | 678 FieldAccess const access = AccessBuilder::ForStringLength(graph()->zone()); |
673 // It is safe for the load to be effect-free (i.e. not linked into effect | 679 // It is safe for the load to be effect-free (i.e. not linked into effect |
674 // chain) because we assume String::length to be immutable. | 680 // chain) because we assume String::length to be immutable. |
675 Node* length = graph()->NewNode(simplified()->LoadField(access), input, | 681 Node* length = graph()->NewNode(simplified()->LoadField(access), input, |
676 graph()->start(), graph()->start()); | 682 graph()->start(), graph()->start()); |
| 683 ReplaceWithValue(node, node, length); |
677 node->ReplaceInput(0, jsgraph()->ZeroConstant()); | 684 node->ReplaceInput(0, jsgraph()->ZeroConstant()); |
678 node->ReplaceInput(1, length); | 685 node->ReplaceInput(1, length); |
| 686 node->TrimInputCount(2); |
679 NodeProperties::ChangeOp(node, simplified()->NumberLessThan()); | 687 NodeProperties::ChangeOp(node, simplified()->NumberLessThan()); |
680 return Changed(node); | 688 return Changed(node); |
681 } | 689 } |
682 return NoChange(); | 690 return NoChange(); |
683 } | 691 } |
684 | 692 |
685 | 693 |
686 Reduction JSTypedLowering::ReduceJSToNumberInput(Node* input) { | 694 Reduction JSTypedLowering::ReduceJSToNumberInput(Node* input) { |
687 if (input->opcode() == IrOpcode::kJSToNumber) { | 695 if (input->opcode() == IrOpcode::kJSToNumber) { |
688 // Recursively try to reduce the input first. | 696 // Recursively try to reduce the input first. |
(...skipping 1057 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1746 } | 1754 } |
1747 | 1755 |
1748 | 1756 |
1749 MachineOperatorBuilder* JSTypedLowering::machine() const { | 1757 MachineOperatorBuilder* JSTypedLowering::machine() const { |
1750 return jsgraph()->machine(); | 1758 return jsgraph()->machine(); |
1751 } | 1759 } |
1752 | 1760 |
1753 } // namespace compiler | 1761 } // namespace compiler |
1754 } // namespace internal | 1762 } // namespace internal |
1755 } // namespace v8 | 1763 } // namespace v8 |
OLD | NEW |