Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6)

Side by Side Diff: src/hydrogen-instructions.h

Issue 12226112: Infrastructure classes for evaluating numeric relations between values. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Discard OSR values. Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
140 V(LoadKeyed) \ 140 V(LoadKeyed) \
141 V(LoadKeyedGeneric) \ 141 V(LoadKeyedGeneric) \
142 V(LoadNamedField) \ 142 V(LoadNamedField) \
143 V(LoadNamedFieldPolymorphic) \ 143 V(LoadNamedFieldPolymorphic) \
144 V(LoadNamedGeneric) \ 144 V(LoadNamedGeneric) \
145 V(MapEnumLength) \ 145 V(MapEnumLength) \
146 V(MathFloorOfDiv) \ 146 V(MathFloorOfDiv) \
147 V(MathMinMax) \ 147 V(MathMinMax) \
148 V(Mod) \ 148 V(Mod) \
149 V(Mul) \ 149 V(Mul) \
150 V(NumericConstraint) \
150 V(ObjectLiteral) \ 151 V(ObjectLiteral) \
151 V(OsrEntry) \ 152 V(OsrEntry) \
152 V(OuterContext) \ 153 V(OuterContext) \
153 V(Parameter) \ 154 V(Parameter) \
154 V(Power) \ 155 V(Power) \
155 V(PushArgument) \ 156 V(PushArgument) \
156 V(Random) \ 157 V(Random) \
157 V(RegExpLiteral) \ 158 V(RegExpLiteral) \
158 V(Return) \ 159 V(Return) \
159 V(Ror) \ 160 V(Ror) \
(...skipping 546 matching lines...) Expand 10 before | Expand all | Expand 10 after
706 707
707 virtual void AddInformativeDefinitions() {} 708 virtual void AddInformativeDefinitions() {}
708 709
709 void UpdateRedefinedUsesWhileSettingUpInformativeDefinitions() { 710 void UpdateRedefinedUsesWhileSettingUpInformativeDefinitions() {
710 UpdateRedefinedUsesInner<TestDominanceUsingProcessedFlag>(); 711 UpdateRedefinedUsesInner<TestDominanceUsingProcessedFlag>();
711 } 712 }
712 void UpdateRedefinedUses() { 713 void UpdateRedefinedUses() {
713 UpdateRedefinedUsesInner<Dominates>(); 714 UpdateRedefinedUsesInner<Dominates>();
714 } 715 }
715 716
717 bool IsInteger32Constant();
718 int32_t GetInteger32Constant();
719
716 bool IsDefinedAfter(HBasicBlock* other) const; 720 bool IsDefinedAfter(HBasicBlock* other) const;
717 721
718 // Operands. 722 // Operands.
719 virtual int OperandCount() = 0; 723 virtual int OperandCount() = 0;
720 virtual HValue* OperandAt(int index) const = 0; 724 virtual HValue* OperandAt(int index) const = 0;
721 void SetOperandAt(int index, HValue* value); 725 void SetOperandAt(int index, HValue* value);
722 726
723 void DeleteAndReplaceWith(HValue* other); 727 void DeleteAndReplaceWith(HValue* other);
724 void ReplaceAllUsesWith(HValue* other); 728 void ReplaceAllUsesWith(HValue* other);
725 bool HasNoUses() const { return use_list_ == NULL; } 729 bool HasNoUses() const { return use_list_ == NULL; }
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
832 } 836 }
833 837
834 bool IsDead() const { 838 bool IsDead() const {
835 return HasNoUses() && !HasObservableSideEffects() && IsDeletable(); 839 return HasNoUses() && !HasObservableSideEffects() && IsDeletable();
836 } 840 }
837 841
838 #ifdef DEBUG 842 #ifdef DEBUG
839 virtual void Verify() = 0; 843 virtual void Verify() = 0;
840 #endif 844 #endif
841 845
846 class NumericRelation {
847 public:
848 enum Kind { NONE, EQ, GT, GE, LT, LE, NE };
849 static const char* MnemonicFromKind(Kind kind) {
850 switch (kind) {
851 case NONE: return "NONE";
852 case EQ: return "EQ";
853 case GT: return "GT";
854 case GE: return "GE";
855 case LT: return "LT";
856 case LE: return "LE";
857 case NE: return "NE";
858 }
859 UNREACHABLE();
860 return NULL;
861 }
862 const char* Mnemonic() const { return MnemonicFromKind((Kind) kind_); }
863
864 static NumericRelation None() { return NumericRelation(NONE); }
865 static NumericRelation Eq() { return NumericRelation(EQ); }
866 static NumericRelation Gt() { return NumericRelation(GT); }
867 static NumericRelation Ge() { return NumericRelation(GE); }
868 static NumericRelation Lt() { return NumericRelation(LT); }
869 static NumericRelation Le() { return NumericRelation(LE); }
870 static NumericRelation Ne() { return NumericRelation(NE); }
871
872 static NumericRelation FromToken(Token::Value token) {
873 switch (token) {
874 case Token::EQ: return Eq();
875 case Token::EQ_STRICT: return Eq();
876 case Token::LT: return Gt();
877 case Token::GT: return Lt();
878 case Token::LTE: return Ge();
879 case Token::GTE: return Le();
880 case Token::NE: return Ne();
881 default: return None();
882 }
883 }
884
885 bool operator==(const NumericRelation& other) {
886 return kind_ == other.kind_;
887 }
888 bool operator!=(const NumericRelation& other) {
889 return kind_ != other.kind_;
890 }
891
892 // The semantics of "Reversed" is that if "x rel y" is true then also
893 // "y rel.Reversed() x" is true, and that rel.Reversed().Reversed() == rel.
894 NumericRelation Reversed() {
895 switch (kind_) {
896 case NONE: return None();
897 case EQ: return Eq();
898 case GT: return Lt();
899 case GE: return Le();
900 case LT: return Gt();
901 case LE: return Ge();
902 case NE: return Ne();
903 }
904 UNREACHABLE();
905 return None();
906 }
907
908 // The semantics of "Implies" is that if "x rel y" is true
909 // then also "x other_relation y" is true.
910 bool Implies(NumericRelation other_relation) {
911 switch (kind_) {
912 case NONE: return false;
913 case EQ: return (other_relation.kind_ == EQ)
914 || (other_relation.kind_ == GE)
915 || (other_relation.kind_ == LE);
916 case GT: return (other_relation.kind_ == GT)
917 || (other_relation.kind_ == GE)
918 || (other_relation.kind_ == NE);
919 case LT: return (other_relation.kind_ == LT)
920 || (other_relation.kind_ == LE)
921 || (other_relation.kind_ == NE);
922 case GE: return (other_relation.kind_ == GE);
923 case LE: return (other_relation.kind_ == LE);
924 case NE: return (other_relation.kind_ == NE);
925 default:
926 UNREACHABLE();
927 return false;
928 }
929 }
930
931 // The semantics of "IsExtendable" is that if
932 // "rel.IsExtendable(direction) is true" then
933 // "x rel y" implies "(x + direction) rel y" .
934 bool IsExtendable(int direction) {
935 switch (kind_) {
936 case NONE: return false;
937 case EQ: return false;
938 case GT: return (direction >= 0);
939 case GE: return (direction >= 0);
940 case LT: return (direction <= 0);
941 case LE: return (direction <= 0);
942 case NE: return false;
943 }
944 UNREACHABLE();
945 return false;
946 }
947
948 private:
949 explicit NumericRelation(Kind kind) : kind_(kind) {}
950
951 Kind kind_;
952 };
953
954 // This method is recursive but it is guaranteed to terminate because
955 // RedefinedOperand() always dominates "this".
956 bool IsRelationTrue(NumericRelation relation, HValue* other) {
957 if (this == other) {
958 return NumericRelation::Eq().Implies(relation);
959 }
960
961 bool result = CheckRelation(relation, other) ||
962 other->CheckRelation(relation.Reversed(), this);
963 if (!result) {
964 HValue* redefined = RedefinedOperand();
965 if (redefined != NULL) {
966 result = redefined->IsRelationTrue(relation, other);
967 }
968 }
969 return result;
970 }
971
972 HValue* AddNumericConstraint(HInstruction* insertion_point,
973 HValue* related_value,
974 NumericRelation relation);
975
842 protected: 976 protected:
843 // This function must be overridden for instructions with flag kUseGVN, to 977 // This function must be overridden for instructions with flag kUseGVN, to
844 // compare the non-Operand parts of the instruction. 978 // compare the non-Operand parts of the instruction.
845 virtual bool DataEquals(HValue* other) { 979 virtual bool DataEquals(HValue* other) {
846 UNREACHABLE(); 980 UNREACHABLE();
847 return false; 981 return false;
848 } 982 }
849 983
850 virtual Representation RepresentationFromInputs() { 984 virtual Representation RepresentationFromInputs() {
851 return representation(); 985 return representation();
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
894 if (input != NULL) { 1028 if (input != NULL) {
895 for (HUseIterator uses = input->uses(); !uses.Done(); uses.Advance()) { 1029 for (HUseIterator uses = input->uses(); !uses.Done(); uses.Advance()) {
896 HValue* use = uses.value(); 1030 HValue* use = uses.value();
897 if (TestDominance(this, use)) { 1031 if (TestDominance(this, use)) {
898 use->SetOperandAt(uses.index(), this); 1032 use->SetOperandAt(uses.index(), this);
899 } 1033 }
900 } 1034 }
901 } 1035 }
902 } 1036 }
903 1037
1038 // Informative definitions can override this method to state any numeric
1039 // relation they provide on the redefined value.
1040 virtual bool CheckRelation(NumericRelation relation, HValue* other) {
1041 return false;
1042 }
1043
904 static GVNFlagSet AllDependsOnFlagSet() { 1044 static GVNFlagSet AllDependsOnFlagSet() {
905 GVNFlagSet result; 1045 GVNFlagSet result;
906 // Create changes mask. 1046 // Create changes mask.
907 #define ADD_FLAG(type) result.Add(kDependsOn##type); 1047 #define ADD_FLAG(type) result.Add(kDependsOn##type);
908 GVN_TRACKED_FLAG_LIST(ADD_FLAG) 1048 GVN_TRACKED_FLAG_LIST(ADD_FLAG)
909 GVN_UNTRACKED_FLAG_LIST(ADD_FLAG) 1049 GVN_UNTRACKED_FLAG_LIST(ADD_FLAG)
910 #undef ADD_FLAG 1050 #undef ADD_FLAG
911 return result; 1051 return result;
912 } 1052 }
913 1053
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
1118 virtual Representation RequiredInputRepresentation(int index) { 1258 virtual Representation RequiredInputRepresentation(int index) {
1119 return Representation::None(); 1259 return Representation::None();
1120 } 1260 }
1121 1261
1122 virtual void PrintDataTo(StringStream* stream); 1262 virtual void PrintDataTo(StringStream* stream);
1123 1263
1124 DECLARE_CONCRETE_INSTRUCTION(DummyUse); 1264 DECLARE_CONCRETE_INSTRUCTION(DummyUse);
1125 }; 1265 };
1126 1266
1127 1267
1268 class HNumericConstraint : public HTemplateInstruction<2> {
1269 public:
1270 static HNumericConstraint* New(HInstruction* insertion_point,
1271 HValue* constrained_value,
1272 HValue* related_value,
1273 NumericRelation relation);
1274
1275 HValue* constrained_value() { return OperandAt(0); }
1276 HValue* related_value() { return OperandAt(1); }
1277 NumericRelation relation() { return relation_; }
1278
1279 virtual int RedefinedOperandIndex() { return 0; }
1280
1281 virtual Representation RequiredInputRepresentation(int index) {
1282 return constrained_value()->RequiredInputRepresentation(index);
1283 }
1284
1285 virtual void PrintDataTo(StringStream* stream);
1286
1287 virtual bool CheckRelation(NumericRelation other_relation,
1288 HValue* other_related_value) {
1289 if (related_value() == other_related_value) {
1290 return relation().Implies(other_relation);
1291 } else {
1292 return false;
1293 }
1294 }
1295
1296 DECLARE_CONCRETE_INSTRUCTION(NumericConstraint)
1297
1298 private:
1299 explicit HNumericConstraint(HValue* constrained_value,
1300 HValue* related_value,
1301 NumericRelation relation)
1302 : relation_(relation) {
1303 SetOperandAt(0, constrained_value);
1304 SetOperandAt(1, related_value);
1305 set_representation(constrained_value->representation());
1306 }
1307
1308 NumericRelation relation_;
1309 };
1310
1311
1128 // We insert soft-deoptimize when we hit code with unknown typefeedback, 1312 // We insert soft-deoptimize when we hit code with unknown typefeedback,
1129 // so that we get a chance of re-optimizing with useful typefeedback. 1313 // so that we get a chance of re-optimizing with useful typefeedback.
1130 // HSoftDeoptimize does not end a basic block as opposed to HDeoptimize. 1314 // HSoftDeoptimize does not end a basic block as opposed to HDeoptimize.
1131 class HSoftDeoptimize: public HTemplateInstruction<0> { 1315 class HSoftDeoptimize: public HTemplateInstruction<0> {
1132 public: 1316 public:
1133 virtual Representation RequiredInputRepresentation(int index) { 1317 virtual Representation RequiredInputRepresentation(int index) {
1134 return Representation::None(); 1318 return Representation::None();
1135 } 1319 }
1136 1320
1137 DECLARE_CONCRETE_INSTRUCTION(SoftDeoptimize) 1321 DECLARE_CONCRETE_INSTRUCTION(SoftDeoptimize)
(...skipping 1532 matching lines...) Expand 10 before | Expand all | Expand 10 after
2670 virtual int OperandCount() { return inputs_.length(); } 2854 virtual int OperandCount() { return inputs_.length(); }
2671 virtual HValue* OperandAt(int index) const { return inputs_[index]; } 2855 virtual HValue* OperandAt(int index) const { return inputs_[index]; }
2672 HValue* GetRedundantReplacement(); 2856 HValue* GetRedundantReplacement();
2673 void AddInput(HValue* value); 2857 void AddInput(HValue* value);
2674 bool HasRealUses(); 2858 bool HasRealUses();
2675 2859
2676 bool IsReceiver() { return merged_index_ == 0; } 2860 bool IsReceiver() { return merged_index_ == 0; }
2677 2861
2678 int merged_index() const { return merged_index_; } 2862 int merged_index() const { return merged_index_; }
2679 2863
2864 virtual void AddInformativeDefinitions();
2865
2680 virtual void PrintTo(StringStream* stream); 2866 virtual void PrintTo(StringStream* stream);
2681 2867
2682 #ifdef DEBUG 2868 #ifdef DEBUG
2683 virtual void Verify(); 2869 virtual void Verify();
2684 #endif 2870 #endif
2685 2871
2686 void InitRealUses(int id); 2872 void InitRealUses(int id);
2687 void AddNonPhiUsesFrom(HPhi* other); 2873 void AddNonPhiUsesFrom(HPhi* other);
2688 void AddIndirectUsesTo(int* use_count); 2874 void AddIndirectUsesTo(int* use_count);
2689 2875
(...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after
3147 bool skip_check() { return skip_check_; } 3333 bool skip_check() { return skip_check_; }
3148 void set_skip_check(bool skip_check) { skip_check_ = skip_check; } 3334 void set_skip_check(bool skip_check) { skip_check_ = skip_check; }
3149 3335
3150 virtual Representation RequiredInputRepresentation(int arg_index) { 3336 virtual Representation RequiredInputRepresentation(int arg_index) {
3151 return representation(); 3337 return representation();
3152 } 3338 }
3153 virtual Representation observed_input_representation(int index) { 3339 virtual Representation observed_input_representation(int index) {
3154 return Representation::Integer32(); 3340 return Representation::Integer32();
3155 } 3341 }
3156 3342
3343 virtual bool CheckRelation(NumericRelation relation, HValue* related_value);
3344
3157 virtual void PrintDataTo(StringStream* stream); 3345 virtual void PrintDataTo(StringStream* stream);
3158 virtual void InferRepresentation(HInferRepresentation* h_infer); 3346 virtual void InferRepresentation(HInferRepresentation* h_infer);
3159 3347
3160 HValue* index() { return OperandAt(0); } 3348 HValue* index() { return OperandAt(0); }
3161 HValue* length() { return OperandAt(1); } 3349 HValue* length() { return OperandAt(1); }
3162 3350
3163 virtual int RedefinedOperandIndex() { return 0; } 3351 virtual int RedefinedOperandIndex() { return 0; }
3352 virtual void AddInformativeDefinitions();
3164 3353
3165 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck) 3354 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck)
3166 3355
3167 protected: 3356 protected:
3168 virtual bool DataEquals(HValue* other) { return true; } 3357 virtual bool DataEquals(HValue* other) { return true; }
3169 BoundsCheckKeyMode key_mode_; 3358 BoundsCheckKeyMode key_mode_;
3170 bool skip_check_; 3359 bool skip_check_;
3171 }; 3360 };
3172 3361
3173 3362
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
3330 virtual void InferRepresentation(HInferRepresentation* h_infer); 3519 virtual void InferRepresentation(HInferRepresentation* h_infer);
3331 3520
3332 virtual Representation RequiredInputRepresentation(int index) { 3521 virtual Representation RequiredInputRepresentation(int index) {
3333 return representation(); 3522 return representation();
3334 } 3523 }
3335 virtual Representation observed_input_representation(int index) { 3524 virtual Representation observed_input_representation(int index) {
3336 return observed_input_representation_[index]; 3525 return observed_input_representation_[index];
3337 } 3526 }
3338 virtual void PrintDataTo(StringStream* stream); 3527 virtual void PrintDataTo(StringStream* stream);
3339 3528
3529 virtual void AddInformativeDefinitions();
3530
3340 DECLARE_CONCRETE_INSTRUCTION(CompareIDAndBranch) 3531 DECLARE_CONCRETE_INSTRUCTION(CompareIDAndBranch)
3341 3532
3342 private: 3533 private:
3343 Representation observed_input_representation_[2]; 3534 Representation observed_input_representation_[2];
3344 Token::Value token_; 3535 Token::Value token_;
3345 }; 3536 };
3346 3537
3347 3538
3348 class HCompareObjectEqAndBranch: public HTemplateControlInstruction<2, 2> { 3539 class HCompareObjectEqAndBranch: public HTemplateControlInstruction<2, 2> {
3349 public: 3540 public:
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after
3734 3925
3735 static HInstruction* NewHAdd(Zone* zone, 3926 static HInstruction* NewHAdd(Zone* zone,
3736 HValue* context, 3927 HValue* context,
3737 HValue* left, 3928 HValue* left,
3738 HValue* right); 3929 HValue* right);
3739 3930
3740 virtual HType CalculateInferredType(); 3931 virtual HType CalculateInferredType();
3741 3932
3742 virtual HValue* Canonicalize(); 3933 virtual HValue* Canonicalize();
3743 3934
3935 virtual bool CheckRelation(NumericRelation relation, HValue* other) {
3936 HValue* base = NULL;
3937 int32_t offset = 0;
3938 if (left()->IsInteger32Constant()) {
3939 base = right();
3940 offset = left()->GetInteger32Constant();
3941 } else if (right()->IsInteger32Constant()) {
3942 base = left();
3943 offset = right()->GetInteger32Constant();
3944 } else {
3945 return false;
3946 }
3947
3948 return relation.IsExtendable(offset)
3949 ? base->IsRelationTrue(relation, other) : false;
3950 }
3951
3744 DECLARE_CONCRETE_INSTRUCTION(Add) 3952 DECLARE_CONCRETE_INSTRUCTION(Add)
3745 3953
3746 protected: 3954 protected:
3747 virtual bool DataEquals(HValue* other) { return true; } 3955 virtual bool DataEquals(HValue* other) { return true; }
3748 3956
3749 virtual Range* InferRange(Zone* zone); 3957 virtual Range* InferRange(Zone* zone);
3750 }; 3958 };
3751 3959
3752 3960
3753 class HSub: public HArithmeticBinaryOperation { 3961 class HSub: public HArithmeticBinaryOperation {
3754 public: 3962 public:
3755 HSub(HValue* context, HValue* left, HValue* right) 3963 HSub(HValue* context, HValue* left, HValue* right)
3756 : HArithmeticBinaryOperation(context, left, right) { 3964 : HArithmeticBinaryOperation(context, left, right) {
3757 SetFlag(kCanOverflow); 3965 SetFlag(kCanOverflow);
3758 } 3966 }
3759 3967
3760 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); 3968 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
3761 3969
3762 virtual HValue* Canonicalize(); 3970 virtual HValue* Canonicalize();
3763 3971
3764 static HInstruction* NewHSub(Zone* zone, 3972 static HInstruction* NewHSub(Zone* zone,
3765 HValue* context, 3973 HValue* context,
3766 HValue* left, 3974 HValue* left,
3767 HValue* right); 3975 HValue* right);
3768 3976
3977 virtual bool CheckRelation(NumericRelation relation, HValue* other) {
3978 if (right()->IsInteger32Constant()) {
3979 HValue* base = left();
3980 int32_t offset = right()->GetInteger32Constant();
3981 return relation.IsExtendable(offset)
3982 ? base->IsRelationTrue(relation, other) : false;
3983 } else {
3984 return false;
3985 }
3986 }
3987
3769 DECLARE_CONCRETE_INSTRUCTION(Sub) 3988 DECLARE_CONCRETE_INSTRUCTION(Sub)
3770 3989
3771 protected: 3990 protected:
3772 virtual bool DataEquals(HValue* other) { return true; } 3991 virtual bool DataEquals(HValue* other) { return true; }
3773 3992
3774 virtual Range* InferRange(Zone* zone); 3993 virtual Range* InferRange(Zone* zone);
3775 }; 3994 };
3776 3995
3777 3996
3778 class HMul: public HArithmeticBinaryOperation { 3997 class HMul: public HArithmeticBinaryOperation {
3779 public: 3998 public:
3780 HMul(HValue* context, HValue* left, HValue* right) 3999 HMul(HValue* context, HValue* left, HValue* right)
3781 : HArithmeticBinaryOperation(context, left, right) { 4000 : HArithmeticBinaryOperation(context, left, right) {
3782 SetFlag(kCanOverflow); 4001 SetFlag(kCanOverflow);
3783 } 4002 }
3784 4003
3785 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); 4004 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
3786 4005
3787 // Only commutative if it is certain that not two objects are multiplicated. 4006 // Only commutative if it is certain that not two objects are multiplicated.
3788 virtual bool IsCommutative() const { 4007 virtual bool IsCommutative() const {
3789 return !representation().IsTagged(); 4008 return !representation().IsTagged();
3790 } 4009 }
3791 4010
3792 static HInstruction* NewHMul(Zone* zone, 4011 static HInstruction* NewHMul(Zone* zone,
3793 HValue* context, 4012 HValue* context,
3794 HValue* left, 4013 HValue* left,
3795 HValue* right); 4014 HValue* right);
3796 4015
4016 // The idea is that "k > 1" implies that "base * k >= base".
4017 virtual bool CheckRelation(NumericRelation relation, HValue* other) {
4018 HValue* base = NULL;
4019 int32_t k = 0;
4020 if (left()->IsInteger32Constant()) {
4021 base = right();
4022 k = left()->GetInteger32Constant();
4023 } else if (right()->IsInteger32Constant()) {
4024 base = left();
4025 k = right()->GetInteger32Constant();
4026 } else {
4027 return false;
4028 }
4029
4030 return (k > 1 && relation.IsExtendable(1))
4031 ? base->IsRelationTrue(relation, other) : false;
4032 }
4033
3797 DECLARE_CONCRETE_INSTRUCTION(Mul) 4034 DECLARE_CONCRETE_INSTRUCTION(Mul)
3798 4035
3799 protected: 4036 protected:
3800 virtual bool DataEquals(HValue* other) { return true; } 4037 virtual bool DataEquals(HValue* other) { return true; }
3801 4038
3802 virtual Range* InferRange(Zone* zone); 4039 virtual Range* InferRange(Zone* zone);
3803 }; 4040 };
3804 4041
3805 4042
3806 class HMod: public HArithmeticBinaryOperation { 4043 class HMod: public HArithmeticBinaryOperation {
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
3960 HShl(HValue* context, HValue* left, HValue* right) 4197 HShl(HValue* context, HValue* left, HValue* right)
3961 : HBitwiseBinaryOperation(context, left, right) { } 4198 : HBitwiseBinaryOperation(context, left, right) { }
3962 4199
3963 virtual Range* InferRange(Zone* zone); 4200 virtual Range* InferRange(Zone* zone);
3964 4201
3965 static HInstruction* NewHShl(Zone* zone, 4202 static HInstruction* NewHShl(Zone* zone,
3966 HValue* context, 4203 HValue* context,
3967 HValue* left, 4204 HValue* left,
3968 HValue* right); 4205 HValue* right);
3969 4206
4207 virtual bool CheckRelation(NumericRelation relation, HValue* other);
4208
3970 DECLARE_CONCRETE_INSTRUCTION(Shl) 4209 DECLARE_CONCRETE_INSTRUCTION(Shl)
3971 4210
3972 protected: 4211 protected:
3973 virtual bool DataEquals(HValue* other) { return true; } 4212 virtual bool DataEquals(HValue* other) { return true; }
3974 }; 4213 };
3975 4214
3976 4215
3977 class HShr: public HBitwiseBinaryOperation { 4216 class HShr: public HBitwiseBinaryOperation {
3978 public: 4217 public:
3979 HShr(HValue* context, HValue* left, HValue* right) 4218 HShr(HValue* context, HValue* left, HValue* right)
3980 : HBitwiseBinaryOperation(context, left, right) { } 4219 : HBitwiseBinaryOperation(context, left, right) { }
3981 4220
3982 virtual Range* InferRange(Zone* zone); 4221 virtual Range* InferRange(Zone* zone);
3983 4222
3984 static HInstruction* NewHShr(Zone* zone, 4223 static HInstruction* NewHShr(Zone* zone,
3985 HValue* context, 4224 HValue* context,
3986 HValue* left, 4225 HValue* left,
3987 HValue* right); 4226 HValue* right);
3988 4227
4228 virtual bool CheckRelation(NumericRelation relation, HValue* other);
4229
3989 DECLARE_CONCRETE_INSTRUCTION(Shr) 4230 DECLARE_CONCRETE_INSTRUCTION(Shr)
3990 4231
3991 protected: 4232 protected:
3992 virtual bool DataEquals(HValue* other) { return true; } 4233 virtual bool DataEquals(HValue* other) { return true; }
3993 }; 4234 };
3994 4235
3995 4236
3996 class HSar: public HBitwiseBinaryOperation { 4237 class HSar: public HBitwiseBinaryOperation {
3997 public: 4238 public:
3998 HSar(HValue* context, HValue* left, HValue* right) 4239 HSar(HValue* context, HValue* left, HValue* right)
(...skipping 1786 matching lines...) Expand 10 before | Expand all | Expand 10 after
5785 virtual bool IsDeletable() const { return true; } 6026 virtual bool IsDeletable() const { return true; }
5786 }; 6027 };
5787 6028
5788 6029
5789 #undef DECLARE_INSTRUCTION 6030 #undef DECLARE_INSTRUCTION
5790 #undef DECLARE_CONCRETE_INSTRUCTION 6031 #undef DECLARE_CONCRETE_INSTRUCTION
5791 6032
5792 } } // namespace v8::internal 6033 } } // namespace v8::internal
5793 6034
5794 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ 6035 #endif // V8_HYDROGEN_INSTRUCTIONS_H_
OLDNEW
« no previous file with comments | « src/hydrogen.cc ('k') | src/hydrogen-instructions.cc » ('j') | src/hydrogen-instructions.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698