| 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 |