OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 719 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
730 HType type() const { return type_; } | 730 HType type() const { return type_; } |
731 void set_type(HType new_type) { | 731 void set_type(HType new_type) { |
732 ASSERT(new_type.IsSubtypeOf(type_)); | 732 ASSERT(new_type.IsSubtypeOf(type_)); |
733 type_ = new_type; | 733 type_ = new_type; |
734 } | 734 } |
735 | 735 |
736 bool IsHeapObject() { | 736 bool IsHeapObject() { |
737 return representation_.IsHeapObject() || type_.IsHeapObject(); | 737 return representation_.IsHeapObject() || type_.IsHeapObject(); |
738 } | 738 } |
739 | 739 |
740 // An operation needs to override this function iff: | |
741 // 1) it can produce an int32 output. | |
742 // 2) the true value of its output can potentially be minus zero. | |
743 // The implementation must set a flag so that it bails out in the case where | |
744 // it would otherwise output what should be a minus zero as an int32 zero. | |
745 // If the operation also exists in a form that takes int32 and outputs int32 | |
746 // then the operation should return its input value so that we can propagate | |
747 // back. There are three operations that need to propagate back to more than | |
748 // one input. They are phi and binary div and mul. They always return NULL | |
749 // and expect the caller to take care of things. | |
750 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited) { | |
751 visited->Add(id()); | |
752 return NULL; | |
753 } | |
754 | |
755 // There are HInstructions that do not really change a value, they | 740 // There are HInstructions that do not really change a value, they |
756 // only add pieces of information to it (like bounds checks, map checks, | 741 // only add pieces of information to it (like bounds checks, map checks, |
757 // smi checks...). | 742 // smi checks...). |
758 // We call these instructions "informative definitions", or "iDef". | 743 // We call these instructions "informative definitions", or "iDef". |
759 // One of the iDef operands is special because it is the value that is | 744 // One of the iDef operands is special because it is the value that is |
760 // "transferred" to the output, we call it the "redefined operand". | 745 // "transferred" to the output, we call it the "redefined operand". |
761 // If an HValue is an iDef it must override RedefinedOperandIndex() so that | 746 // If an HValue is an iDef it must override RedefinedOperandIndex() so that |
762 // it does not return kNoRedefinedOperand; | 747 // it does not return kNoRedefinedOperand; |
763 static const int kNoRedefinedOperand = -1; | 748 static const int kNoRedefinedOperand = -1; |
764 virtual int RedefinedOperandIndex() { return kNoRedefinedOperand; } | 749 virtual int RedefinedOperandIndex() { return kNoRedefinedOperand; } |
(...skipping 945 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1710 }; | 1695 }; |
1711 | 1696 |
1712 | 1697 |
1713 class HForceRepresentation V8_FINAL : public HTemplateInstruction<1> { | 1698 class HForceRepresentation V8_FINAL : public HTemplateInstruction<1> { |
1714 public: | 1699 public: |
1715 static HInstruction* New(Zone* zone, HValue* context, HValue* value, | 1700 static HInstruction* New(Zone* zone, HValue* context, HValue* value, |
1716 Representation required_representation); | 1701 Representation required_representation); |
1717 | 1702 |
1718 HValue* value() { return OperandAt(0); } | 1703 HValue* value() { return OperandAt(0); } |
1719 | 1704 |
1720 virtual HValue* EnsureAndPropagateNotMinusZero( | |
1721 BitVector* visited) V8_OVERRIDE; | |
1722 | |
1723 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { | 1705 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { |
1724 return representation(); // Same as the output representation. | 1706 return representation(); // Same as the output representation. |
1725 } | 1707 } |
1726 | 1708 |
1727 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; | 1709 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; |
1728 | 1710 |
1729 DECLARE_CONCRETE_INSTRUCTION(ForceRepresentation) | 1711 DECLARE_CONCRETE_INSTRUCTION(ForceRepresentation) |
1730 | 1712 |
1731 private: | 1713 private: |
1732 HForceRepresentation(HValue* value, Representation required_representation) { | 1714 HForceRepresentation(HValue* value, Representation required_representation) { |
(...skipping 25 matching lines...) Expand all Loading... |
1758 } else { | 1740 } else { |
1759 set_type(HType::TaggedNumber()); | 1741 set_type(HType::TaggedNumber()); |
1760 if (to.IsTagged()) SetChangesFlag(kNewSpacePromotion); | 1742 if (to.IsTagged()) SetChangesFlag(kNewSpacePromotion); |
1761 } | 1743 } |
1762 } | 1744 } |
1763 | 1745 |
1764 bool can_convert_undefined_to_nan() { | 1746 bool can_convert_undefined_to_nan() { |
1765 return CheckUsesForFlag(kAllowUndefinedAsNaN); | 1747 return CheckUsesForFlag(kAllowUndefinedAsNaN); |
1766 } | 1748 } |
1767 | 1749 |
1768 virtual HValue* EnsureAndPropagateNotMinusZero( | |
1769 BitVector* visited) V8_OVERRIDE; | |
1770 virtual HType CalculateInferredType() V8_OVERRIDE; | 1750 virtual HType CalculateInferredType() V8_OVERRIDE; |
1771 virtual HValue* Canonicalize() V8_OVERRIDE; | 1751 virtual HValue* Canonicalize() V8_OVERRIDE; |
1772 | 1752 |
1773 Representation from() const { return value()->representation(); } | 1753 Representation from() const { return value()->representation(); } |
1774 Representation to() const { return representation(); } | 1754 Representation to() const { return representation(); } |
1775 bool deoptimize_on_minus_zero() const { | 1755 bool deoptimize_on_minus_zero() const { |
1776 return CheckFlag(kBailoutOnMinusZero); | 1756 return CheckFlag(kBailoutOnMinusZero); |
1777 } | 1757 } |
1778 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { | 1758 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { |
1779 return from(); | 1759 return from(); |
(...skipping 783 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2563 static HInstruction* New(Zone* zone, | 2543 static HInstruction* New(Zone* zone, |
2564 HValue* context, | 2544 HValue* context, |
2565 HValue* value, | 2545 HValue* value, |
2566 BuiltinFunctionId op); | 2546 BuiltinFunctionId op); |
2567 | 2547 |
2568 HValue* context() { return OperandAt(0); } | 2548 HValue* context() { return OperandAt(0); } |
2569 HValue* value() { return OperandAt(1); } | 2549 HValue* value() { return OperandAt(1); } |
2570 | 2550 |
2571 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; | 2551 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; |
2572 | 2552 |
2573 virtual HValue* EnsureAndPropagateNotMinusZero( | |
2574 BitVector* visited) V8_OVERRIDE; | |
2575 | |
2576 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { | 2553 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { |
2577 if (index == 0) { | 2554 if (index == 0) { |
2578 return Representation::Tagged(); | 2555 return Representation::Tagged(); |
2579 } else { | 2556 } else { |
2580 switch (op_) { | 2557 switch (op_) { |
2581 case kMathFloor: | 2558 case kMathFloor: |
2582 case kMathRound: | 2559 case kMathRound: |
2583 case kMathSqrt: | 2560 case kMathSqrt: |
2584 case kMathPowHalf: | 2561 case kMathPowHalf: |
2585 case kMathLog: | 2562 case kMathLog: |
(...skipping 1451 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4037 virtual bool IsDeletable() const V8_OVERRIDE { return true; } | 4014 virtual bool IsDeletable() const V8_OVERRIDE { return true; } |
4038 }; | 4015 }; |
4039 | 4016 |
4040 | 4017 |
4041 class HMathFloorOfDiv V8_FINAL : public HBinaryOperation { | 4018 class HMathFloorOfDiv V8_FINAL : public HBinaryOperation { |
4042 public: | 4019 public: |
4043 DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HMathFloorOfDiv, | 4020 DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HMathFloorOfDiv, |
4044 HValue*, | 4021 HValue*, |
4045 HValue*); | 4022 HValue*); |
4046 | 4023 |
4047 virtual HValue* EnsureAndPropagateNotMinusZero( | |
4048 BitVector* visited) V8_OVERRIDE; | |
4049 | |
4050 DECLARE_CONCRETE_INSTRUCTION(MathFloorOfDiv) | 4024 DECLARE_CONCRETE_INSTRUCTION(MathFloorOfDiv) |
4051 | 4025 |
4052 protected: | 4026 protected: |
4053 virtual bool DataEquals(HValue* other) V8_OVERRIDE { return true; } | 4027 virtual bool DataEquals(HValue* other) V8_OVERRIDE { return true; } |
4054 | 4028 |
4055 private: | 4029 private: |
4056 HMathFloorOfDiv(HValue* context, HValue* left, HValue* right) | 4030 HMathFloorOfDiv(HValue* context, HValue* left, HValue* right) |
4057 : HBinaryOperation(context, left, right) { | 4031 : HBinaryOperation(context, left, right) { |
4058 set_representation(Representation::Integer32()); | 4032 set_representation(Representation::Integer32()); |
4059 SetFlag(kUseGVN); | 4033 SetFlag(kUseGVN); |
(...skipping 586 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4646 HValue* left, | 4620 HValue* left, |
4647 HValue* right); | 4621 HValue* right); |
4648 | 4622 |
4649 // Add is only commutative if two integer values are added and not if two | 4623 // Add is only commutative if two integer values are added and not if two |
4650 // tagged values are added (because it might be a String concatenation). | 4624 // tagged values are added (because it might be a String concatenation). |
4651 // We also do not commute (pointer + offset). | 4625 // We also do not commute (pointer + offset). |
4652 virtual bool IsCommutative() const V8_OVERRIDE { | 4626 virtual bool IsCommutative() const V8_OVERRIDE { |
4653 return !representation().IsTagged() && !representation().IsExternal(); | 4627 return !representation().IsTagged() && !representation().IsExternal(); |
4654 } | 4628 } |
4655 | 4629 |
4656 virtual HValue* EnsureAndPropagateNotMinusZero( | |
4657 BitVector* visited) V8_OVERRIDE; | |
4658 | |
4659 virtual HValue* Canonicalize() V8_OVERRIDE; | 4630 virtual HValue* Canonicalize() V8_OVERRIDE; |
4660 | 4631 |
4661 virtual bool TryDecompose(DecompositionResult* decomposition) V8_OVERRIDE { | 4632 virtual bool TryDecompose(DecompositionResult* decomposition) V8_OVERRIDE { |
4662 if (left()->IsInteger32Constant()) { | 4633 if (left()->IsInteger32Constant()) { |
4663 decomposition->Apply(right(), left()->GetInteger32Constant()); | 4634 decomposition->Apply(right(), left()->GetInteger32Constant()); |
4664 return true; | 4635 return true; |
4665 } else if (right()->IsInteger32Constant()) { | 4636 } else if (right()->IsInteger32Constant()) { |
4666 decomposition->Apply(left(), right()->GetInteger32Constant()); | 4637 decomposition->Apply(left(), right()->GetInteger32Constant()); |
4667 return true; | 4638 return true; |
4668 } else { | 4639 } else { |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4705 }; | 4676 }; |
4706 | 4677 |
4707 | 4678 |
4708 class HSub V8_FINAL : public HArithmeticBinaryOperation { | 4679 class HSub V8_FINAL : public HArithmeticBinaryOperation { |
4709 public: | 4680 public: |
4710 static HInstruction* New(Zone* zone, | 4681 static HInstruction* New(Zone* zone, |
4711 HValue* context, | 4682 HValue* context, |
4712 HValue* left, | 4683 HValue* left, |
4713 HValue* right); | 4684 HValue* right); |
4714 | 4685 |
4715 virtual HValue* EnsureAndPropagateNotMinusZero( | |
4716 BitVector* visited) V8_OVERRIDE; | |
4717 | |
4718 virtual HValue* Canonicalize() V8_OVERRIDE; | 4686 virtual HValue* Canonicalize() V8_OVERRIDE; |
4719 | 4687 |
4720 virtual bool TryDecompose(DecompositionResult* decomposition) V8_OVERRIDE { | 4688 virtual bool TryDecompose(DecompositionResult* decomposition) V8_OVERRIDE { |
4721 if (right()->IsInteger32Constant()) { | 4689 if (right()->IsInteger32Constant()) { |
4722 decomposition->Apply(left(), -right()->GetInteger32Constant()); | 4690 decomposition->Apply(left(), -right()->GetInteger32Constant()); |
4723 return true; | 4691 return true; |
4724 } else { | 4692 } else { |
4725 return false; | 4693 return false; |
4726 } | 4694 } |
4727 } | 4695 } |
(...skipping 26 matching lines...) Expand all Loading... |
4754 HValue* right) { | 4722 HValue* right) { |
4755 HInstruction* instr = HMul::New(zone, context, left, right); | 4723 HInstruction* instr = HMul::New(zone, context, left, right); |
4756 if (!instr->IsMul()) return instr; | 4724 if (!instr->IsMul()) return instr; |
4757 HMul* mul = HMul::cast(instr); | 4725 HMul* mul = HMul::cast(instr); |
4758 // TODO(mstarzinger): Prevent bailout on minus zero for imul. | 4726 // TODO(mstarzinger): Prevent bailout on minus zero for imul. |
4759 mul->AssumeRepresentation(Representation::Integer32()); | 4727 mul->AssumeRepresentation(Representation::Integer32()); |
4760 mul->ClearFlag(HValue::kCanOverflow); | 4728 mul->ClearFlag(HValue::kCanOverflow); |
4761 return mul; | 4729 return mul; |
4762 } | 4730 } |
4763 | 4731 |
4764 virtual HValue* EnsureAndPropagateNotMinusZero( | |
4765 BitVector* visited) V8_OVERRIDE; | |
4766 | |
4767 virtual HValue* Canonicalize() V8_OVERRIDE; | 4732 virtual HValue* Canonicalize() V8_OVERRIDE; |
4768 | 4733 |
4769 // Only commutative if it is certain that not two objects are multiplicated. | 4734 // Only commutative if it is certain that not two objects are multiplicated. |
4770 virtual bool IsCommutative() const V8_OVERRIDE { | 4735 virtual bool IsCommutative() const V8_OVERRIDE { |
4771 return !representation().IsTagged(); | 4736 return !representation().IsTagged(); |
4772 } | 4737 } |
4773 | 4738 |
4774 virtual void UpdateRepresentation(Representation new_rep, | 4739 virtual void UpdateRepresentation(Representation new_rep, |
4775 HInferRepresentationPhase* h_infer, | 4740 HInferRepresentationPhase* h_infer, |
4776 const char* reason) V8_OVERRIDE { | 4741 const char* reason) V8_OVERRIDE { |
(...skipping 17 matching lines...) Expand all Loading... |
4794 }; | 4759 }; |
4795 | 4760 |
4796 | 4761 |
4797 class HMod V8_FINAL : public HArithmeticBinaryOperation { | 4762 class HMod V8_FINAL : public HArithmeticBinaryOperation { |
4798 public: | 4763 public: |
4799 static HInstruction* New(Zone* zone, | 4764 static HInstruction* New(Zone* zone, |
4800 HValue* context, | 4765 HValue* context, |
4801 HValue* left, | 4766 HValue* left, |
4802 HValue* right); | 4767 HValue* right); |
4803 | 4768 |
4804 virtual HValue* EnsureAndPropagateNotMinusZero( | |
4805 BitVector* visited) V8_OVERRIDE; | |
4806 | |
4807 virtual HValue* Canonicalize() V8_OVERRIDE; | 4769 virtual HValue* Canonicalize() V8_OVERRIDE; |
4808 | 4770 |
4809 virtual void UpdateRepresentation(Representation new_rep, | 4771 virtual void UpdateRepresentation(Representation new_rep, |
4810 HInferRepresentationPhase* h_infer, | 4772 HInferRepresentationPhase* h_infer, |
4811 const char* reason) V8_OVERRIDE { | 4773 const char* reason) V8_OVERRIDE { |
4812 if (new_rep.IsSmi()) new_rep = Representation::Integer32(); | 4774 if (new_rep.IsSmi()) new_rep = Representation::Integer32(); |
4813 HArithmeticBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason); | 4775 HArithmeticBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason); |
4814 } | 4776 } |
4815 | 4777 |
4816 DECLARE_CONCRETE_INSTRUCTION(Mod) | 4778 DECLARE_CONCRETE_INSTRUCTION(Mod) |
(...skipping 13 matching lines...) Expand all Loading... |
4830 }; | 4792 }; |
4831 | 4793 |
4832 | 4794 |
4833 class HDiv V8_FINAL : public HArithmeticBinaryOperation { | 4795 class HDiv V8_FINAL : public HArithmeticBinaryOperation { |
4834 public: | 4796 public: |
4835 static HInstruction* New(Zone* zone, | 4797 static HInstruction* New(Zone* zone, |
4836 HValue* context, | 4798 HValue* context, |
4837 HValue* left, | 4799 HValue* left, |
4838 HValue* right); | 4800 HValue* right); |
4839 | 4801 |
4840 virtual HValue* EnsureAndPropagateNotMinusZero( | |
4841 BitVector* visited) V8_OVERRIDE; | |
4842 | |
4843 virtual HValue* Canonicalize() V8_OVERRIDE; | 4802 virtual HValue* Canonicalize() V8_OVERRIDE; |
4844 | 4803 |
4845 virtual void UpdateRepresentation(Representation new_rep, | 4804 virtual void UpdateRepresentation(Representation new_rep, |
4846 HInferRepresentationPhase* h_infer, | 4805 HInferRepresentationPhase* h_infer, |
4847 const char* reason) V8_OVERRIDE { | 4806 const char* reason) V8_OVERRIDE { |
4848 if (new_rep.IsSmi()) new_rep = Representation::Integer32(); | 4807 if (new_rep.IsSmi()) new_rep = Representation::Integer32(); |
4849 HArithmeticBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason); | 4808 HArithmeticBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason); |
4850 } | 4809 } |
4851 | 4810 |
4852 DECLARE_CONCRETE_INSTRUCTION(Div) | 4811 DECLARE_CONCRETE_INSTRUCTION(Div) |
(...skipping 2632 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7485 virtual bool IsDeletable() const V8_OVERRIDE { return true; } | 7444 virtual bool IsDeletable() const V8_OVERRIDE { return true; } |
7486 }; | 7445 }; |
7487 | 7446 |
7488 | 7447 |
7489 #undef DECLARE_INSTRUCTION | 7448 #undef DECLARE_INSTRUCTION |
7490 #undef DECLARE_CONCRETE_INSTRUCTION | 7449 #undef DECLARE_CONCRETE_INSTRUCTION |
7491 | 7450 |
7492 } } // namespace v8::internal | 7451 } } // namespace v8::internal |
7493 | 7452 |
7494 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ | 7453 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ |
OLD | NEW |