Chromium Code Reviews| 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 |