| 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 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 288 } | 288 } |
| 289 | 289 |
| 290 void Intersect(Range* other); | 290 void Intersect(Range* other); |
| 291 void Union(Range* other); | 291 void Union(Range* other); |
| 292 void CombinedMax(Range* other); | 292 void CombinedMax(Range* other); |
| 293 void CombinedMin(Range* other); | 293 void CombinedMin(Range* other); |
| 294 | 294 |
| 295 void AddConstant(int32_t value); | 295 void AddConstant(int32_t value); |
| 296 void Sar(int32_t value); | 296 void Sar(int32_t value); |
| 297 void Shl(int32_t value); | 297 void Shl(int32_t value); |
| 298 bool AddAndCheckOverflow(Range* other); | 298 bool AddAndCheckOverflow(const Representation& r, Range* other); |
| 299 bool SubAndCheckOverflow(Range* other); | 299 bool SubAndCheckOverflow(const Representation& r, Range* other); |
| 300 bool MulAndCheckOverflow(Range* other); | 300 bool MulAndCheckOverflow(const Representation& r, Range* other); |
| 301 | 301 |
| 302 private: | 302 private: |
| 303 int32_t lower_; | 303 int32_t lower_; |
| 304 int32_t upper_; | 304 int32_t upper_; |
| 305 Range* next_; | 305 Range* next_; |
| 306 bool can_be_minus_zero_; | 306 bool can_be_minus_zero_; |
| 307 }; | 307 }; |
| 308 | 308 |
| 309 | 309 |
| 310 class UniqueValueId { | 310 class UniqueValueId { |
| (...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 799 // sets this flag, it must implement HandleSideEffectDominator() and should | 799 // sets this flag, it must implement HandleSideEffectDominator() and should |
| 800 // indicate which side effects to track by setting GVN flags. | 800 // indicate which side effects to track by setting GVN flags. |
| 801 kTrackSideEffectDominators, | 801 kTrackSideEffectDominators, |
| 802 kCanOverflow, | 802 kCanOverflow, |
| 803 kBailoutOnMinusZero, | 803 kBailoutOnMinusZero, |
| 804 kCanBeDivByZero, | 804 kCanBeDivByZero, |
| 805 kAllowUndefinedAsNaN, | 805 kAllowUndefinedAsNaN, |
| 806 kIsArguments, | 806 kIsArguments, |
| 807 kTruncatingToInt32, | 807 kTruncatingToInt32, |
| 808 kAllUsesTruncatingToInt32, | 808 kAllUsesTruncatingToInt32, |
| 809 kTruncatingToSmi, |
| 810 kAllUsesTruncatingToSmi, |
| 809 // Set after an instruction is killed. | 811 // Set after an instruction is killed. |
| 810 kIsDead, | 812 kIsDead, |
| 811 // Instructions that are allowed to produce full range unsigned integer | 813 // Instructions that are allowed to produce full range unsigned integer |
| 812 // values are marked with kUint32 flag. If arithmetic shift or a load from | 814 // values are marked with kUint32 flag. If arithmetic shift or a load from |
| 813 // EXTERNAL_UNSIGNED_INT_ELEMENTS array is not marked with this flag | 815 // EXTERNAL_UNSIGNED_INT_ELEMENTS array is not marked with this flag |
| 814 // it will deoptimize if result does not fit into signed integer range. | 816 // it will deoptimize if result does not fit into signed integer range. |
| 815 // HGraph::ComputeSafeUint32Operations is responsible for setting this | 817 // HGraph::ComputeSafeUint32Operations is responsible for setting this |
| 816 // flag. | 818 // flag. |
| 817 kUint32, | 819 kUint32, |
| 818 // If a phi is involved in the evaluation of a numeric constraint the | 820 // If a phi is involved in the evaluation of a numeric constraint the |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 885 | 887 |
| 886 // Note: Never call this method for an unlinked value. | 888 // Note: Never call this method for an unlinked value. |
| 887 Isolate* isolate() const; | 889 Isolate* isolate() const; |
| 888 | 890 |
| 889 int id() const { return id_; } | 891 int id() const { return id_; } |
| 890 void set_id(int id) { id_ = id; } | 892 void set_id(int id) { id_ = id; } |
| 891 | 893 |
| 892 HUseIterator uses() const { return HUseIterator(use_list_); } | 894 HUseIterator uses() const { return HUseIterator(use_list_); } |
| 893 | 895 |
| 894 virtual bool EmitAtUses() { return false; } | 896 virtual bool EmitAtUses() { return false; } |
| 897 |
| 895 Representation representation() const { return representation_; } | 898 Representation representation() const { return representation_; } |
| 896 void ChangeRepresentation(Representation r) { | 899 void ChangeRepresentation(Representation r) { |
| 897 ASSERT(CheckFlag(kFlexibleRepresentation)); | 900 ASSERT(CheckFlag(kFlexibleRepresentation)); |
| 898 ASSERT(!CheckFlag(kCannotBeTagged) || !r.IsTagged()); | 901 ASSERT(!CheckFlag(kCannotBeTagged) || !r.IsTagged()); |
| 899 RepresentationChanged(r); | 902 RepresentationChanged(r); |
| 900 representation_ = r; | 903 representation_ = r; |
| 901 if (r.IsTagged()) { | 904 if (r.IsTagged()) { |
| 902 // Tagged is the bottom of the lattice, don't go any further. | 905 // Tagged is the bottom of the lattice, don't go any further. |
| 903 ClearFlag(kFlexibleRepresentation); | 906 ClearFlag(kFlexibleRepresentation); |
| 904 } | 907 } |
| (...skipping 803 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1708 virtual void PrintDataTo(StringStream* stream); | 1711 virtual void PrintDataTo(StringStream* stream); |
| 1709 | 1712 |
| 1710 DECLARE_CONCRETE_INSTRUCTION(ForceRepresentation) | 1713 DECLARE_CONCRETE_INSTRUCTION(ForceRepresentation) |
| 1711 }; | 1714 }; |
| 1712 | 1715 |
| 1713 | 1716 |
| 1714 class HChange: public HUnaryOperation { | 1717 class HChange: public HUnaryOperation { |
| 1715 public: | 1718 public: |
| 1716 HChange(HValue* value, | 1719 HChange(HValue* value, |
| 1717 Representation to, | 1720 Representation to, |
| 1718 bool is_truncating, | 1721 bool is_truncating_to_smi, |
| 1722 bool is_truncating_to_int32, |
| 1719 bool allow_undefined_as_nan) | 1723 bool allow_undefined_as_nan) |
| 1720 : HUnaryOperation(value) { | 1724 : HUnaryOperation(value) { |
| 1721 ASSERT(!value->representation().IsNone()); | 1725 ASSERT(!value->representation().IsNone()); |
| 1722 ASSERT(!to.IsNone()); | 1726 ASSERT(!to.IsNone()); |
| 1723 ASSERT(!value->representation().Equals(to)); | 1727 ASSERT(!value->representation().Equals(to)); |
| 1724 set_representation(to); | 1728 set_representation(to); |
| 1725 SetFlag(kUseGVN); | 1729 SetFlag(kUseGVN); |
| 1726 if (allow_undefined_as_nan) SetFlag(kAllowUndefinedAsNaN); | 1730 if (allow_undefined_as_nan) SetFlag(kAllowUndefinedAsNaN); |
| 1727 if (is_truncating) SetFlag(kTruncatingToInt32); | 1731 if (is_truncating_to_smi) SetFlag(kTruncatingToSmi); |
| 1732 if (is_truncating_to_int32) SetFlag(kTruncatingToInt32); |
| 1728 if (value->representation().IsSmi() || value->type().IsSmi()) { | 1733 if (value->representation().IsSmi() || value->type().IsSmi()) { |
| 1729 set_type(HType::Smi()); | 1734 set_type(HType::Smi()); |
| 1730 } else { | 1735 } else { |
| 1731 set_type(HType::TaggedNumber()); | 1736 set_type(HType::TaggedNumber()); |
| 1732 if (to.IsTagged()) SetGVNFlag(kChangesNewSpacePromotion); | 1737 if (to.IsTagged()) SetGVNFlag(kChangesNewSpacePromotion); |
| 1733 } | 1738 } |
| 1734 } | 1739 } |
| 1735 | 1740 |
| 1736 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); | 1741 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); |
| 1737 virtual HType CalculateInferredType(); | 1742 virtual HType CalculateInferredType(); |
| (...skipping 880 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2618 } | 2623 } |
| 2619 | 2624 |
| 2620 private: | 2625 private: |
| 2621 HUnaryMathOperation(HValue* context, HValue* value, BuiltinFunctionId op) | 2626 HUnaryMathOperation(HValue* context, HValue* value, BuiltinFunctionId op) |
| 2622 : op_(op) { | 2627 : op_(op) { |
| 2623 SetOperandAt(0, context); | 2628 SetOperandAt(0, context); |
| 2624 SetOperandAt(1, value); | 2629 SetOperandAt(1, value); |
| 2625 switch (op) { | 2630 switch (op) { |
| 2626 case kMathFloor: | 2631 case kMathFloor: |
| 2627 case kMathRound: | 2632 case kMathRound: |
| 2633 // TODO(verwaest): Set representation to flexible int starting as smi. |
| 2628 set_representation(Representation::Integer32()); | 2634 set_representation(Representation::Integer32()); |
| 2629 break; | 2635 break; |
| 2630 case kMathAbs: | 2636 case kMathAbs: |
| 2631 // Not setting representation here: it is None intentionally. | 2637 // Not setting representation here: it is None intentionally. |
| 2632 SetFlag(kFlexibleRepresentation); | 2638 SetFlag(kFlexibleRepresentation); |
| 2633 // TODO(svenpanne) This flag is actually only needed if representation() | 2639 // TODO(svenpanne) This flag is actually only needed if representation() |
| 2634 // is tagged, and not when it is an unboxed double or unboxed integer. | 2640 // is tagged, and not when it is an unboxed double or unboxed integer. |
| 2635 SetGVNFlag(kChangesNewSpacePromotion); | 2641 SetGVNFlag(kChangesNewSpacePromotion); |
| 2636 break; | 2642 break; |
| 2637 case kMathLog: | 2643 case kMathLog: |
| (...skipping 799 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3437 HValue* context() { return OperandAt(0); } | 3443 HValue* context() { return OperandAt(0); } |
| 3438 HValue* left() { return OperandAt(1); } | 3444 HValue* left() { return OperandAt(1); } |
| 3439 HValue* right() { return OperandAt(2); } | 3445 HValue* right() { return OperandAt(2); } |
| 3440 | 3446 |
| 3441 // True if switching left and right operands likely generates better code. | 3447 // True if switching left and right operands likely generates better code. |
| 3442 bool AreOperandsBetterSwitched() { | 3448 bool AreOperandsBetterSwitched() { |
| 3443 if (!IsCommutative()) return false; | 3449 if (!IsCommutative()) return false; |
| 3444 | 3450 |
| 3445 // Constant operands are better off on the right, they can be inlined in | 3451 // Constant operands are better off on the right, they can be inlined in |
| 3446 // many situations on most platforms. | 3452 // many situations on most platforms. |
| 3453 if (right()->IsConstant()) return false; |
| 3447 if (left()->IsConstant()) return true; | 3454 if (left()->IsConstant()) return true; |
| 3448 if (right()->IsConstant()) return false; | |
| 3449 | 3455 |
| 3450 // Otherwise, if there is only one use of the right operand, it would be | 3456 // Otherwise, if there is only one use of the right operand, it would be |
| 3451 // better off on the left for platforms that only have 2-arg arithmetic | 3457 // better off on the left for platforms that only have 2-arg arithmetic |
| 3452 // ops (e.g ia32, x64) that clobber the left operand. | 3458 // ops (e.g ia32, x64) that clobber the left operand. |
| 3453 return (right()->UseCount() == 1); | 3459 return left()->UseCount() > 1 && right()->UseCount() == 1; |
| 3454 } | 3460 } |
| 3455 | 3461 |
| 3456 HValue* BetterLeftOperand() { | 3462 HValue* BetterLeftOperand() { |
| 3457 return AreOperandsBetterSwitched() ? right() : left(); | 3463 return AreOperandsBetterSwitched() ? right() : left(); |
| 3458 } | 3464 } |
| 3459 | 3465 |
| 3460 HValue* BetterRightOperand() { | 3466 HValue* BetterRightOperand() { |
| 3461 return AreOperandsBetterSwitched() ? left() : right(); | 3467 return AreOperandsBetterSwitched() ? left() : right(); |
| 3462 } | 3468 } |
| 3463 | 3469 |
| 3464 void set_observed_input_representation(int index, Representation rep) { | 3470 void set_observed_input_representation(int index, Representation rep) { |
| 3465 ASSERT(index >= 1 && index <= 2); | 3471 ASSERT(index >= 1 && index <= 2); |
| 3466 observed_input_representation_[index - 1] = rep; | 3472 observed_input_representation_[index - 1] = rep; |
| 3467 } | 3473 } |
| 3468 | 3474 |
| 3469 virtual void initialize_output_representation(Representation observed) { | 3475 virtual void initialize_output_representation(Representation observed) { |
| 3470 observed_output_representation_ = observed; | 3476 observed_output_representation_ = observed; |
| 3471 } | 3477 } |
| 3472 | 3478 |
| 3473 virtual Representation observed_input_representation(int index) { | 3479 virtual Representation observed_input_representation(int index) { |
| 3474 if (index == 0) return Representation::Tagged(); | 3480 if (index == 0) return Representation::Tagged(); |
| 3475 return observed_input_representation_[index - 1]; | 3481 return observed_input_representation_[index - 1]; |
| 3476 } | 3482 } |
| 3477 | 3483 |
| 3484 virtual void UpdateRepresentation(Representation new_rep, |
| 3485 HInferRepresentationPhase* h_infer, |
| 3486 const char* reason) { |
| 3487 if (!FLAG_smi_binop) { |
| 3488 if (new_rep.IsSmi()) new_rep = Representation::Integer32(); |
| 3489 } |
| 3490 HValue::UpdateRepresentation(new_rep, h_infer, reason); |
| 3491 } |
| 3492 |
| 3478 virtual void InferRepresentation(HInferRepresentationPhase* h_infer); | 3493 virtual void InferRepresentation(HInferRepresentationPhase* h_infer); |
| 3479 virtual Representation RepresentationFromInputs(); | 3494 virtual Representation RepresentationFromInputs(); |
| 3495 Representation RepresentationFromOutput(); |
| 3480 virtual void AssumeRepresentation(Representation r); | 3496 virtual void AssumeRepresentation(Representation r); |
| 3481 | 3497 |
| 3482 virtual void UpdateRepresentation(Representation new_rep, | |
| 3483 HInferRepresentationPhase* h_infer, | |
| 3484 const char* reason) { | |
| 3485 // By default, binary operations don't handle Smis. | |
| 3486 if (new_rep.IsSmi()) { | |
| 3487 new_rep = Representation::Integer32(); | |
| 3488 } | |
| 3489 HValue::UpdateRepresentation(new_rep, h_infer, reason); | |
| 3490 } | |
| 3491 | |
| 3492 virtual bool IsCommutative() const { return false; } | 3498 virtual bool IsCommutative() const { return false; } |
| 3493 | 3499 |
| 3494 virtual void PrintDataTo(StringStream* stream); | 3500 virtual void PrintDataTo(StringStream* stream); |
| 3495 | 3501 |
| 3502 virtual Representation RequiredInputRepresentation(int index) { |
| 3503 if (index == 0) return Representation::Tagged(); |
| 3504 return representation(); |
| 3505 } |
| 3506 |
| 3496 DECLARE_ABSTRACT_INSTRUCTION(BinaryOperation) | 3507 DECLARE_ABSTRACT_INSTRUCTION(BinaryOperation) |
| 3497 | 3508 |
| 3498 private: | 3509 private: |
| 3499 bool IgnoreObservedOutputRepresentation(Representation current_rep); | 3510 bool IgnoreObservedOutputRepresentation(Representation current_rep); |
| 3500 | 3511 |
| 3501 Representation observed_input_representation_[2]; | 3512 Representation observed_input_representation_[2]; |
| 3502 Representation observed_output_representation_; | 3513 Representation observed_output_representation_; |
| 3503 }; | 3514 }; |
| 3504 | 3515 |
| 3505 | 3516 |
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3764 class HBitwiseBinaryOperation: public HBinaryOperation { | 3775 class HBitwiseBinaryOperation: public HBinaryOperation { |
| 3765 public: | 3776 public: |
| 3766 HBitwiseBinaryOperation(HValue* context, HValue* left, HValue* right) | 3777 HBitwiseBinaryOperation(HValue* context, HValue* left, HValue* right) |
| 3767 : HBinaryOperation(context, left, right) { | 3778 : HBinaryOperation(context, left, right) { |
| 3768 SetFlag(kFlexibleRepresentation); | 3779 SetFlag(kFlexibleRepresentation); |
| 3769 SetFlag(kTruncatingToInt32); | 3780 SetFlag(kTruncatingToInt32); |
| 3770 SetFlag(kAllowUndefinedAsNaN); | 3781 SetFlag(kAllowUndefinedAsNaN); |
| 3771 SetAllSideEffects(); | 3782 SetAllSideEffects(); |
| 3772 } | 3783 } |
| 3773 | 3784 |
| 3774 virtual Representation RequiredInputRepresentation(int index) { | |
| 3775 return index == 0 | |
| 3776 ? Representation::Tagged() | |
| 3777 : representation(); | |
| 3778 } | |
| 3779 | |
| 3780 virtual void RepresentationChanged(Representation to) { | 3785 virtual void RepresentationChanged(Representation to) { |
| 3781 if (!to.IsTagged()) { | 3786 if (!to.IsTagged()) { |
| 3782 ASSERT(to.IsInteger32()); | 3787 ASSERT(to.IsSmiOrInteger32()); |
| 3783 ClearAllSideEffects(); | 3788 ClearAllSideEffects(); |
| 3784 SetFlag(kUseGVN); | 3789 SetFlag(kUseGVN); |
| 3785 } else { | 3790 } else { |
| 3786 SetAllSideEffects(); | 3791 SetAllSideEffects(); |
| 3787 ClearFlag(kUseGVN); | 3792 ClearFlag(kUseGVN); |
| 3788 } | 3793 } |
| 3789 } | 3794 } |
| 3790 | 3795 |
| 3791 virtual void UpdateRepresentation(Representation new_rep, | 3796 virtual void UpdateRepresentation(Representation new_rep, |
| 3792 HInferRepresentationPhase* h_infer, | 3797 HInferRepresentationPhase* h_infer, |
| 3793 const char* reason) { | 3798 const char* reason) { |
| 3794 // We only generate either int32 or generic tagged bitwise operations. | 3799 // We only generate either int32 or generic tagged bitwise operations. |
| 3795 if (new_rep.IsSmi() || new_rep.IsDouble()) { | 3800 if (new_rep.IsDouble()) new_rep = Representation::Integer32(); |
| 3796 new_rep = Representation::Integer32(); | 3801 HBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason); |
| 3797 } | 3802 } |
| 3798 HValue::UpdateRepresentation(new_rep, h_infer, reason); | 3803 |
| 3804 virtual Representation observed_input_representation(int index) { |
| 3805 Representation r = HBinaryOperation::observed_input_representation(index); |
| 3806 if (r.IsDouble()) return Representation::Integer32(); |
| 3807 return r; |
| 3799 } | 3808 } |
| 3800 | 3809 |
| 3801 virtual void initialize_output_representation(Representation observed) { | 3810 virtual void initialize_output_representation(Representation observed) { |
| 3802 if (observed.IsDouble()) observed = Representation::Integer32(); | 3811 if (observed.IsDouble()) observed = Representation::Integer32(); |
| 3803 HBinaryOperation::initialize_output_representation(observed); | 3812 HBinaryOperation::initialize_output_representation(observed); |
| 3804 } | 3813 } |
| 3805 | 3814 |
| 3806 virtual HType CalculateInferredType(); | 3815 virtual HType CalculateInferredType(); |
| 3807 | 3816 |
| 3808 DECLARE_ABSTRACT_INSTRUCTION(BitwiseBinaryOperation) | 3817 DECLARE_ABSTRACT_INSTRUCTION(BitwiseBinaryOperation) |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3854 if (to.IsTagged()) { | 3863 if (to.IsTagged()) { |
| 3855 SetAllSideEffects(); | 3864 SetAllSideEffects(); |
| 3856 ClearFlag(kUseGVN); | 3865 ClearFlag(kUseGVN); |
| 3857 } else { | 3866 } else { |
| 3858 ClearAllSideEffects(); | 3867 ClearAllSideEffects(); |
| 3859 SetFlag(kUseGVN); | 3868 SetFlag(kUseGVN); |
| 3860 } | 3869 } |
| 3861 } | 3870 } |
| 3862 | 3871 |
| 3863 virtual HType CalculateInferredType(); | 3872 virtual HType CalculateInferredType(); |
| 3864 virtual Representation RequiredInputRepresentation(int index) { | |
| 3865 return index == 0 | |
| 3866 ? Representation::Tagged() | |
| 3867 : representation(); | |
| 3868 } | |
| 3869 | 3873 |
| 3870 DECLARE_ABSTRACT_INSTRUCTION(ArithmeticBinaryOperation) | 3874 DECLARE_ABSTRACT_INSTRUCTION(ArithmeticBinaryOperation) |
| 3871 | 3875 |
| 3872 private: | 3876 private: |
| 3873 virtual bool IsDeletable() const { return true; } | 3877 virtual bool IsDeletable() const { return true; } |
| 3874 }; | 3878 }; |
| 3875 | 3879 |
| 3876 | 3880 |
| 3877 class HCompareGeneric: public HBinaryOperation { | 3881 class HCompareGeneric: public HBinaryOperation { |
| 3878 public: | 3882 public: |
| (...skipping 539 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4418 | 4422 |
| 4419 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); | 4423 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); |
| 4420 | 4424 |
| 4421 virtual HValue* Canonicalize(); | 4425 virtual HValue* Canonicalize(); |
| 4422 | 4426 |
| 4423 // Only commutative if it is certain that not two objects are multiplicated. | 4427 // Only commutative if it is certain that not two objects are multiplicated. |
| 4424 virtual bool IsCommutative() const { | 4428 virtual bool IsCommutative() const { |
| 4425 return !representation().IsTagged(); | 4429 return !representation().IsTagged(); |
| 4426 } | 4430 } |
| 4427 | 4431 |
| 4432 virtual void UpdateRepresentation(Representation new_rep, |
| 4433 HInferRepresentationPhase* h_infer, |
| 4434 const char* reason) { |
| 4435 if (new_rep.IsSmi()) new_rep = Representation::Integer32(); |
| 4436 HArithmeticBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason); |
| 4437 } |
| 4438 |
| 4428 DECLARE_CONCRETE_INSTRUCTION(Mul) | 4439 DECLARE_CONCRETE_INSTRUCTION(Mul) |
| 4429 | 4440 |
| 4430 protected: | 4441 protected: |
| 4431 virtual bool DataEquals(HValue* other) { return true; } | 4442 virtual bool DataEquals(HValue* other) { return true; } |
| 4432 | 4443 |
| 4433 virtual Range* InferRange(Zone* zone); | 4444 virtual Range* InferRange(Zone* zone); |
| 4434 | 4445 |
| 4435 private: | 4446 private: |
| 4436 HMul(HValue* context, HValue* left, HValue* right) | 4447 HMul(HValue* context, HValue* left, HValue* right) |
| 4437 : HArithmeticBinaryOperation(context, left, right) { | 4448 : HArithmeticBinaryOperation(context, left, right) { |
| (...skipping 19 matching lines...) Expand all Loading... |
| 4457 return value != 0 && (IsPowerOf2(value) || IsPowerOf2(-value)); | 4468 return value != 0 && (IsPowerOf2(value) || IsPowerOf2(-value)); |
| 4458 } | 4469 } |
| 4459 | 4470 |
| 4460 return false; | 4471 return false; |
| 4461 } | 4472 } |
| 4462 | 4473 |
| 4463 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); | 4474 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); |
| 4464 | 4475 |
| 4465 virtual HValue* Canonicalize(); | 4476 virtual HValue* Canonicalize(); |
| 4466 | 4477 |
| 4478 virtual void UpdateRepresentation(Representation new_rep, |
| 4479 HInferRepresentationPhase* h_infer, |
| 4480 const char* reason) { |
| 4481 if (!FLAG_smi_binop) { |
| 4482 if (new_rep.IsSmi()) new_rep = Representation::Integer32(); |
| 4483 } |
| 4484 HArithmeticBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason); |
| 4485 } |
| 4486 |
| 4467 DECLARE_CONCRETE_INSTRUCTION(Mod) | 4487 DECLARE_CONCRETE_INSTRUCTION(Mod) |
| 4468 | 4488 |
| 4469 protected: | 4489 protected: |
| 4470 virtual bool DataEquals(HValue* other) { return true; } | 4490 virtual bool DataEquals(HValue* other) { return true; } |
| 4471 | 4491 |
| 4472 virtual Range* InferRange(Zone* zone); | 4492 virtual Range* InferRange(Zone* zone); |
| 4473 | 4493 |
| 4474 private: | 4494 private: |
| 4475 HMod(HValue* context, | 4495 HMod(HValue* context, |
| 4476 HValue* left, | 4496 HValue* left, |
| (...skipping 22 matching lines...) Expand all Loading... |
| 4499 return value != 0 && (IsPowerOf2(value) || IsPowerOf2(-value)); | 4519 return value != 0 && (IsPowerOf2(value) || IsPowerOf2(-value)); |
| 4500 } | 4520 } |
| 4501 | 4521 |
| 4502 return false; | 4522 return false; |
| 4503 } | 4523 } |
| 4504 | 4524 |
| 4505 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); | 4525 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); |
| 4506 | 4526 |
| 4507 virtual HValue* Canonicalize(); | 4527 virtual HValue* Canonicalize(); |
| 4508 | 4528 |
| 4529 virtual void UpdateRepresentation(Representation new_rep, |
| 4530 HInferRepresentationPhase* h_infer, |
| 4531 const char* reason) { |
| 4532 if (new_rep.IsSmi()) new_rep = Representation::Integer32(); |
| 4533 HArithmeticBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason); |
| 4534 } |
| 4535 |
| 4509 DECLARE_CONCRETE_INSTRUCTION(Div) | 4536 DECLARE_CONCRETE_INSTRUCTION(Div) |
| 4510 | 4537 |
| 4511 protected: | 4538 protected: |
| 4512 virtual bool DataEquals(HValue* other) { return true; } | 4539 virtual bool DataEquals(HValue* other) { return true; } |
| 4513 | 4540 |
| 4514 virtual Range* InferRange(Zone* zone); | 4541 virtual Range* InferRange(Zone* zone); |
| 4515 | 4542 |
| 4516 private: | 4543 private: |
| 4517 HDiv(HValue* context, HValue* left, HValue* right) | 4544 HDiv(HValue* context, HValue* left, HValue* right) |
| 4518 : HArithmeticBinaryOperation(context, left, right) { | 4545 : HArithmeticBinaryOperation(context, left, right) { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 4539 | 4566 |
| 4540 virtual Representation observed_input_representation(int index) { | 4567 virtual Representation observed_input_representation(int index) { |
| 4541 return RequiredInputRepresentation(index); | 4568 return RequiredInputRepresentation(index); |
| 4542 } | 4569 } |
| 4543 | 4570 |
| 4544 virtual void InferRepresentation(HInferRepresentationPhase* h_infer); | 4571 virtual void InferRepresentation(HInferRepresentationPhase* h_infer); |
| 4545 | 4572 |
| 4546 virtual Representation RepresentationFromInputs() { | 4573 virtual Representation RepresentationFromInputs() { |
| 4547 Representation left_rep = left()->representation(); | 4574 Representation left_rep = left()->representation(); |
| 4548 Representation right_rep = right()->representation(); | 4575 Representation right_rep = right()->representation(); |
| 4549 if ((left_rep.IsNone() || left_rep.IsInteger32()) && | 4576 Representation result = Representation::Smi(); |
| 4550 (right_rep.IsNone() || right_rep.IsInteger32())) { | 4577 result = result.generalize(left_rep); |
| 4551 return Representation::Integer32(); | 4578 result = result.generalize(right_rep); |
| 4552 } | 4579 if (result.IsTagged()) return Representation::Double(); |
| 4553 return Representation::Double(); | 4580 return result; |
| 4554 } | 4581 } |
| 4555 | 4582 |
| 4556 virtual bool IsCommutative() const { return true; } | 4583 virtual bool IsCommutative() const { return true; } |
| 4557 | 4584 |
| 4558 Operation operation() { return operation_; } | 4585 Operation operation() { return operation_; } |
| 4559 | 4586 |
| 4560 DECLARE_CONCRETE_INSTRUCTION(MathMinMax) | 4587 DECLARE_CONCRETE_INSTRUCTION(MathMinMax) |
| 4561 | 4588 |
| 4562 protected: | 4589 protected: |
| 4563 virtual bool DataEquals(HValue* other) { | 4590 virtual bool DataEquals(HValue* other) { |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4598 virtual bool DataEquals(HValue* other) { | 4625 virtual bool DataEquals(HValue* other) { |
| 4599 return op() == HBitwise::cast(other)->op(); | 4626 return op() == HBitwise::cast(other)->op(); |
| 4600 } | 4627 } |
| 4601 | 4628 |
| 4602 virtual Range* InferRange(Zone* zone); | 4629 virtual Range* InferRange(Zone* zone); |
| 4603 | 4630 |
| 4604 private: | 4631 private: |
| 4605 HBitwise(Token::Value op, HValue* context, HValue* left, HValue* right) | 4632 HBitwise(Token::Value op, HValue* context, HValue* left, HValue* right) |
| 4606 : HBitwiseBinaryOperation(context, left, right), op_(op) { | 4633 : HBitwiseBinaryOperation(context, left, right), op_(op) { |
| 4607 ASSERT(op == Token::BIT_AND || op == Token::BIT_OR || op == Token::BIT_XOR); | 4634 ASSERT(op == Token::BIT_AND || op == Token::BIT_OR || op == Token::BIT_XOR); |
| 4635 if (op == Token::BIT_AND && |
| 4636 ((left->IsConstant() && left->representation().IsSmi()) || |
| 4637 (right->IsConstant() && right->representation().IsSmi()))) { |
| 4638 SetFlag(kTruncatingToSmi); |
| 4639 } |
| 4608 } | 4640 } |
| 4609 | 4641 |
| 4610 Token::Value op_; | 4642 Token::Value op_; |
| 4611 }; | 4643 }; |
| 4612 | 4644 |
| 4613 | 4645 |
| 4614 class HShl: public HBitwiseBinaryOperation { | 4646 class HShl: public HBitwiseBinaryOperation { |
| 4615 public: | 4647 public: |
| 4616 static HInstruction* New(Zone* zone, | 4648 static HInstruction* New(Zone* zone, |
| 4617 HValue* context, | 4649 HValue* context, |
| 4618 HValue* left, | 4650 HValue* left, |
| 4619 HValue* right); | 4651 HValue* right); |
| 4620 | 4652 |
| 4621 virtual Range* InferRange(Zone* zone); | 4653 virtual Range* InferRange(Zone* zone); |
| 4622 | 4654 |
| 4655 virtual void UpdateRepresentation(Representation new_rep, |
| 4656 HInferRepresentationPhase* h_infer, |
| 4657 const char* reason) { |
| 4658 if (new_rep.IsSmi()) new_rep = Representation::Integer32(); |
| 4659 HBitwiseBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason); |
| 4660 } |
| 4661 |
| 4623 DECLARE_CONCRETE_INSTRUCTION(Shl) | 4662 DECLARE_CONCRETE_INSTRUCTION(Shl) |
| 4624 | 4663 |
| 4625 protected: | 4664 protected: |
| 4626 virtual bool DataEquals(HValue* other) { return true; } | 4665 virtual bool DataEquals(HValue* other) { return true; } |
| 4627 | 4666 |
| 4628 private: | 4667 private: |
| 4629 HShl(HValue* context, HValue* left, HValue* right) | 4668 HShl(HValue* context, HValue* left, HValue* right) |
| 4630 : HBitwiseBinaryOperation(context, left, right) { } | 4669 : HBitwiseBinaryOperation(context, left, right) { } |
| 4631 }; | 4670 }; |
| 4632 | 4671 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 4645 // like ((base + offset) >> scale) with one single decomposition. | 4684 // like ((base + offset) >> scale) with one single decomposition. |
| 4646 left()->TryDecompose(decomposition); | 4685 left()->TryDecompose(decomposition); |
| 4647 return true; | 4686 return true; |
| 4648 } | 4687 } |
| 4649 } | 4688 } |
| 4650 return false; | 4689 return false; |
| 4651 } | 4690 } |
| 4652 | 4691 |
| 4653 virtual Range* InferRange(Zone* zone); | 4692 virtual Range* InferRange(Zone* zone); |
| 4654 | 4693 |
| 4694 virtual void UpdateRepresentation(Representation new_rep, |
| 4695 HInferRepresentationPhase* h_infer, |
| 4696 const char* reason) { |
| 4697 if (new_rep.IsSmi()) new_rep = Representation::Integer32(); |
| 4698 HBitwiseBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason); |
| 4699 } |
| 4700 |
| 4655 DECLARE_CONCRETE_INSTRUCTION(Shr) | 4701 DECLARE_CONCRETE_INSTRUCTION(Shr) |
| 4656 | 4702 |
| 4657 protected: | 4703 protected: |
| 4658 virtual bool DataEquals(HValue* other) { return true; } | 4704 virtual bool DataEquals(HValue* other) { return true; } |
| 4659 | 4705 |
| 4660 private: | 4706 private: |
| 4661 HShr(HValue* context, HValue* left, HValue* right) | 4707 HShr(HValue* context, HValue* left, HValue* right) |
| 4662 : HBitwiseBinaryOperation(context, left, right) { } | 4708 : HBitwiseBinaryOperation(context, left, right) { } |
| 4663 }; | 4709 }; |
| 4664 | 4710 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 4677 // like ((base + offset) >> scale) with one single decomposition. | 4723 // like ((base + offset) >> scale) with one single decomposition. |
| 4678 left()->TryDecompose(decomposition); | 4724 left()->TryDecompose(decomposition); |
| 4679 return true; | 4725 return true; |
| 4680 } | 4726 } |
| 4681 } | 4727 } |
| 4682 return false; | 4728 return false; |
| 4683 } | 4729 } |
| 4684 | 4730 |
| 4685 virtual Range* InferRange(Zone* zone); | 4731 virtual Range* InferRange(Zone* zone); |
| 4686 | 4732 |
| 4733 virtual void UpdateRepresentation(Representation new_rep, |
| 4734 HInferRepresentationPhase* h_infer, |
| 4735 const char* reason) { |
| 4736 if (new_rep.IsSmi()) new_rep = Representation::Integer32(); |
| 4737 HBitwiseBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason); |
| 4738 } |
| 4739 |
| 4687 DECLARE_CONCRETE_INSTRUCTION(Sar) | 4740 DECLARE_CONCRETE_INSTRUCTION(Sar) |
| 4688 | 4741 |
| 4689 protected: | 4742 protected: |
| 4690 virtual bool DataEquals(HValue* other) { return true; } | 4743 virtual bool DataEquals(HValue* other) { return true; } |
| 4691 | 4744 |
| 4692 private: | 4745 private: |
| 4693 HSar(HValue* context, HValue* left, HValue* right) | 4746 HSar(HValue* context, HValue* left, HValue* right) |
| 4694 : HBitwiseBinaryOperation(context, left, right) { } | 4747 : HBitwiseBinaryOperation(context, left, right) { } |
| 4695 }; | 4748 }; |
| 4696 | 4749 |
| 4697 | 4750 |
| 4698 class HRor: public HBitwiseBinaryOperation { | 4751 class HRor: public HBitwiseBinaryOperation { |
| 4699 public: | 4752 public: |
| 4700 HRor(HValue* context, HValue* left, HValue* right) | 4753 HRor(HValue* context, HValue* left, HValue* right) |
| 4701 : HBitwiseBinaryOperation(context, left, right) { | 4754 : HBitwiseBinaryOperation(context, left, right) { |
| 4702 ChangeRepresentation(Representation::Integer32()); | 4755 ChangeRepresentation(Representation::Integer32()); |
| 4703 } | 4756 } |
| 4704 | 4757 |
| 4758 virtual void UpdateRepresentation(Representation new_rep, |
| 4759 HInferRepresentationPhase* h_infer, |
| 4760 const char* reason) { |
| 4761 if (new_rep.IsSmi()) new_rep = Representation::Integer32(); |
| 4762 HBitwiseBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason); |
| 4763 } |
| 4764 |
| 4705 DECLARE_CONCRETE_INSTRUCTION(Ror) | 4765 DECLARE_CONCRETE_INSTRUCTION(Ror) |
| 4706 | 4766 |
| 4707 protected: | 4767 protected: |
| 4708 virtual bool DataEquals(HValue* other) { return true; } | 4768 virtual bool DataEquals(HValue* other) { return true; } |
| 4709 }; | 4769 }; |
| 4710 | 4770 |
| 4711 | 4771 |
| 4712 class HOsrEntry: public HTemplateInstruction<0> { | 4772 class HOsrEntry: public HTemplateInstruction<0> { |
| 4713 public: | 4773 public: |
| 4714 explicit HOsrEntry(BailoutId ast_id) : ast_id_(ast_id) { | 4774 explicit HOsrEntry(BailoutId ast_id) : ast_id_(ast_id) { |
| (...skipping 1207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5922 SetGVNFlag(kChangesDoubleArrayElements); | 5982 SetGVNFlag(kChangesDoubleArrayElements); |
| 5923 } else if (IsFastSmiElementsKind(elements_kind)) { | 5983 } else if (IsFastSmiElementsKind(elements_kind)) { |
| 5924 SetGVNFlag(kChangesArrayElements); | 5984 SetGVNFlag(kChangesArrayElements); |
| 5925 } else { | 5985 } else { |
| 5926 SetGVNFlag(kChangesArrayElements); | 5986 SetGVNFlag(kChangesArrayElements); |
| 5927 } | 5987 } |
| 5928 | 5988 |
| 5929 // EXTERNAL_{UNSIGNED_,}{BYTE,SHORT,INT}_ELEMENTS are truncating. | 5989 // EXTERNAL_{UNSIGNED_,}{BYTE,SHORT,INT}_ELEMENTS are truncating. |
| 5930 if (elements_kind >= EXTERNAL_BYTE_ELEMENTS && | 5990 if (elements_kind >= EXTERNAL_BYTE_ELEMENTS && |
| 5931 elements_kind <= EXTERNAL_UNSIGNED_INT_ELEMENTS) { | 5991 elements_kind <= EXTERNAL_UNSIGNED_INT_ELEMENTS) { |
| 5992 if (elements_kind <= EXTERNAL_SHORT_ELEMENTS) { |
| 5993 SetFlag(kTruncatingToSmi); |
| 5994 } |
| 5932 SetFlag(kTruncatingToInt32); | 5995 SetFlag(kTruncatingToInt32); |
| 5933 } | 5996 } |
| 5934 } | 5997 } |
| 5935 | 5998 |
| 5936 virtual bool HasEscapingOperandAt(int index) { return index != 0; } | 5999 virtual bool HasEscapingOperandAt(int index) { return index != 0; } |
| 5937 virtual Representation RequiredInputRepresentation(int index) { | 6000 virtual Representation RequiredInputRepresentation(int index) { |
| 5938 // kind_fast: tagged[int32] = tagged | 6001 // kind_fast: tagged[int32] = tagged |
| 5939 // kind_double: tagged[int32] = double | 6002 // kind_double: tagged[int32] = double |
| 5940 // kind_smi : tagged[int32] = smi | 6003 // kind_smi : tagged[int32] = smi |
| 5941 // kind_external: external[int32] = (double | int32) | 6004 // kind_external: external[int32] = (double | int32) |
| (...skipping 702 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6644 virtual bool IsDeletable() const { return true; } | 6707 virtual bool IsDeletable() const { return true; } |
| 6645 }; | 6708 }; |
| 6646 | 6709 |
| 6647 | 6710 |
| 6648 #undef DECLARE_INSTRUCTION | 6711 #undef DECLARE_INSTRUCTION |
| 6649 #undef DECLARE_CONCRETE_INSTRUCTION | 6712 #undef DECLARE_CONCRETE_INSTRUCTION |
| 6650 | 6713 |
| 6651 } } // namespace v8::internal | 6714 } } // namespace v8::internal |
| 6652 | 6715 |
| 6653 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ | 6716 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ |
| OLD | NEW |