| 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 && |
| 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 |