| 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 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 139 V(LoadKeyed) \ | 139 V(LoadKeyed) \ |
| 140 V(LoadKeyedGeneric) \ | 140 V(LoadKeyedGeneric) \ |
| 141 V(LoadNamedField) \ | 141 V(LoadNamedField) \ |
| 142 V(LoadNamedFieldPolymorphic) \ | 142 V(LoadNamedFieldPolymorphic) \ |
| 143 V(LoadNamedGeneric) \ | 143 V(LoadNamedGeneric) \ |
| 144 V(MapEnumLength) \ | 144 V(MapEnumLength) \ |
| 145 V(MathFloorOfDiv) \ | 145 V(MathFloorOfDiv) \ |
| 146 V(MathMinMax) \ | 146 V(MathMinMax) \ |
| 147 V(Mod) \ | 147 V(Mod) \ |
| 148 V(Mul) \ | 148 V(Mul) \ |
| 149 V(NumericConstraint) \ |
| 149 V(ObjectLiteral) \ | 150 V(ObjectLiteral) \ |
| 150 V(OsrEntry) \ | 151 V(OsrEntry) \ |
| 151 V(OuterContext) \ | 152 V(OuterContext) \ |
| 152 V(Parameter) \ | 153 V(Parameter) \ |
| 153 V(Power) \ | 154 V(Power) \ |
| 154 V(PushArgument) \ | 155 V(PushArgument) \ |
| 155 V(Random) \ | 156 V(Random) \ |
| 156 V(RegExpLiteral) \ | 157 V(RegExpLiteral) \ |
| 157 V(Return) \ | 158 V(Return) \ |
| 158 V(Ror) \ | 159 V(Ror) \ |
| (...skipping 546 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 705 | 706 |
| 706 virtual void AddInformativeDefinitions() {} | 707 virtual void AddInformativeDefinitions() {} |
| 707 | 708 |
| 708 void UpdateRedefinedUsesWhileSettingUpInformativeDefinitions() { | 709 void UpdateRedefinedUsesWhileSettingUpInformativeDefinitions() { |
| 709 UpdateRedefinedUsesInner<TestDominanceUsingProcessedFlag>(); | 710 UpdateRedefinedUsesInner<TestDominanceUsingProcessedFlag>(); |
| 710 } | 711 } |
| 711 void UpdateRedefinedUses() { | 712 void UpdateRedefinedUses() { |
| 712 UpdateRedefinedUsesInner<Dominates>(); | 713 UpdateRedefinedUsesInner<Dominates>(); |
| 713 } | 714 } |
| 714 | 715 |
| 716 bool IsInteger32Constant(); |
| 717 int32_t GetInteger32Constant(); |
| 718 |
| 715 bool IsDefinedAfter(HBasicBlock* other) const; | 719 bool IsDefinedAfter(HBasicBlock* other) const; |
| 716 | 720 |
| 717 // Operands. | 721 // Operands. |
| 718 virtual int OperandCount() = 0; | 722 virtual int OperandCount() = 0; |
| 719 virtual HValue* OperandAt(int index) const = 0; | 723 virtual HValue* OperandAt(int index) const = 0; |
| 720 void SetOperandAt(int index, HValue* value); | 724 void SetOperandAt(int index, HValue* value); |
| 721 | 725 |
| 722 void DeleteAndReplaceWith(HValue* other); | 726 void DeleteAndReplaceWith(HValue* other); |
| 723 void ReplaceAllUsesWith(HValue* other); | 727 void ReplaceAllUsesWith(HValue* other); |
| 724 bool HasNoUses() const { return use_list_ == NULL; } | 728 bool HasNoUses() const { return use_list_ == NULL; } |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 831 } | 835 } |
| 832 | 836 |
| 833 bool IsDead() const { | 837 bool IsDead() const { |
| 834 return HasNoUses() && !HasObservableSideEffects() && IsDeletable(); | 838 return HasNoUses() && !HasObservableSideEffects() && IsDeletable(); |
| 835 } | 839 } |
| 836 | 840 |
| 837 #ifdef DEBUG | 841 #ifdef DEBUG |
| 838 virtual void Verify() = 0; | 842 virtual void Verify() = 0; |
| 839 #endif | 843 #endif |
| 840 | 844 |
| 845 class NumericRelation { |
| 846 public: |
| 847 enum Kind { NONE, EQ, GT, GE, LT, LE, NE }; |
| 848 static const char* MnemonicFromKind(Kind kind) { |
| 849 switch(kind) { |
| 850 case NONE: return "NONE"; |
| 851 case EQ: return "EQ"; |
| 852 case GT: return "GT"; |
| 853 case GE: return "GE"; |
| 854 case LT: return "LT"; |
| 855 case LE: return "LE"; |
| 856 case NE: return "NE"; |
| 857 } |
| 858 UNREACHABLE(); |
| 859 return NULL; |
| 860 } |
| 861 const char* Mnemonic() const { return MnemonicFromKind((Kind) kind_); } |
| 862 |
| 863 static NumericRelation None() { return NumericRelation(NONE); } |
| 864 static NumericRelation Eq() { return NumericRelation(EQ); } |
| 865 static NumericRelation Gt() { return NumericRelation(GT); } |
| 866 static NumericRelation Ge() { return NumericRelation(GE); } |
| 867 static NumericRelation Lt() { return NumericRelation(LT); } |
| 868 static NumericRelation Le() { return NumericRelation(LE); } |
| 869 static NumericRelation Ne() { return NumericRelation(NE); } |
| 870 |
| 871 static NumericRelation FromToken(Token::Value token) { |
| 872 switch (token) { |
| 873 case Token::EQ: return Eq(); |
| 874 case Token::EQ_STRICT: return Eq(); |
| 875 case Token::LT: return Gt(); |
| 876 case Token::GT: return Lt(); |
| 877 case Token::LTE: return Ge(); |
| 878 case Token::GTE: return Le(); |
| 879 case Token::NE: return Ne(); |
| 880 default: return None(); |
| 881 } |
| 882 } |
| 883 |
| 884 bool operator==(const NumericRelation& other) { |
| 885 return kind_ == other.kind_; |
| 886 } |
| 887 bool operator!=(const NumericRelation& other) { |
| 888 return kind_ != other.kind_; |
| 889 } |
| 890 |
| 891 // The semantics of "Reversed" is that if "x rel y" is true then also |
| 892 // "y rel.Reversed() x" is true, and that rel.Reversed().Reversed() == rel. |
| 893 NumericRelation Reversed() { |
| 894 switch (kind_) { |
| 895 case NONE: return None(); |
| 896 case EQ: return Eq(); |
| 897 case GT: return Lt(); |
| 898 case GE: return Le(); |
| 899 case LT: return Gt(); |
| 900 case LE: return Ge(); |
| 901 case NE: return Ne(); |
| 902 } |
| 903 UNREACHABLE(); |
| 904 return None(); |
| 905 } |
| 906 |
| 907 // The semantics of "Implies" is that if "x rel y" is true |
| 908 // then also "x other_relation y" is true. |
| 909 bool Implies(NumericRelation other_relation) { |
| 910 switch (kind_) { |
| 911 case NONE: return false; |
| 912 case EQ: return (other_relation.kind_ == EQ) |
| 913 || (other_relation.kind_ == GE) |
| 914 || (other_relation.kind_ == LE); |
| 915 case GT: return (other_relation.kind_ == GT) |
| 916 || (other_relation.kind_ == GE) |
| 917 || (other_relation.kind_ == NE); |
| 918 case LT: return (other_relation.kind_ == LT) |
| 919 || (other_relation.kind_ == LE) |
| 920 || (other_relation.kind_ == NE); |
| 921 case GE: return (other_relation.kind_ == GE); |
| 922 case LE: return (other_relation.kind_ == LE); |
| 923 case NE: return (other_relation.kind_ == NE); |
| 924 default: |
| 925 UNREACHABLE(); |
| 926 return false; |
| 927 } |
| 928 } |
| 929 |
| 930 // The semantics of "IsExtendable" is that if |
| 931 // "rel.IsExtendable(direction) is true" then |
| 932 // "(x + direction) rel y" implies "x rel y". |
| 933 bool IsExtendable(int direction) { |
| 934 switch (kind_) { |
| 935 case NONE: return false; |
| 936 case EQ: return false; |
| 937 case GT: return (direction <= 0); |
| 938 case GE: return (direction <= 0); |
| 939 case LT: return (direction >= 0); |
| 940 case LE: return (direction >= 0); |
| 941 case NE: return false; |
| 942 } |
| 943 UNREACHABLE(); |
| 944 return false; |
| 945 } |
| 946 |
| 947 private: |
| 948 explicit NumericRelation(Kind kind) : kind_(kind) {} |
| 949 |
| 950 Kind kind_; |
| 951 }; |
| 952 |
| 953 // This method is recursive but it is guaranteed to terminate because |
| 954 // RedefinedOperand() always dominates "this". |
| 955 bool IsRelationTrue(NumericRelation relation, HValue* other) { |
| 956 bool result = CheckRelation(relation, other) || |
| 957 other->CheckRelation(relation.Reversed(), this); |
| 958 if (!result) { |
| 959 HValue* redefined = RedefinedOperand(); |
| 960 if (redefined != NULL) { |
| 961 result = redefined->IsRelationTrue(relation, other); |
| 962 } |
| 963 } |
| 964 return result; |
| 965 } |
| 966 |
| 967 HValue* AddNumericConstraint(HInstruction* insertion_point, |
| 968 HValue* related_value, |
| 969 NumericRelation relation); |
| 970 |
| 841 protected: | 971 protected: |
| 842 // This function must be overridden for instructions with flag kUseGVN, to | 972 // This function must be overridden for instructions with flag kUseGVN, to |
| 843 // compare the non-Operand parts of the instruction. | 973 // compare the non-Operand parts of the instruction. |
| 844 virtual bool DataEquals(HValue* other) { | 974 virtual bool DataEquals(HValue* other) { |
| 845 UNREACHABLE(); | 975 UNREACHABLE(); |
| 846 return false; | 976 return false; |
| 847 } | 977 } |
| 848 | 978 |
| 849 virtual Representation RepresentationFromInputs() { | 979 virtual Representation RepresentationFromInputs() { |
| 850 return representation(); | 980 return representation(); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 893 if (input != NULL) { | 1023 if (input != NULL) { |
| 894 for (HUseIterator uses = input->uses(); !uses.Done(); uses.Advance()) { | 1024 for (HUseIterator uses = input->uses(); !uses.Done(); uses.Advance()) { |
| 895 HValue* use = uses.value(); | 1025 HValue* use = uses.value(); |
| 896 if (TestDominance(this, use)) { | 1026 if (TestDominance(this, use)) { |
| 897 use->SetOperandAt(uses.index(), this); | 1027 use->SetOperandAt(uses.index(), this); |
| 898 } | 1028 } |
| 899 } | 1029 } |
| 900 } | 1030 } |
| 901 } | 1031 } |
| 902 | 1032 |
| 1033 // Informative definitions can override this method to state any numeric |
| 1034 // relation they provide on the redefined value. |
| 1035 virtual bool CheckRelation(NumericRelation relation, HValue* other) { |
| 1036 return false; |
| 1037 } |
| 1038 |
| 903 static GVNFlagSet AllDependsOnFlagSet() { | 1039 static GVNFlagSet AllDependsOnFlagSet() { |
| 904 GVNFlagSet result; | 1040 GVNFlagSet result; |
| 905 // Create changes mask. | 1041 // Create changes mask. |
| 906 #define ADD_FLAG(type) result.Add(kDependsOn##type); | 1042 #define ADD_FLAG(type) result.Add(kDependsOn##type); |
| 907 GVN_TRACKED_FLAG_LIST(ADD_FLAG) | 1043 GVN_TRACKED_FLAG_LIST(ADD_FLAG) |
| 908 GVN_UNTRACKED_FLAG_LIST(ADD_FLAG) | 1044 GVN_UNTRACKED_FLAG_LIST(ADD_FLAG) |
| 909 #undef ADD_FLAG | 1045 #undef ADD_FLAG |
| 910 return result; | 1046 return result; |
| 911 } | 1047 } |
| 912 | 1048 |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1117 virtual Representation RequiredInputRepresentation(int index) { | 1253 virtual Representation RequiredInputRepresentation(int index) { |
| 1118 return Representation::None(); | 1254 return Representation::None(); |
| 1119 } | 1255 } |
| 1120 | 1256 |
| 1121 virtual void PrintDataTo(StringStream* stream); | 1257 virtual void PrintDataTo(StringStream* stream); |
| 1122 | 1258 |
| 1123 DECLARE_CONCRETE_INSTRUCTION(DummyUse); | 1259 DECLARE_CONCRETE_INSTRUCTION(DummyUse); |
| 1124 }; | 1260 }; |
| 1125 | 1261 |
| 1126 | 1262 |
| 1263 class HNumericConstraint : public HTemplateInstruction<2> { |
| 1264 public: |
| 1265 static HNumericConstraint* New(HInstruction* insertion_point, |
| 1266 HValue* constrained_value, |
| 1267 HValue* related_value, |
| 1268 NumericRelation relation); |
| 1269 |
| 1270 HValue* constrained_value() { return OperandAt(0); } |
| 1271 HValue* related_value() { return OperandAt(1); } |
| 1272 NumericRelation relation() { return relation_; } |
| 1273 |
| 1274 virtual int RedefinedOperandIndex() { return 0; } |
| 1275 |
| 1276 virtual Representation RequiredInputRepresentation(int index) { |
| 1277 return constrained_value()->RequiredInputRepresentation(index); |
| 1278 } |
| 1279 |
| 1280 virtual void PrintDataTo(StringStream* stream); |
| 1281 |
| 1282 virtual bool CheckRelation(NumericRelation other_relation, |
| 1283 HValue* other_related_value) { |
| 1284 if (related_value() == other_related_value) { |
| 1285 return relation().Implies(other_relation); |
| 1286 } else { |
| 1287 return false; |
| 1288 } |
| 1289 } |
| 1290 |
| 1291 DECLARE_CONCRETE_INSTRUCTION(NumericConstraint) |
| 1292 |
| 1293 private: |
| 1294 explicit HNumericConstraint(HValue* constrained_value, |
| 1295 HValue* related_value, |
| 1296 NumericRelation relation) |
| 1297 : relation_(relation) { |
| 1298 SetOperandAt(0, constrained_value); |
| 1299 SetOperandAt(1, related_value); |
| 1300 set_representation(constrained_value->representation()); |
| 1301 } |
| 1302 |
| 1303 NumericRelation relation_; |
| 1304 }; |
| 1305 |
| 1306 |
| 1127 // We insert soft-deoptimize when we hit code with unknown typefeedback, | 1307 // We insert soft-deoptimize when we hit code with unknown typefeedback, |
| 1128 // so that we get a chance of re-optimizing with useful typefeedback. | 1308 // so that we get a chance of re-optimizing with useful typefeedback. |
| 1129 // HSoftDeoptimize does not end a basic block as opposed to HDeoptimize. | 1309 // HSoftDeoptimize does not end a basic block as opposed to HDeoptimize. |
| 1130 class HSoftDeoptimize: public HTemplateInstruction<0> { | 1310 class HSoftDeoptimize: public HTemplateInstruction<0> { |
| 1131 public: | 1311 public: |
| 1132 virtual Representation RequiredInputRepresentation(int index) { | 1312 virtual Representation RequiredInputRepresentation(int index) { |
| 1133 return Representation::None(); | 1313 return Representation::None(); |
| 1134 } | 1314 } |
| 1135 | 1315 |
| 1136 DECLARE_CONCRETE_INSTRUCTION(SoftDeoptimize) | 1316 DECLARE_CONCRETE_INSTRUCTION(SoftDeoptimize) |
| (...skipping 1504 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2641 virtual int OperandCount() { return inputs_.length(); } | 2821 virtual int OperandCount() { return inputs_.length(); } |
| 2642 virtual HValue* OperandAt(int index) const { return inputs_[index]; } | 2822 virtual HValue* OperandAt(int index) const { return inputs_[index]; } |
| 2643 HValue* GetRedundantReplacement(); | 2823 HValue* GetRedundantReplacement(); |
| 2644 void AddInput(HValue* value); | 2824 void AddInput(HValue* value); |
| 2645 bool HasRealUses(); | 2825 bool HasRealUses(); |
| 2646 | 2826 |
| 2647 bool IsReceiver() { return merged_index_ == 0; } | 2827 bool IsReceiver() { return merged_index_ == 0; } |
| 2648 | 2828 |
| 2649 int merged_index() const { return merged_index_; } | 2829 int merged_index() const { return merged_index_; } |
| 2650 | 2830 |
| 2831 virtual void AddInformativeDefinitions(); |
| 2832 |
| 2651 virtual void PrintTo(StringStream* stream); | 2833 virtual void PrintTo(StringStream* stream); |
| 2652 | 2834 |
| 2653 #ifdef DEBUG | 2835 #ifdef DEBUG |
| 2654 virtual void Verify(); | 2836 virtual void Verify(); |
| 2655 #endif | 2837 #endif |
| 2656 | 2838 |
| 2657 void InitRealUses(int id); | 2839 void InitRealUses(int id); |
| 2658 void AddNonPhiUsesFrom(HPhi* other); | 2840 void AddNonPhiUsesFrom(HPhi* other); |
| 2659 void AddIndirectUsesTo(int* use_count); | 2841 void AddIndirectUsesTo(int* use_count); |
| 2660 | 2842 |
| (...skipping 445 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3106 SetFlag(kUseGVN); | 3288 SetFlag(kUseGVN); |
| 3107 } | 3289 } |
| 3108 | 3290 |
| 3109 virtual Representation RequiredInputRepresentation(int arg_index) { | 3291 virtual Representation RequiredInputRepresentation(int arg_index) { |
| 3110 return representation(); | 3292 return representation(); |
| 3111 } | 3293 } |
| 3112 virtual Representation observed_input_representation(int index) { | 3294 virtual Representation observed_input_representation(int index) { |
| 3113 return Representation::Integer32(); | 3295 return Representation::Integer32(); |
| 3114 } | 3296 } |
| 3115 | 3297 |
| 3298 virtual bool CheckRelation(NumericRelation relation, HValue* related_value); |
| 3299 |
| 3116 virtual void PrintDataTo(StringStream* stream); | 3300 virtual void PrintDataTo(StringStream* stream); |
| 3117 virtual void InferRepresentation(HInferRepresentation* h_infer); | 3301 virtual void InferRepresentation(HInferRepresentation* h_infer); |
| 3118 | 3302 |
| 3119 HValue* index() { return OperandAt(0); } | 3303 HValue* index() { return OperandAt(0); } |
| 3120 HValue* length() { return OperandAt(1); } | 3304 HValue* length() { return OperandAt(1); } |
| 3121 | 3305 |
| 3122 virtual int RedefinedOperandIndex() { return 0; } | 3306 virtual int RedefinedOperandIndex() { return 0; } |
| 3123 | 3307 |
| 3124 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck) | 3308 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck) |
| 3125 | 3309 |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3288 virtual void InferRepresentation(HInferRepresentation* h_infer); | 3472 virtual void InferRepresentation(HInferRepresentation* h_infer); |
| 3289 | 3473 |
| 3290 virtual Representation RequiredInputRepresentation(int index) { | 3474 virtual Representation RequiredInputRepresentation(int index) { |
| 3291 return representation(); | 3475 return representation(); |
| 3292 } | 3476 } |
| 3293 virtual Representation observed_input_representation(int index) { | 3477 virtual Representation observed_input_representation(int index) { |
| 3294 return observed_input_representation_[index]; | 3478 return observed_input_representation_[index]; |
| 3295 } | 3479 } |
| 3296 virtual void PrintDataTo(StringStream* stream); | 3480 virtual void PrintDataTo(StringStream* stream); |
| 3297 | 3481 |
| 3482 virtual void AddInformativeDefinitions(); |
| 3483 |
| 3298 DECLARE_CONCRETE_INSTRUCTION(CompareIDAndBranch) | 3484 DECLARE_CONCRETE_INSTRUCTION(CompareIDAndBranch) |
| 3299 | 3485 |
| 3300 private: | 3486 private: |
| 3301 Representation observed_input_representation_[2]; | 3487 Representation observed_input_representation_[2]; |
| 3302 Token::Value token_; | 3488 Token::Value token_; |
| 3303 }; | 3489 }; |
| 3304 | 3490 |
| 3305 | 3491 |
| 3306 class HCompareObjectEqAndBranch: public HTemplateControlInstruction<2, 2> { | 3492 class HCompareObjectEqAndBranch: public HTemplateControlInstruction<2, 2> { |
| 3307 public: | 3493 public: |
| (...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3692 | 3878 |
| 3693 static HInstruction* NewHAdd(Zone* zone, | 3879 static HInstruction* NewHAdd(Zone* zone, |
| 3694 HValue* context, | 3880 HValue* context, |
| 3695 HValue* left, | 3881 HValue* left, |
| 3696 HValue* right); | 3882 HValue* right); |
| 3697 | 3883 |
| 3698 virtual HType CalculateInferredType(); | 3884 virtual HType CalculateInferredType(); |
| 3699 | 3885 |
| 3700 virtual HValue* Canonicalize(); | 3886 virtual HValue* Canonicalize(); |
| 3701 | 3887 |
| 3888 virtual bool CheckRelation(NumericRelation relation, HValue* other) { |
| 3889 HValue* base = NULL; |
| 3890 int32_t offset = 0; |
| 3891 if (left()->IsInteger32Constant()) { |
| 3892 base = right(); |
| 3893 offset = left()->GetInteger32Constant(); |
| 3894 } else if (right()->IsInteger32Constant()) { |
| 3895 base = left(); |
| 3896 offset = right()->GetInteger32Constant(); |
| 3897 } else { |
| 3898 return false; |
| 3899 } |
| 3900 |
| 3901 return relation.IsExtendable(offset) |
| 3902 ? base->IsRelationTrue(relation, other) : false; |
| 3903 } |
| 3904 |
| 3702 DECLARE_CONCRETE_INSTRUCTION(Add) | 3905 DECLARE_CONCRETE_INSTRUCTION(Add) |
| 3703 | 3906 |
| 3704 protected: | 3907 protected: |
| 3705 virtual bool DataEquals(HValue* other) { return true; } | 3908 virtual bool DataEquals(HValue* other) { return true; } |
| 3706 | 3909 |
| 3707 virtual Range* InferRange(Zone* zone); | 3910 virtual Range* InferRange(Zone* zone); |
| 3708 }; | 3911 }; |
| 3709 | 3912 |
| 3710 | 3913 |
| 3711 class HSub: public HArithmeticBinaryOperation { | 3914 class HSub: public HArithmeticBinaryOperation { |
| 3712 public: | 3915 public: |
| 3713 HSub(HValue* context, HValue* left, HValue* right) | 3916 HSub(HValue* context, HValue* left, HValue* right) |
| 3714 : HArithmeticBinaryOperation(context, left, right) { | 3917 : HArithmeticBinaryOperation(context, left, right) { |
| 3715 SetFlag(kCanOverflow); | 3918 SetFlag(kCanOverflow); |
| 3716 } | 3919 } |
| 3717 | 3920 |
| 3718 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); | 3921 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); |
| 3719 | 3922 |
| 3720 virtual HValue* Canonicalize(); | 3923 virtual HValue* Canonicalize(); |
| 3721 | 3924 |
| 3722 static HInstruction* NewHSub(Zone* zone, | 3925 static HInstruction* NewHSub(Zone* zone, |
| 3723 HValue* context, | 3926 HValue* context, |
| 3724 HValue* left, | 3927 HValue* left, |
| 3725 HValue* right); | 3928 HValue* right); |
| 3726 | 3929 |
| 3930 virtual bool CheckRelation(NumericRelation relation, HValue* other) { |
| 3931 if (right()->IsInteger32Constant()) { |
| 3932 HValue* base = left(); |
| 3933 int32_t offset = right()->GetInteger32Constant(); |
| 3934 return relation.IsExtendable(offset) |
| 3935 ? base->IsRelationTrue(relation, other) : false; |
| 3936 } else { |
| 3937 return false; |
| 3938 } |
| 3939 } |
| 3940 |
| 3727 DECLARE_CONCRETE_INSTRUCTION(Sub) | 3941 DECLARE_CONCRETE_INSTRUCTION(Sub) |
| 3728 | 3942 |
| 3729 protected: | 3943 protected: |
| 3730 virtual bool DataEquals(HValue* other) { return true; } | 3944 virtual bool DataEquals(HValue* other) { return true; } |
| 3731 | 3945 |
| 3732 virtual Range* InferRange(Zone* zone); | 3946 virtual Range* InferRange(Zone* zone); |
| 3733 }; | 3947 }; |
| 3734 | 3948 |
| 3735 | 3949 |
| 3736 class HMul: public HArithmeticBinaryOperation { | 3950 class HMul: public HArithmeticBinaryOperation { |
| 3737 public: | 3951 public: |
| 3738 HMul(HValue* context, HValue* left, HValue* right) | 3952 HMul(HValue* context, HValue* left, HValue* right) |
| 3739 : HArithmeticBinaryOperation(context, left, right) { | 3953 : HArithmeticBinaryOperation(context, left, right) { |
| 3740 SetFlag(kCanOverflow); | 3954 SetFlag(kCanOverflow); |
| 3741 } | 3955 } |
| 3742 | 3956 |
| 3743 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); | 3957 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); |
| 3744 | 3958 |
| 3745 // Only commutative if it is certain that not two objects are multiplicated. | 3959 // Only commutative if it is certain that not two objects are multiplicated. |
| 3746 virtual bool IsCommutative() const { | 3960 virtual bool IsCommutative() const { |
| 3747 return !representation().IsTagged(); | 3961 return !representation().IsTagged(); |
| 3748 } | 3962 } |
| 3749 | 3963 |
| 3750 static HInstruction* NewHMul(Zone* zone, | 3964 static HInstruction* NewHMul(Zone* zone, |
| 3751 HValue* context, | 3965 HValue* context, |
| 3752 HValue* left, | 3966 HValue* left, |
| 3753 HValue* right); | 3967 HValue* right); |
| 3754 | 3968 |
| 3969 // The idea is that "k > 1" implies that "base * k >= base". |
| 3970 virtual bool CheckRelation(NumericRelation relation, HValue* other) { |
| 3971 HValue* base = NULL; |
| 3972 int32_t k = 0; |
| 3973 if (left()->IsInteger32Constant()) { |
| 3974 base = right(); |
| 3975 k = left()->GetInteger32Constant(); |
| 3976 } else if (right()->IsInteger32Constant()) { |
| 3977 base = left(); |
| 3978 k = right()->GetInteger32Constant(); |
| 3979 } else { |
| 3980 return false; |
| 3981 } |
| 3982 |
| 3983 return (k > 1 && relation.IsExtendable(1)) |
| 3984 ? base->IsRelationTrue(relation, other) : false; |
| 3985 } |
| 3986 |
| 3755 DECLARE_CONCRETE_INSTRUCTION(Mul) | 3987 DECLARE_CONCRETE_INSTRUCTION(Mul) |
| 3756 | 3988 |
| 3757 protected: | 3989 protected: |
| 3758 virtual bool DataEquals(HValue* other) { return true; } | 3990 virtual bool DataEquals(HValue* other) { return true; } |
| 3759 | 3991 |
| 3760 virtual Range* InferRange(Zone* zone); | 3992 virtual Range* InferRange(Zone* zone); |
| 3761 }; | 3993 }; |
| 3762 | 3994 |
| 3763 | 3995 |
| 3764 class HMod: public HArithmeticBinaryOperation { | 3996 class HMod: public HArithmeticBinaryOperation { |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3937 HShr(HValue* context, HValue* left, HValue* right) | 4169 HShr(HValue* context, HValue* left, HValue* right) |
| 3938 : HBitwiseBinaryOperation(context, left, right) { } | 4170 : HBitwiseBinaryOperation(context, left, right) { } |
| 3939 | 4171 |
| 3940 virtual Range* InferRange(Zone* zone); | 4172 virtual Range* InferRange(Zone* zone); |
| 3941 | 4173 |
| 3942 static HInstruction* NewHShr(Zone* zone, | 4174 static HInstruction* NewHShr(Zone* zone, |
| 3943 HValue* context, | 4175 HValue* context, |
| 3944 HValue* left, | 4176 HValue* left, |
| 3945 HValue* right); | 4177 HValue* right); |
| 3946 | 4178 |
| 4179 virtual bool CheckRelation(NumericRelation relation, HValue* other) { |
| 4180 if (right()->IsInteger32Constant()) { |
| 4181 HValue* base = left(); |
| 4182 int32_t bits = right()->GetInteger32Constant(); |
| 4183 return relation.IsExtendable(-bits) |
| 4184 ? base->IsRelationTrue(relation, other) : false; |
| 4185 } else { |
| 4186 return false; |
| 4187 } |
| 4188 } |
| 4189 |
| 3947 DECLARE_CONCRETE_INSTRUCTION(Shr) | 4190 DECLARE_CONCRETE_INSTRUCTION(Shr) |
| 3948 | 4191 |
| 3949 protected: | 4192 protected: |
| 3950 virtual bool DataEquals(HValue* other) { return true; } | 4193 virtual bool DataEquals(HValue* other) { return true; } |
| 3951 }; | 4194 }; |
| 3952 | 4195 |
| 3953 | 4196 |
| 3954 class HSar: public HBitwiseBinaryOperation { | 4197 class HSar: public HBitwiseBinaryOperation { |
| 3955 public: | 4198 public: |
| 3956 HSar(HValue* context, HValue* left, HValue* right) | 4199 HSar(HValue* context, HValue* left, HValue* right) |
| 3957 : HBitwiseBinaryOperation(context, left, right) { } | 4200 : HBitwiseBinaryOperation(context, left, right) { } |
| 3958 | 4201 |
| 3959 virtual Range* InferRange(Zone* zone); | 4202 virtual Range* InferRange(Zone* zone); |
| 3960 | 4203 |
| 3961 static HInstruction* NewHSar(Zone* zone, | 4204 static HInstruction* NewHSar(Zone* zone, |
| 3962 HValue* context, | 4205 HValue* context, |
| 3963 HValue* left, | 4206 HValue* left, |
| 3964 HValue* right); | 4207 HValue* right); |
| 3965 | 4208 |
| 4209 virtual bool CheckRelation(NumericRelation relation, HValue* other) { |
| 4210 if (right()->IsInteger32Constant()) { |
| 4211 HValue* base = left(); |
| 4212 int32_t bits = right()->GetInteger32Constant(); |
| 4213 return relation.IsExtendable(bits) |
| 4214 ? base->IsRelationTrue(relation, other) : false; |
| 4215 } else { |
| 4216 return false; |
| 4217 } |
| 4218 } |
| 4219 |
| 3966 DECLARE_CONCRETE_INSTRUCTION(Sar) | 4220 DECLARE_CONCRETE_INSTRUCTION(Sar) |
| 3967 | 4221 |
| 3968 protected: | 4222 protected: |
| 3969 virtual bool DataEquals(HValue* other) { return true; } | 4223 virtual bool DataEquals(HValue* other) { return true; } |
| 3970 }; | 4224 }; |
| 3971 | 4225 |
| 3972 | 4226 |
| 3973 class HRor: public HBitwiseBinaryOperation { | 4227 class HRor: public HBitwiseBinaryOperation { |
| 3974 public: | 4228 public: |
| 3975 HRor(HValue* context, HValue* left, HValue* right) | 4229 HRor(HValue* context, HValue* left, HValue* right) |
| (...skipping 1767 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5743 virtual bool IsDeletable() const { return true; } | 5997 virtual bool IsDeletable() const { return true; } |
| 5744 }; | 5998 }; |
| 5745 | 5999 |
| 5746 | 6000 |
| 5747 #undef DECLARE_INSTRUCTION | 6001 #undef DECLARE_INSTRUCTION |
| 5748 #undef DECLARE_CONCRETE_INSTRUCTION | 6002 #undef DECLARE_CONCRETE_INSTRUCTION |
| 5749 | 6003 |
| 5750 } } // namespace v8::internal | 6004 } } // namespace v8::internal |
| 5751 | 6005 |
| 5752 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ | 6006 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ |
| OLD | NEW |