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 799 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3437 HValue* context() { return OperandAt(0); } | 3444 HValue* context() { return OperandAt(0); } |
3438 HValue* left() { return OperandAt(1); } | 3445 HValue* left() { return OperandAt(1); } |
3439 HValue* right() { return OperandAt(2); } | 3446 HValue* right() { return OperandAt(2); } |
3440 | 3447 |
3441 // True if switching left and right operands likely generates better code. | 3448 // True if switching left and right operands likely generates better code. |
3442 bool AreOperandsBetterSwitched() { | 3449 bool AreOperandsBetterSwitched() { |
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. |
3454 if (right()->IsConstant()) return false; | |
Sven Panne
2013/07/24 11:38:36
Let's hope that this change doesn't have subtle pe
Toon Verwaest
2013/07/24 13:24:01
Restored to its original form.
On 2013/07/24 11:3
| |
3447 if (left()->IsConstant()) return true; | 3455 if (left()->IsConstant()) return true; |
3448 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 if (!FLAG_smi_binop) { | |
Sven Panne
2013/07/24 11:38:36
Nit: I think that
if (new_rep.IsSmi() && !FLAG
Toon Verwaest
2013/07/24 13:24:01
Done.
| |
3489 if (new_rep.IsSmi()) new_rep = Representation::Integer32(); | |
3490 } | |
3491 HValue::UpdateRepresentation(new_rep, h_infer, reason); | |
3492 } | |
3493 | |
3478 virtual void InferRepresentation(HInferRepresentationPhase* h_infer); | 3494 virtual void InferRepresentation(HInferRepresentationPhase* h_infer); |
3479 virtual Representation RepresentationFromInputs(); | 3495 virtual Representation RepresentationFromInputs(); |
3496 Representation RepresentationFromOutput(); | |
3480 virtual void AssumeRepresentation(Representation r); | 3497 virtual void AssumeRepresentation(Representation r); |
3481 | 3498 |
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; } | 3499 virtual bool IsCommutative() const { return false; } |
3493 | 3500 |
3494 virtual void PrintDataTo(StringStream* stream); | 3501 virtual void PrintDataTo(StringStream* stream); |
3495 | 3502 |
3503 virtual Representation RequiredInputRepresentation(int index) { | |
3504 if (index == 0) return Representation::Tagged(); | |
3505 return representation(); | |
3506 } | |
3507 | |
3496 DECLARE_ABSTRACT_INSTRUCTION(BinaryOperation) | 3508 DECLARE_ABSTRACT_INSTRUCTION(BinaryOperation) |
3497 | 3509 |
3498 private: | 3510 private: |
3499 bool IgnoreObservedOutputRepresentation(Representation current_rep); | 3511 bool IgnoreObservedOutputRepresentation(Representation current_rep); |
3500 | 3512 |
3501 Representation observed_input_representation_[2]; | 3513 Representation observed_input_representation_[2]; |
3502 Representation observed_output_representation_; | 3514 Representation observed_output_representation_; |
3503 }; | 3515 }; |
3504 | 3516 |
3505 | 3517 |
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3764 class HBitwiseBinaryOperation: public HBinaryOperation { | 3776 class HBitwiseBinaryOperation: public HBinaryOperation { |
3765 public: | 3777 public: |
3766 HBitwiseBinaryOperation(HValue* context, HValue* left, HValue* right) | 3778 HBitwiseBinaryOperation(HValue* context, HValue* left, HValue* right) |
3767 : HBinaryOperation(context, left, right) { | 3779 : HBinaryOperation(context, left, right) { |
3768 SetFlag(kFlexibleRepresentation); | 3780 SetFlag(kFlexibleRepresentation); |
3769 SetFlag(kTruncatingToInt32); | 3781 SetFlag(kTruncatingToInt32); |
3770 SetFlag(kAllowUndefinedAsNaN); | 3782 SetFlag(kAllowUndefinedAsNaN); |
3771 SetAllSideEffects(); | 3783 SetAllSideEffects(); |
3772 } | 3784 } |
3773 | 3785 |
3774 virtual Representation RequiredInputRepresentation(int index) { | |
3775 return index == 0 | |
3776 ? Representation::Tagged() | |
3777 : representation(); | |
3778 } | |
3779 | |
3780 virtual void RepresentationChanged(Representation to) { | 3786 virtual void RepresentationChanged(Representation to) { |
3781 if (!to.IsTagged()) { | 3787 if (!to.IsTagged()) { |
3782 ASSERT(to.IsInteger32()); | 3788 ASSERT(to.IsSmiOrInteger32()); |
3783 ClearAllSideEffects(); | 3789 ClearAllSideEffects(); |
3784 SetFlag(kUseGVN); | 3790 SetFlag(kUseGVN); |
3785 } else { | 3791 } else { |
3786 SetAllSideEffects(); | 3792 SetAllSideEffects(); |
3787 ClearFlag(kUseGVN); | 3793 ClearFlag(kUseGVN); |
3788 } | 3794 } |
3789 } | 3795 } |
3790 | 3796 |
3791 virtual void UpdateRepresentation(Representation new_rep, | 3797 virtual void UpdateRepresentation(Representation new_rep, |
3792 HInferRepresentationPhase* h_infer, | 3798 HInferRepresentationPhase* h_infer, |
3793 const char* reason) { | 3799 const char* reason) { |
3794 // We only generate either int32 or generic tagged bitwise operations. | 3800 // We only generate either int32 or generic tagged bitwise operations. |
3795 if (new_rep.IsSmi() || new_rep.IsDouble()) { | 3801 if (new_rep.IsDouble()) new_rep = Representation::Integer32(); |
3796 new_rep = Representation::Integer32(); | 3802 HBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason); |
3797 } | 3803 } |
3798 HValue::UpdateRepresentation(new_rep, h_infer, reason); | 3804 |
3805 virtual Representation observed_input_representation(int index) { | |
3806 Representation r = HBinaryOperation::observed_input_representation(index); | |
3807 if (r.IsDouble()) return Representation::Integer32(); | |
3808 return r; | |
3799 } | 3809 } |
3800 | 3810 |
3801 virtual void initialize_output_representation(Representation observed) { | 3811 virtual void initialize_output_representation(Representation observed) { |
3802 if (observed.IsDouble()) observed = Representation::Integer32(); | 3812 if (observed.IsDouble()) observed = Representation::Integer32(); |
3803 HBinaryOperation::initialize_output_representation(observed); | 3813 HBinaryOperation::initialize_output_representation(observed); |
3804 } | 3814 } |
3805 | 3815 |
3806 virtual HType CalculateInferredType(); | 3816 virtual HType CalculateInferredType(); |
3807 | 3817 |
3808 DECLARE_ABSTRACT_INSTRUCTION(BitwiseBinaryOperation) | 3818 DECLARE_ABSTRACT_INSTRUCTION(BitwiseBinaryOperation) |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3854 if (to.IsTagged()) { | 3864 if (to.IsTagged()) { |
3855 SetAllSideEffects(); | 3865 SetAllSideEffects(); |
3856 ClearFlag(kUseGVN); | 3866 ClearFlag(kUseGVN); |
3857 } else { | 3867 } else { |
3858 ClearAllSideEffects(); | 3868 ClearAllSideEffects(); |
3859 SetFlag(kUseGVN); | 3869 SetFlag(kUseGVN); |
3860 } | 3870 } |
3861 } | 3871 } |
3862 | 3872 |
3863 virtual HType CalculateInferredType(); | 3873 virtual HType CalculateInferredType(); |
3864 virtual Representation RequiredInputRepresentation(int index) { | |
3865 return index == 0 | |
3866 ? Representation::Tagged() | |
3867 : representation(); | |
3868 } | |
3869 | 3874 |
3870 DECLARE_ABSTRACT_INSTRUCTION(ArithmeticBinaryOperation) | 3875 DECLARE_ABSTRACT_INSTRUCTION(ArithmeticBinaryOperation) |
3871 | 3876 |
3872 private: | 3877 private: |
3873 virtual bool IsDeletable() const { return true; } | 3878 virtual bool IsDeletable() const { return true; } |
3874 }; | 3879 }; |
3875 | 3880 |
3876 | 3881 |
3877 class HCompareGeneric: public HBinaryOperation { | 3882 class HCompareGeneric: public HBinaryOperation { |
3878 public: | 3883 public: |
(...skipping 539 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4418 | 4423 |
4419 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); | 4424 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); |
4420 | 4425 |
4421 virtual HValue* Canonicalize(); | 4426 virtual HValue* Canonicalize(); |
4422 | 4427 |
4423 // Only commutative if it is certain that not two objects are multiplicated. | 4428 // Only commutative if it is certain that not two objects are multiplicated. |
4424 virtual bool IsCommutative() const { | 4429 virtual bool IsCommutative() const { |
4425 return !representation().IsTagged(); | 4430 return !representation().IsTagged(); |
4426 } | 4431 } |
4427 | 4432 |
4433 virtual void UpdateRepresentation(Representation new_rep, | |
4434 HInferRepresentationPhase* h_infer, | |
4435 const char* reason) { | |
4436 if (new_rep.IsSmi()) new_rep = Representation::Integer32(); | |
4437 HArithmeticBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason); | |
4438 } | |
4439 | |
4428 DECLARE_CONCRETE_INSTRUCTION(Mul) | 4440 DECLARE_CONCRETE_INSTRUCTION(Mul) |
4429 | 4441 |
4430 protected: | 4442 protected: |
4431 virtual bool DataEquals(HValue* other) { return true; } | 4443 virtual bool DataEquals(HValue* other) { return true; } |
4432 | 4444 |
4433 virtual Range* InferRange(Zone* zone); | 4445 virtual Range* InferRange(Zone* zone); |
4434 | 4446 |
4435 private: | 4447 private: |
4436 HMul(HValue* context, HValue* left, HValue* right) | 4448 HMul(HValue* context, HValue* left, HValue* right) |
4437 : HArithmeticBinaryOperation(context, left, right) { | 4449 : HArithmeticBinaryOperation(context, left, right) { |
(...skipping 19 matching lines...) Expand all Loading... | |
4457 return value != 0 && (IsPowerOf2(value) || IsPowerOf2(-value)); | 4469 return value != 0 && (IsPowerOf2(value) || IsPowerOf2(-value)); |
4458 } | 4470 } |
4459 | 4471 |
4460 return false; | 4472 return false; |
4461 } | 4473 } |
4462 | 4474 |
4463 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); | 4475 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); |
4464 | 4476 |
4465 virtual HValue* Canonicalize(); | 4477 virtual HValue* Canonicalize(); |
4466 | 4478 |
4479 virtual void UpdateRepresentation(Representation new_rep, | |
4480 HInferRepresentationPhase* h_infer, | |
4481 const char* reason) { | |
4482 if (new_rep.IsSmi()) new_rep = Representation::Integer32(); | |
4483 HArithmeticBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason); | |
4484 } | |
4485 | |
4467 DECLARE_CONCRETE_INSTRUCTION(Mod) | 4486 DECLARE_CONCRETE_INSTRUCTION(Mod) |
4468 | 4487 |
4469 protected: | 4488 protected: |
4470 virtual bool DataEquals(HValue* other) { return true; } | 4489 virtual bool DataEquals(HValue* other) { return true; } |
4471 | 4490 |
4472 virtual Range* InferRange(Zone* zone); | 4491 virtual Range* InferRange(Zone* zone); |
4473 | 4492 |
4474 private: | 4493 private: |
4475 HMod(HValue* context, | 4494 HMod(HValue* context, |
4476 HValue* left, | 4495 HValue* left, |
(...skipping 22 matching lines...) Expand all Loading... | |
4499 return value != 0 && (IsPowerOf2(value) || IsPowerOf2(-value)); | 4518 return value != 0 && (IsPowerOf2(value) || IsPowerOf2(-value)); |
4500 } | 4519 } |
4501 | 4520 |
4502 return false; | 4521 return false; |
4503 } | 4522 } |
4504 | 4523 |
4505 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); | 4524 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); |
4506 | 4525 |
4507 virtual HValue* Canonicalize(); | 4526 virtual HValue* Canonicalize(); |
4508 | 4527 |
4528 virtual void UpdateRepresentation(Representation new_rep, | |
4529 HInferRepresentationPhase* h_infer, | |
4530 const char* reason) { | |
4531 if (new_rep.IsSmi()) new_rep = Representation::Integer32(); | |
4532 HArithmeticBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason); | |
4533 } | |
4534 | |
4509 DECLARE_CONCRETE_INSTRUCTION(Div) | 4535 DECLARE_CONCRETE_INSTRUCTION(Div) |
4510 | 4536 |
4511 protected: | 4537 protected: |
4512 virtual bool DataEquals(HValue* other) { return true; } | 4538 virtual bool DataEquals(HValue* other) { return true; } |
4513 | 4539 |
4514 virtual Range* InferRange(Zone* zone); | 4540 virtual Range* InferRange(Zone* zone); |
4515 | 4541 |
4516 private: | 4542 private: |
4517 HDiv(HValue* context, HValue* left, HValue* right) | 4543 HDiv(HValue* context, HValue* left, HValue* right) |
4518 : HArithmeticBinaryOperation(context, left, right) { | 4544 : HArithmeticBinaryOperation(context, left, right) { |
(...skipping 20 matching lines...) Expand all Loading... | |
4539 | 4565 |
4540 virtual Representation observed_input_representation(int index) { | 4566 virtual Representation observed_input_representation(int index) { |
4541 return RequiredInputRepresentation(index); | 4567 return RequiredInputRepresentation(index); |
4542 } | 4568 } |
4543 | 4569 |
4544 virtual void InferRepresentation(HInferRepresentationPhase* h_infer); | 4570 virtual void InferRepresentation(HInferRepresentationPhase* h_infer); |
4545 | 4571 |
4546 virtual Representation RepresentationFromInputs() { | 4572 virtual Representation RepresentationFromInputs() { |
4547 Representation left_rep = left()->representation(); | 4573 Representation left_rep = left()->representation(); |
4548 Representation right_rep = right()->representation(); | 4574 Representation right_rep = right()->representation(); |
4549 if ((left_rep.IsNone() || left_rep.IsInteger32()) && | 4575 Representation result = Representation::Smi(); |
4550 (right_rep.IsNone() || right_rep.IsInteger32())) { | 4576 result = result.generalize(left_rep); |
4551 return Representation::Integer32(); | 4577 result = result.generalize(right_rep); |
4552 } | 4578 if (result.IsTagged()) return Representation::Double(); |
4553 return Representation::Double(); | 4579 return result; |
4554 } | 4580 } |
4555 | 4581 |
4556 virtual bool IsCommutative() const { return true; } | 4582 virtual bool IsCommutative() const { return true; } |
4557 | 4583 |
4558 Operation operation() { return operation_; } | 4584 Operation operation() { return operation_; } |
4559 | 4585 |
4560 DECLARE_CONCRETE_INSTRUCTION(MathMinMax) | 4586 DECLARE_CONCRETE_INSTRUCTION(MathMinMax) |
4561 | 4587 |
4562 protected: | 4588 protected: |
4563 virtual bool DataEquals(HValue* other) { | 4589 virtual bool DataEquals(HValue* other) { |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4598 virtual bool DataEquals(HValue* other) { | 4624 virtual bool DataEquals(HValue* other) { |
4599 return op() == HBitwise::cast(other)->op(); | 4625 return op() == HBitwise::cast(other)->op(); |
4600 } | 4626 } |
4601 | 4627 |
4602 virtual Range* InferRange(Zone* zone); | 4628 virtual Range* InferRange(Zone* zone); |
4603 | 4629 |
4604 private: | 4630 private: |
4605 HBitwise(Token::Value op, HValue* context, HValue* left, HValue* right) | 4631 HBitwise(Token::Value op, HValue* context, HValue* left, HValue* right) |
4606 : HBitwiseBinaryOperation(context, left, right), op_(op) { | 4632 : HBitwiseBinaryOperation(context, left, right), op_(op) { |
4607 ASSERT(op == Token::BIT_AND || op == Token::BIT_OR || op == Token::BIT_XOR); | 4633 ASSERT(op == Token::BIT_AND || op == Token::BIT_OR || op == Token::BIT_XOR); |
4634 if (op == Token::BIT_AND && | |
4635 ((left->IsConstant() && left->representation().IsSmi()) || | |
4636 (right->IsConstant() && right->representation().IsSmi()))) { | |
4637 SetFlag(kTruncatingToSmi); | |
Sven Panne
2013/07/24 11:38:36
I don't understand this part. Why is this correct?
Toon Verwaest
2013/07/24 13:24:01
Adjusted to >= 0 for bitand, and added a case for
| |
4638 } | |
4608 } | 4639 } |
4609 | 4640 |
4610 Token::Value op_; | 4641 Token::Value op_; |
4611 }; | 4642 }; |
4612 | 4643 |
4613 | 4644 |
4614 class HShl: public HBitwiseBinaryOperation { | 4645 class HShl: public HBitwiseBinaryOperation { |
4615 public: | 4646 public: |
4616 static HInstruction* New(Zone* zone, | 4647 static HInstruction* New(Zone* zone, |
4617 HValue* context, | 4648 HValue* context, |
4618 HValue* left, | 4649 HValue* left, |
4619 HValue* right); | 4650 HValue* right); |
4620 | 4651 |
4621 virtual Range* InferRange(Zone* zone); | 4652 virtual Range* InferRange(Zone* zone); |
4622 | 4653 |
4654 virtual void UpdateRepresentation(Representation new_rep, | |
4655 HInferRepresentationPhase* h_infer, | |
4656 const char* reason) { | |
4657 if (new_rep.IsSmi()) new_rep = Representation::Integer32(); | |
4658 HBitwiseBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason); | |
4659 } | |
4660 | |
4623 DECLARE_CONCRETE_INSTRUCTION(Shl) | 4661 DECLARE_CONCRETE_INSTRUCTION(Shl) |
4624 | 4662 |
4625 protected: | 4663 protected: |
4626 virtual bool DataEquals(HValue* other) { return true; } | 4664 virtual bool DataEquals(HValue* other) { return true; } |
4627 | 4665 |
4628 private: | 4666 private: |
4629 HShl(HValue* context, HValue* left, HValue* right) | 4667 HShl(HValue* context, HValue* left, HValue* right) |
4630 : HBitwiseBinaryOperation(context, left, right) { } | 4668 : HBitwiseBinaryOperation(context, left, right) { } |
4631 }; | 4669 }; |
4632 | 4670 |
(...skipping 12 matching lines...) Expand all Loading... | |
4645 // like ((base + offset) >> scale) with one single decomposition. | 4683 // like ((base + offset) >> scale) with one single decomposition. |
4646 left()->TryDecompose(decomposition); | 4684 left()->TryDecompose(decomposition); |
4647 return true; | 4685 return true; |
4648 } | 4686 } |
4649 } | 4687 } |
4650 return false; | 4688 return false; |
4651 } | 4689 } |
4652 | 4690 |
4653 virtual Range* InferRange(Zone* zone); | 4691 virtual Range* InferRange(Zone* zone); |
4654 | 4692 |
4693 virtual void UpdateRepresentation(Representation new_rep, | |
4694 HInferRepresentationPhase* h_infer, | |
4695 const char* reason) { | |
4696 if (new_rep.IsSmi()) new_rep = Representation::Integer32(); | |
4697 HBitwiseBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason); | |
4698 } | |
4699 | |
4655 DECLARE_CONCRETE_INSTRUCTION(Shr) | 4700 DECLARE_CONCRETE_INSTRUCTION(Shr) |
4656 | 4701 |
4657 protected: | 4702 protected: |
4658 virtual bool DataEquals(HValue* other) { return true; } | 4703 virtual bool DataEquals(HValue* other) { return true; } |
4659 | 4704 |
4660 private: | 4705 private: |
4661 HShr(HValue* context, HValue* left, HValue* right) | 4706 HShr(HValue* context, HValue* left, HValue* right) |
4662 : HBitwiseBinaryOperation(context, left, right) { } | 4707 : HBitwiseBinaryOperation(context, left, right) { } |
4663 }; | 4708 }; |
4664 | 4709 |
(...skipping 12 matching lines...) Expand all Loading... | |
4677 // like ((base + offset) >> scale) with one single decomposition. | 4722 // like ((base + offset) >> scale) with one single decomposition. |
4678 left()->TryDecompose(decomposition); | 4723 left()->TryDecompose(decomposition); |
4679 return true; | 4724 return true; |
4680 } | 4725 } |
4681 } | 4726 } |
4682 return false; | 4727 return false; |
4683 } | 4728 } |
4684 | 4729 |
4685 virtual Range* InferRange(Zone* zone); | 4730 virtual Range* InferRange(Zone* zone); |
4686 | 4731 |
4732 virtual void UpdateRepresentation(Representation new_rep, | |
4733 HInferRepresentationPhase* h_infer, | |
4734 const char* reason) { | |
4735 if (new_rep.IsSmi()) new_rep = Representation::Integer32(); | |
4736 HBitwiseBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason); | |
4737 } | |
4738 | |
4687 DECLARE_CONCRETE_INSTRUCTION(Sar) | 4739 DECLARE_CONCRETE_INSTRUCTION(Sar) |
4688 | 4740 |
4689 protected: | 4741 protected: |
4690 virtual bool DataEquals(HValue* other) { return true; } | 4742 virtual bool DataEquals(HValue* other) { return true; } |
4691 | 4743 |
4692 private: | 4744 private: |
4693 HSar(HValue* context, HValue* left, HValue* right) | 4745 HSar(HValue* context, HValue* left, HValue* right) |
4694 : HBitwiseBinaryOperation(context, left, right) { } | 4746 : HBitwiseBinaryOperation(context, left, right) { } |
4695 }; | 4747 }; |
4696 | 4748 |
4697 | 4749 |
4698 class HRor: public HBitwiseBinaryOperation { | 4750 class HRor: public HBitwiseBinaryOperation { |
4699 public: | 4751 public: |
4700 HRor(HValue* context, HValue* left, HValue* right) | 4752 HRor(HValue* context, HValue* left, HValue* right) |
4701 : HBitwiseBinaryOperation(context, left, right) { | 4753 : HBitwiseBinaryOperation(context, left, right) { |
4702 ChangeRepresentation(Representation::Integer32()); | 4754 ChangeRepresentation(Representation::Integer32()); |
4703 } | 4755 } |
4704 | 4756 |
4757 virtual void UpdateRepresentation(Representation new_rep, | |
4758 HInferRepresentationPhase* h_infer, | |
4759 const char* reason) { | |
4760 if (new_rep.IsSmi()) new_rep = Representation::Integer32(); | |
4761 HBitwiseBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason); | |
4762 } | |
4763 | |
4705 DECLARE_CONCRETE_INSTRUCTION(Ror) | 4764 DECLARE_CONCRETE_INSTRUCTION(Ror) |
4706 | 4765 |
4707 protected: | 4766 protected: |
4708 virtual bool DataEquals(HValue* other) { return true; } | 4767 virtual bool DataEquals(HValue* other) { return true; } |
4709 }; | 4768 }; |
4710 | 4769 |
4711 | 4770 |
4712 class HOsrEntry: public HTemplateInstruction<0> { | 4771 class HOsrEntry: public HTemplateInstruction<0> { |
4713 public: | 4772 public: |
4714 explicit HOsrEntry(BailoutId ast_id) : ast_id_(ast_id) { | 4773 explicit HOsrEntry(BailoutId ast_id) : ast_id_(ast_id) { |
(...skipping 1200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5915 SetGVNFlag(kChangesDoubleArrayElements); | 5974 SetGVNFlag(kChangesDoubleArrayElements); |
5916 } else if (IsFastSmiElementsKind(elements_kind)) { | 5975 } else if (IsFastSmiElementsKind(elements_kind)) { |
5917 SetGVNFlag(kChangesArrayElements); | 5976 SetGVNFlag(kChangesArrayElements); |
5918 } else { | 5977 } else { |
5919 SetGVNFlag(kChangesArrayElements); | 5978 SetGVNFlag(kChangesArrayElements); |
5920 } | 5979 } |
5921 | 5980 |
5922 // EXTERNAL_{UNSIGNED_,}{BYTE,SHORT,INT}_ELEMENTS are truncating. | 5981 // EXTERNAL_{UNSIGNED_,}{BYTE,SHORT,INT}_ELEMENTS are truncating. |
5923 if (elements_kind >= EXTERNAL_BYTE_ELEMENTS && | 5982 if (elements_kind >= EXTERNAL_BYTE_ELEMENTS && |
5924 elements_kind <= EXTERNAL_UNSIGNED_INT_ELEMENTS) { | 5983 elements_kind <= EXTERNAL_UNSIGNED_INT_ELEMENTS) { |
5984 if (elements_kind <= EXTERNAL_SHORT_ELEMENTS) { | |
Sven Panne
2013/07/24 11:38:36
Stuff like this has been there before, but it is u
Toon Verwaest
2013/07/24 13:24:01
Removed.
On 2013/07/24 11:38:36, Sven Panne wrote
| |
5985 SetFlag(kTruncatingToSmi); | |
5986 } | |
5925 SetFlag(kTruncatingToInt32); | 5987 SetFlag(kTruncatingToInt32); |
5926 } | 5988 } |
5927 } | 5989 } |
5928 | 5990 |
5929 virtual bool HasEscapingOperandAt(int index) { return index != 0; } | 5991 virtual bool HasEscapingOperandAt(int index) { return index != 0; } |
5930 virtual Representation RequiredInputRepresentation(int index) { | 5992 virtual Representation RequiredInputRepresentation(int index) { |
5931 // kind_fast: tagged[int32] = tagged | 5993 // kind_fast: tagged[int32] = tagged |
5932 // kind_double: tagged[int32] = double | 5994 // kind_double: tagged[int32] = double |
5933 // kind_smi : tagged[int32] = smi | 5995 // kind_smi : tagged[int32] = smi |
5934 // kind_external: external[int32] = (double | int32) | 5996 // kind_external: external[int32] = (double | int32) |
(...skipping 702 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6637 virtual bool IsDeletable() const { return true; } | 6699 virtual bool IsDeletable() const { return true; } |
6638 }; | 6700 }; |
6639 | 6701 |
6640 | 6702 |
6641 #undef DECLARE_INSTRUCTION | 6703 #undef DECLARE_INSTRUCTION |
6642 #undef DECLARE_CONCRETE_INSTRUCTION | 6704 #undef DECLARE_CONCRETE_INSTRUCTION |
6643 | 6705 |
6644 } } // namespace v8::internal | 6706 } } // namespace v8::internal |
6645 | 6707 |
6646 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ | 6708 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ |
OLD | NEW |