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 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1160 virtual bool DataEquals(HValue* other) { | 1163 virtual bool DataEquals(HValue* other) { |
1161 UNREACHABLE(); | 1164 UNREACHABLE(); |
1162 return false; | 1165 return false; |
1163 } | 1166 } |
1164 | 1167 |
1165 virtual Representation RepresentationFromInputs() { | 1168 virtual Representation RepresentationFromInputs() { |
1166 return representation(); | 1169 return representation(); |
1167 } | 1170 } |
1168 Representation RepresentationFromUses(); | 1171 Representation RepresentationFromUses(); |
1169 Representation RepresentationFromUseRequirements(); | 1172 Representation RepresentationFromUseRequirements(); |
1173 bool HasNonSmiUse(); | |
1170 virtual void UpdateRepresentation(Representation new_rep, | 1174 virtual void UpdateRepresentation(Representation new_rep, |
1171 HInferRepresentationPhase* h_infer, | 1175 HInferRepresentationPhase* h_infer, |
1172 const char* reason); | 1176 const char* reason); |
1173 void AddDependantsToWorklist(HInferRepresentationPhase* h_infer); | 1177 void AddDependantsToWorklist(HInferRepresentationPhase* h_infer); |
1174 | 1178 |
1175 virtual void RepresentationChanged(Representation to) { } | 1179 virtual void RepresentationChanged(Representation to) { } |
1176 | 1180 |
1177 virtual Range* InferRange(Zone* zone); | 1181 virtual Range* InferRange(Zone* zone); |
1178 virtual void DeleteFromGraph() = 0; | 1182 virtual void DeleteFromGraph() = 0; |
1179 virtual void InternalSetOperandAt(int index, HValue* value) = 0; | 1183 virtual void InternalSetOperandAt(int index, HValue* value) = 0; |
(...skipping 528 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1708 virtual void PrintDataTo(StringStream* stream); | 1712 virtual void PrintDataTo(StringStream* stream); |
1709 | 1713 |
1710 DECLARE_CONCRETE_INSTRUCTION(ForceRepresentation) | 1714 DECLARE_CONCRETE_INSTRUCTION(ForceRepresentation) |
1711 }; | 1715 }; |
1712 | 1716 |
1713 | 1717 |
1714 class HChange: public HUnaryOperation { | 1718 class HChange: public HUnaryOperation { |
1715 public: | 1719 public: |
1716 HChange(HValue* value, | 1720 HChange(HValue* value, |
1717 Representation to, | 1721 Representation to, |
1718 bool is_truncating, | 1722 bool is_truncating_to_smi, |
1723 bool is_truncating_to_int32, | |
1719 bool allow_undefined_as_nan) | 1724 bool allow_undefined_as_nan) |
1720 : HUnaryOperation(value) { | 1725 : HUnaryOperation(value) { |
1721 ASSERT(!value->representation().IsNone()); | 1726 ASSERT(!value->representation().IsNone()); |
1722 ASSERT(!to.IsNone()); | 1727 ASSERT(!to.IsNone()); |
1723 ASSERT(!value->representation().Equals(to)); | 1728 ASSERT(!value->representation().Equals(to)); |
1724 set_representation(to); | 1729 set_representation(to); |
1725 SetFlag(kUseGVN); | 1730 SetFlag(kUseGVN); |
1726 if (allow_undefined_as_nan) SetFlag(kAllowUndefinedAsNaN); | 1731 if (allow_undefined_as_nan) SetFlag(kAllowUndefinedAsNaN); |
1727 if (is_truncating) SetFlag(kTruncatingToInt32); | 1732 if (is_truncating_to_smi) SetFlag(kTruncatingToSmi); |
1733 if (is_truncating_to_int32) SetFlag(kTruncatingToInt32); | |
1728 if (value->representation().IsSmi() || value->type().IsSmi()) { | 1734 if (value->representation().IsSmi() || value->type().IsSmi()) { |
1729 set_type(HType::Smi()); | 1735 set_type(HType::Smi()); |
1730 } else { | 1736 } else { |
1731 set_type(HType::TaggedNumber()); | 1737 set_type(HType::TaggedNumber()); |
1732 if (to.IsTagged()) SetGVNFlag(kChangesNewSpacePromotion); | 1738 if (to.IsTagged()) SetGVNFlag(kChangesNewSpacePromotion); |
1733 } | 1739 } |
1734 } | 1740 } |
1735 | 1741 |
1736 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); | 1742 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); |
1737 virtual HType CalculateInferredType(); | 1743 virtual HType CalculateInferredType(); |
(...skipping 880 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2618 } | 2624 } |
2619 | 2625 |
2620 private: | 2626 private: |
2621 HUnaryMathOperation(HValue* context, HValue* value, BuiltinFunctionId op) | 2627 HUnaryMathOperation(HValue* context, HValue* value, BuiltinFunctionId op) |
2622 : op_(op) { | 2628 : op_(op) { |
2623 SetOperandAt(0, context); | 2629 SetOperandAt(0, context); |
2624 SetOperandAt(1, value); | 2630 SetOperandAt(1, value); |
2625 switch (op) { | 2631 switch (op) { |
2626 case kMathFloor: | 2632 case kMathFloor: |
2627 case kMathRound: | 2633 case kMathRound: |
2634 // TODO(verwaest): Set representation to flexible int starting as smi. | |
2628 set_representation(Representation::Integer32()); | 2635 set_representation(Representation::Integer32()); |
2629 break; | 2636 break; |
2630 case kMathAbs: | 2637 case kMathAbs: |
2631 // Not setting representation here: it is None intentionally. | 2638 // Not setting representation here: it is None intentionally. |
2632 SetFlag(kFlexibleRepresentation); | 2639 SetFlag(kFlexibleRepresentation); |
2633 // TODO(svenpanne) This flag is actually only needed if representation() | 2640 // TODO(svenpanne) This flag is actually only needed if representation() |
2634 // is tagged, and not when it is an unboxed double or unboxed integer. | 2641 // is tagged, and not when it is an unboxed double or unboxed integer. |
2635 SetGVNFlag(kChangesNewSpacePromotion); | 2642 SetGVNFlag(kChangesNewSpacePromotion); |
2636 break; | 2643 break; |
2637 case kMathLog: | 2644 case kMathLog: |
(...skipping 643 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3281 | 3288 |
3282 bool IsCell() const { | 3289 bool IsCell() const { |
3283 return is_cell_; | 3290 return is_cell_; |
3284 } | 3291 } |
3285 | 3292 |
3286 virtual Representation RequiredInputRepresentation(int index) { | 3293 virtual Representation RequiredInputRepresentation(int index) { |
3287 return Representation::None(); | 3294 return Representation::None(); |
3288 } | 3295 } |
3289 | 3296 |
3290 virtual Representation KnownOptimalRepresentation() { | 3297 virtual Representation KnownOptimalRepresentation() { |
3291 if (HasSmiValue()) return Representation::Smi(); | 3298 if (HasSmiValue() && kSmiValueSize == 31) return Representation::Smi(); |
3292 if (HasInteger32Value()) return Representation::Integer32(); | 3299 if (HasInteger32Value()) return Representation::Integer32(); |
3293 if (HasNumberValue()) return Representation::Double(); | 3300 if (HasNumberValue()) return Representation::Double(); |
3294 return Representation::Tagged(); | 3301 return Representation::Tagged(); |
3295 } | 3302 } |
3296 | 3303 |
3297 virtual bool EmitAtUses(); | 3304 virtual bool EmitAtUses(); |
3298 virtual void PrintDataTo(StringStream* stream); | 3305 virtual void PrintDataTo(StringStream* stream); |
3299 virtual HType CalculateInferredType(); | 3306 virtual HType CalculateInferredType(); |
3300 bool IsInteger() { return handle()->IsSmi(); } | 3307 bool IsInteger() { return handle()->IsSmi(); } |
3301 HConstant* CopyToRepresentation(Representation r, Zone* zone) const; | 3308 HConstant* CopyToRepresentation(Representation r, Zone* zone) const; |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3443 if (!IsCommutative()) return false; | 3450 if (!IsCommutative()) return false; |
3444 | 3451 |
3445 // Constant operands are better off on the right, they can be inlined in | 3452 // Constant operands are better off on the right, they can be inlined in |
3446 // many situations on most platforms. | 3453 // many situations on most platforms. |
3447 if (left()->IsConstant()) return true; | 3454 if (left()->IsConstant()) return true; |
3448 if (right()->IsConstant()) return false; | 3455 if (right()->IsConstant()) return false; |
3449 | 3456 |
3450 // Otherwise, if there is only one use of the right operand, it would be | 3457 // 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 | 3458 // better off on the left for platforms that only have 2-arg arithmetic |
3452 // ops (e.g ia32, x64) that clobber the left operand. | 3459 // ops (e.g ia32, x64) that clobber the left operand. |
3453 return (right()->UseCount() == 1); | 3460 return right()->UseCount() == 1; |
3454 } | 3461 } |
3455 | 3462 |
3456 HValue* BetterLeftOperand() { | 3463 HValue* BetterLeftOperand() { |
3457 return AreOperandsBetterSwitched() ? right() : left(); | 3464 return AreOperandsBetterSwitched() ? right() : left(); |
3458 } | 3465 } |
3459 | 3466 |
3460 HValue* BetterRightOperand() { | 3467 HValue* BetterRightOperand() { |
3461 return AreOperandsBetterSwitched() ? left() : right(); | 3468 return AreOperandsBetterSwitched() ? left() : right(); |
3462 } | 3469 } |
3463 | 3470 |
3464 void set_observed_input_representation(int index, Representation rep) { | 3471 void set_observed_input_representation(int index, Representation rep) { |
3465 ASSERT(index >= 1 && index <= 2); | 3472 ASSERT(index >= 1 && index <= 2); |
3466 observed_input_representation_[index - 1] = rep; | 3473 observed_input_representation_[index - 1] = rep; |
3467 } | 3474 } |
3468 | 3475 |
3469 virtual void initialize_output_representation(Representation observed) { | 3476 virtual void initialize_output_representation(Representation observed) { |
3470 observed_output_representation_ = observed; | 3477 observed_output_representation_ = observed; |
3471 } | 3478 } |
3472 | 3479 |
3473 virtual Representation observed_input_representation(int index) { | 3480 virtual Representation observed_input_representation(int index) { |
3474 if (index == 0) return Representation::Tagged(); | 3481 if (index == 0) return Representation::Tagged(); |
3475 return observed_input_representation_[index - 1]; | 3482 return observed_input_representation_[index - 1]; |
3476 } | 3483 } |
3477 | 3484 |
3485 virtual void UpdateRepresentation(Representation new_rep, | |
3486 HInferRepresentationPhase* h_infer, | |
3487 const char* reason) { | |
3488 Representation rep = !FLAG_smi_binop && new_rep.IsSmi() | |
3489 ? Representation::Integer32() : new_rep; | |
3490 HValue::UpdateRepresentation(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 (new_rep.IsSmi()) new_rep = Representation::Integer32(); | |
4482 HArithmeticBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason); | |
4483 } | |
4484 | |
4467 DECLARE_CONCRETE_INSTRUCTION(Mod) | 4485 DECLARE_CONCRETE_INSTRUCTION(Mod) |
4468 | 4486 |
4469 protected: | 4487 protected: |
4470 virtual bool DataEquals(HValue* other) { return true; } | 4488 virtual bool DataEquals(HValue* other) { return true; } |
4471 | 4489 |
4472 virtual Range* InferRange(Zone* zone); | 4490 virtual Range* InferRange(Zone* zone); |
4473 | 4491 |
4474 private: | 4492 private: |
4475 HMod(HValue* context, | 4493 HMod(HValue* context, |
4476 HValue* left, | 4494 HValue* left, |
(...skipping 22 matching lines...) Expand all Loading... | |
4499 return value != 0 && (IsPowerOf2(value) || IsPowerOf2(-value)); | 4517 return value != 0 && (IsPowerOf2(value) || IsPowerOf2(-value)); |
4500 } | 4518 } |
4501 | 4519 |
4502 return false; | 4520 return false; |
4503 } | 4521 } |
4504 | 4522 |
4505 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); | 4523 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); |
4506 | 4524 |
4507 virtual HValue* Canonicalize(); | 4525 virtual HValue* Canonicalize(); |
4508 | 4526 |
4527 virtual void UpdateRepresentation(Representation new_rep, | |
4528 HInferRepresentationPhase* h_infer, | |
4529 const char* reason) { | |
4530 if (new_rep.IsSmi()) new_rep = Representation::Integer32(); | |
4531 HArithmeticBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason); | |
4532 } | |
4533 | |
4509 DECLARE_CONCRETE_INSTRUCTION(Div) | 4534 DECLARE_CONCRETE_INSTRUCTION(Div) |
4510 | 4535 |
4511 protected: | 4536 protected: |
4512 virtual bool DataEquals(HValue* other) { return true; } | 4537 virtual bool DataEquals(HValue* other) { return true; } |
4513 | 4538 |
4514 virtual Range* InferRange(Zone* zone); | 4539 virtual Range* InferRange(Zone* zone); |
4515 | 4540 |
4516 private: | 4541 private: |
4517 HDiv(HValue* context, HValue* left, HValue* right) | 4542 HDiv(HValue* context, HValue* left, HValue* right) |
4518 : HArithmeticBinaryOperation(context, left, right) { | 4543 : HArithmeticBinaryOperation(context, left, right) { |
(...skipping 20 matching lines...) Expand all Loading... | |
4539 | 4564 |
4540 virtual Representation observed_input_representation(int index) { | 4565 virtual Representation observed_input_representation(int index) { |
4541 return RequiredInputRepresentation(index); | 4566 return RequiredInputRepresentation(index); |
4542 } | 4567 } |
4543 | 4568 |
4544 virtual void InferRepresentation(HInferRepresentationPhase* h_infer); | 4569 virtual void InferRepresentation(HInferRepresentationPhase* h_infer); |
4545 | 4570 |
4546 virtual Representation RepresentationFromInputs() { | 4571 virtual Representation RepresentationFromInputs() { |
4547 Representation left_rep = left()->representation(); | 4572 Representation left_rep = left()->representation(); |
4548 Representation right_rep = right()->representation(); | 4573 Representation right_rep = right()->representation(); |
4549 if ((left_rep.IsNone() || left_rep.IsInteger32()) && | 4574 Representation result = Representation::Smi(); |
4550 (right_rep.IsNone() || right_rep.IsInteger32())) { | 4575 result = result.generalize(left_rep); |
4551 return Representation::Integer32(); | 4576 result = result.generalize(right_rep); |
4552 } | 4577 if (result.IsTagged()) return Representation::Double(); |
4553 return Representation::Double(); | 4578 return result; |
4554 } | 4579 } |
4555 | 4580 |
4556 virtual bool IsCommutative() const { return true; } | 4581 virtual bool IsCommutative() const { return true; } |
4557 | 4582 |
4558 Operation operation() { return operation_; } | 4583 Operation operation() { return operation_; } |
4559 | 4584 |
4560 DECLARE_CONCRETE_INSTRUCTION(MathMinMax) | 4585 DECLARE_CONCRETE_INSTRUCTION(MathMinMax) |
4561 | 4586 |
4562 protected: | 4587 protected: |
4563 virtual bool DataEquals(HValue* other) { | 4588 virtual bool DataEquals(HValue* other) { |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4598 virtual bool DataEquals(HValue* other) { | 4623 virtual bool DataEquals(HValue* other) { |
4599 return op() == HBitwise::cast(other)->op(); | 4624 return op() == HBitwise::cast(other)->op(); |
4600 } | 4625 } |
4601 | 4626 |
4602 virtual Range* InferRange(Zone* zone); | 4627 virtual Range* InferRange(Zone* zone); |
4603 | 4628 |
4604 private: | 4629 private: |
4605 HBitwise(Token::Value op, HValue* context, HValue* left, HValue* right) | 4630 HBitwise(Token::Value op, HValue* context, HValue* left, HValue* right) |
4606 : HBitwiseBinaryOperation(context, left, right), op_(op) { | 4631 : HBitwiseBinaryOperation(context, left, right), op_(op) { |
4607 ASSERT(op == Token::BIT_AND || op == Token::BIT_OR || op == Token::BIT_XOR); | 4632 ASSERT(op == Token::BIT_AND || op == Token::BIT_OR || op == Token::BIT_XOR); |
4633 // BIT_AND with a smi-range positive value will always unset the | |
4634 // entire sign-extension of the smi-sign. | |
4635 if (op == Token::BIT_AND && | |
4636 ((left->IsConstant() && | |
4637 left->representation().IsSmi() && | |
4638 HConstant::cast(left)->Integer32Value() >= 0) || | |
4639 (right->IsConstant() && | |
4640 right->representation().IsSmi() && | |
4641 HConstant::cast(right)->Integer32Value() >= 0))) { | |
4642 SetFlag(kTruncatingToSmi); | |
4643 // BIT_OR with a smi-range negative value will always set the entire | |
4644 // sign-extension of the smi-sign. | |
4645 } else if (op == Token::BIT_OR && | |
Sven Panne
2013/07/25 06:05:58
Can we come up with a case for BIT_XOR? :-)
Toon Verwaest
2013/07/25 09:29:24
I guess not: Even if all the sign-extended bits ar
| |
4646 ((left->IsConstant() && | |
4647 left->representation().IsSmi() && | |
4648 HConstant::cast(left)->Integer32Value() < 0) || | |
4649 (right->IsConstant() && | |
4650 right->representation().IsSmi() && | |
4651 HConstant::cast(right)->Integer32Value() < 0))) { | |
4652 SetFlag(kTruncatingToSmi); | |
4653 } | |
4608 } | 4654 } |
4609 | 4655 |
4610 Token::Value op_; | 4656 Token::Value op_; |
4611 }; | 4657 }; |
4612 | 4658 |
4613 | 4659 |
4614 class HShl: public HBitwiseBinaryOperation { | 4660 class HShl: public HBitwiseBinaryOperation { |
4615 public: | 4661 public: |
4616 static HInstruction* New(Zone* zone, | 4662 static HInstruction* New(Zone* zone, |
4617 HValue* context, | 4663 HValue* context, |
4618 HValue* left, | 4664 HValue* left, |
4619 HValue* right); | 4665 HValue* right); |
4620 | 4666 |
4621 virtual Range* InferRange(Zone* zone); | 4667 virtual Range* InferRange(Zone* zone); |
4622 | 4668 |
4669 virtual void UpdateRepresentation(Representation new_rep, | |
4670 HInferRepresentationPhase* h_infer, | |
4671 const char* reason) { | |
4672 if (new_rep.IsSmi()) new_rep = Representation::Integer32(); | |
4673 HBitwiseBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason); | |
4674 } | |
4675 | |
4623 DECLARE_CONCRETE_INSTRUCTION(Shl) | 4676 DECLARE_CONCRETE_INSTRUCTION(Shl) |
4624 | 4677 |
4625 protected: | 4678 protected: |
4626 virtual bool DataEquals(HValue* other) { return true; } | 4679 virtual bool DataEquals(HValue* other) { return true; } |
4627 | 4680 |
4628 private: | 4681 private: |
4629 HShl(HValue* context, HValue* left, HValue* right) | 4682 HShl(HValue* context, HValue* left, HValue* right) |
4630 : HBitwiseBinaryOperation(context, left, right) { } | 4683 : HBitwiseBinaryOperation(context, left, right) { } |
4631 }; | 4684 }; |
4632 | 4685 |
(...skipping 12 matching lines...) Expand all Loading... | |
4645 // like ((base + offset) >> scale) with one single decomposition. | 4698 // like ((base + offset) >> scale) with one single decomposition. |
4646 left()->TryDecompose(decomposition); | 4699 left()->TryDecompose(decomposition); |
4647 return true; | 4700 return true; |
4648 } | 4701 } |
4649 } | 4702 } |
4650 return false; | 4703 return false; |
4651 } | 4704 } |
4652 | 4705 |
4653 virtual Range* InferRange(Zone* zone); | 4706 virtual Range* InferRange(Zone* zone); |
4654 | 4707 |
4708 virtual void UpdateRepresentation(Representation new_rep, | |
4709 HInferRepresentationPhase* h_infer, | |
4710 const char* reason) { | |
4711 if (new_rep.IsSmi()) new_rep = Representation::Integer32(); | |
4712 HBitwiseBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason); | |
4713 } | |
4714 | |
4655 DECLARE_CONCRETE_INSTRUCTION(Shr) | 4715 DECLARE_CONCRETE_INSTRUCTION(Shr) |
4656 | 4716 |
4657 protected: | 4717 protected: |
4658 virtual bool DataEquals(HValue* other) { return true; } | 4718 virtual bool DataEquals(HValue* other) { return true; } |
4659 | 4719 |
4660 private: | 4720 private: |
4661 HShr(HValue* context, HValue* left, HValue* right) | 4721 HShr(HValue* context, HValue* left, HValue* right) |
4662 : HBitwiseBinaryOperation(context, left, right) { } | 4722 : HBitwiseBinaryOperation(context, left, right) { } |
4663 }; | 4723 }; |
4664 | 4724 |
(...skipping 12 matching lines...) Expand all Loading... | |
4677 // like ((base + offset) >> scale) with one single decomposition. | 4737 // like ((base + offset) >> scale) with one single decomposition. |
4678 left()->TryDecompose(decomposition); | 4738 left()->TryDecompose(decomposition); |
4679 return true; | 4739 return true; |
4680 } | 4740 } |
4681 } | 4741 } |
4682 return false; | 4742 return false; |
4683 } | 4743 } |
4684 | 4744 |
4685 virtual Range* InferRange(Zone* zone); | 4745 virtual Range* InferRange(Zone* zone); |
4686 | 4746 |
4747 virtual void UpdateRepresentation(Representation new_rep, | |
4748 HInferRepresentationPhase* h_infer, | |
4749 const char* reason) { | |
4750 if (new_rep.IsSmi()) new_rep = Representation::Integer32(); | |
4751 HBitwiseBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason); | |
4752 } | |
4753 | |
4687 DECLARE_CONCRETE_INSTRUCTION(Sar) | 4754 DECLARE_CONCRETE_INSTRUCTION(Sar) |
4688 | 4755 |
4689 protected: | 4756 protected: |
4690 virtual bool DataEquals(HValue* other) { return true; } | 4757 virtual bool DataEquals(HValue* other) { return true; } |
4691 | 4758 |
4692 private: | 4759 private: |
4693 HSar(HValue* context, HValue* left, HValue* right) | 4760 HSar(HValue* context, HValue* left, HValue* right) |
4694 : HBitwiseBinaryOperation(context, left, right) { } | 4761 : HBitwiseBinaryOperation(context, left, right) { } |
4695 }; | 4762 }; |
4696 | 4763 |
4697 | 4764 |
4698 class HRor: public HBitwiseBinaryOperation { | 4765 class HRor: public HBitwiseBinaryOperation { |
4699 public: | 4766 public: |
4700 HRor(HValue* context, HValue* left, HValue* right) | 4767 HRor(HValue* context, HValue* left, HValue* right) |
4701 : HBitwiseBinaryOperation(context, left, right) { | 4768 : HBitwiseBinaryOperation(context, left, right) { |
4702 ChangeRepresentation(Representation::Integer32()); | 4769 ChangeRepresentation(Representation::Integer32()); |
4703 } | 4770 } |
4704 | 4771 |
4772 virtual void UpdateRepresentation(Representation new_rep, | |
4773 HInferRepresentationPhase* h_infer, | |
4774 const char* reason) { | |
4775 if (new_rep.IsSmi()) new_rep = Representation::Integer32(); | |
4776 HBitwiseBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason); | |
4777 } | |
4778 | |
4705 DECLARE_CONCRETE_INSTRUCTION(Ror) | 4779 DECLARE_CONCRETE_INSTRUCTION(Ror) |
4706 | 4780 |
4707 protected: | 4781 protected: |
4708 virtual bool DataEquals(HValue* other) { return true; } | 4782 virtual bool DataEquals(HValue* other) { return true; } |
4709 }; | 4783 }; |
4710 | 4784 |
4711 | 4785 |
4712 class HOsrEntry: public HTemplateInstruction<0> { | 4786 class HOsrEntry: public HTemplateInstruction<0> { |
4713 public: | 4787 public: |
4714 explicit HOsrEntry(BailoutId ast_id) : ast_id_(ast_id) { | 4788 explicit HOsrEntry(BailoutId ast_id) : ast_id_(ast_id) { |
(...skipping 1922 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6637 virtual bool IsDeletable() const { return true; } | 6711 virtual bool IsDeletable() const { return true; } |
6638 }; | 6712 }; |
6639 | 6713 |
6640 | 6714 |
6641 #undef DECLARE_INSTRUCTION | 6715 #undef DECLARE_INSTRUCTION |
6642 #undef DECLARE_CONCRETE_INSTRUCTION | 6716 #undef DECLARE_CONCRETE_INSTRUCTION |
6643 | 6717 |
6644 } } // namespace v8::internal | 6718 } } // namespace v8::internal |
6645 | 6719 |
6646 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ | 6720 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ |
OLD | NEW |