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

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: 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 672 matching lines...) Expand 10 before | Expand all | Expand 10 after
832 } 833 }
833 834
834 bool IsDead() const { 835 bool IsDead() const {
835 return HasNoUses() && !HasObservableSideEffects() && IsDeletable(); 836 return HasNoUses() && !HasObservableSideEffects() && IsDeletable();
836 } 837 }
837 838
838 #ifdef DEBUG 839 #ifdef DEBUG
839 virtual void Verify() = 0; 840 virtual void Verify() = 0;
840 #endif 841 #endif
841 842
843 class NumericRelation {
Jakob Kummerow 2013/02/12 15:10:42 I'd prefer making this a top-level class.
Massi 2013/02/13 11:56:42 Done.
844 public:
845 enum Kind { NONE, EQ, GT, GE, LT, LE, NE };
846 static const char* MnemonicFromKind(Kind kind) {
847 switch (kind) {
848 case NONE: return "NONE";
849 case EQ: return "EQ";
850 case GT: return "GT";
851 case GE: return "GE";
852 case LT: return "LT";
853 case LE: return "LE";
854 case NE: return "NE";
855 }
856 UNREACHABLE();
857 return NULL;
858 }
859 const char* Mnemonic() const { return MnemonicFromKind((Kind) kind_); }
Jakob Kummerow 2013/02/12 15:10:42 C++ style casts please
Massi 2013/02/13 11:56:42 Done.
860
861 static NumericRelation None() { return NumericRelation(NONE); }
Jakob Kummerow 2013/02/12 15:10:42 I don't think these add much value. Let's just cal
Massi 2013/02/13 11:56:42 Not having then would mean having to write constru
862 static NumericRelation Eq() { return NumericRelation(EQ); }
863 static NumericRelation Gt() { return NumericRelation(GT); }
864 static NumericRelation Ge() { return NumericRelation(GE); }
865 static NumericRelation Lt() { return NumericRelation(LT); }
866 static NumericRelation Le() { return NumericRelation(LE); }
867 static NumericRelation Ne() { return NumericRelation(NE); }
868
869 bool operator==(const NumericRelation& other) {
Jakob Kummerow 2013/02/12 15:10:42 I'd prefer an Equals() method over operator overlo
Massi 2013/02/13 11:56:42 I added an "IsNone()" method instead. I think that
870 return kind_ == other.kind_;
871 }
872 bool operator!=(const NumericRelation& other) {
873 return kind_ != other.kind_;
874 }
875
876 // The semantics of "Reversed" is that if "x rel y" is true then also
877 // "y rel.Reversed() x" is true, and that rel.Reversed().Reversed() == rel.
878 NumericRelation Reversed() {
879 switch (kind_) {
880 case NONE: return None();
881 case EQ: return Eq();
882 case GT: return Lt();
883 case GE: return Le();
884 case LT: return Gt();
885 case LE: return Ge();
886 case NE: return Ne();
887 }
888 UNREACHABLE();
889 return None();
890 }
891
892 // The semantics of "Implies" is that if "x rel y" is true then also
893 // "x other y" is true.
894 bool Implies(NumericRelation other) {
895 switch (kind_) {
896 case NONE: return false;
897 case EQ: return (other.kind_ == EQ)
898 || (other.kind_ == GE)
899 || (other.kind_ == LE);
900 case GT: return (other.kind_ == GT)
901 || (other.kind_ == GE)
902 || (other.kind_ == NE);
903 case LT: return (other.kind_ == LT)
904 || (other.kind_ == LE)
905 || (other.kind_ == NE);
906 case GE: return (other.kind_ == GE);
907 case LE: return (other.kind_ == LE);
908 case NE: return (other.kind_ == NE);
909 default:
Jakob Kummerow 2013/02/12 15:10:42 no default case
Massi 2013/02/13 11:56:42 Done.
910 UNREACHABLE();
911 return false;
912 }
913 }
914
915 private:
916 explicit NumericRelation(Kind kind) : kind_(kind) {}
917
918 Kind kind_;
919 };
920
921 // This method is recursive but it is guaranteed to terminate because
922 // RedefinedOperand() always dominates "this".
923 bool IsRelationTrue(NumericRelation relation, HValue* other) {
924 bool result = CheckRelation(relation, other) ||
925 other->CheckRelation(relation.Reversed(), this);
926 if (!result) {
927 HValue* redefined = RedefinedOperand();
928 if (redefined != NULL) {
929 result = redefined->IsRelationTrue(relation, other);
930 }
931 }
932 return result;
933 }
934
935 HValue* AddNumericConstraint(HInstruction* insertion_point,
936 HValue* related_value,
937 NumericRelation relation);
938
842 protected: 939 protected:
843 // This function must be overridden for instructions with flag kUseGVN, to 940 // This function must be overridden for instructions with flag kUseGVN, to
844 // compare the non-Operand parts of the instruction. 941 // compare the non-Operand parts of the instruction.
845 virtual bool DataEquals(HValue* other) { 942 virtual bool DataEquals(HValue* other) {
846 UNREACHABLE(); 943 UNREACHABLE();
847 return false; 944 return false;
848 } 945 }
849 946
850 virtual Representation RepresentationFromInputs() { 947 virtual Representation RepresentationFromInputs() {
851 return representation(); 948 return representation();
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
894 if (input != NULL) { 991 if (input != NULL) {
895 for (HUseIterator uses = input->uses(); !uses.Done(); uses.Advance()) { 992 for (HUseIterator uses = input->uses(); !uses.Done(); uses.Advance()) {
896 HValue* use = uses.value(); 993 HValue* use = uses.value();
897 if (TestDominance(this, use)) { 994 if (TestDominance(this, use)) {
898 use->SetOperandAt(uses.index(), this); 995 use->SetOperandAt(uses.index(), this);
899 } 996 }
900 } 997 }
901 } 998 }
902 } 999 }
903 1000
1001 // Informative definitions can override this method to state any numeric
1002 // relation they provide on the redefined value.
1003 virtual bool CheckRelation(NumericRelation relation, HValue* other) {
Jakob Kummerow 2013/02/12 15:10:42 This method's name should clearly express its rela
Massi 2013/02/13 11:56:42 Done.
1004 return false;
1005 }
1006
904 static GVNFlagSet AllDependsOnFlagSet() { 1007 static GVNFlagSet AllDependsOnFlagSet() {
905 GVNFlagSet result; 1008 GVNFlagSet result;
906 // Create changes mask. 1009 // Create changes mask.
907 #define ADD_FLAG(type) result.Add(kDependsOn##type); 1010 #define ADD_FLAG(type) result.Add(kDependsOn##type);
908 GVN_TRACKED_FLAG_LIST(ADD_FLAG) 1011 GVN_TRACKED_FLAG_LIST(ADD_FLAG)
909 GVN_UNTRACKED_FLAG_LIST(ADD_FLAG) 1012 GVN_UNTRACKED_FLAG_LIST(ADD_FLAG)
910 #undef ADD_FLAG 1013 #undef ADD_FLAG
911 return result; 1014 return result;
912 } 1015 }
913 1016
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
1118 virtual Representation RequiredInputRepresentation(int index) { 1221 virtual Representation RequiredInputRepresentation(int index) {
1119 return Representation::None(); 1222 return Representation::None();
1120 } 1223 }
1121 1224
1122 virtual void PrintDataTo(StringStream* stream); 1225 virtual void PrintDataTo(StringStream* stream);
1123 1226
1124 DECLARE_CONCRETE_INSTRUCTION(DummyUse); 1227 DECLARE_CONCRETE_INSTRUCTION(DummyUse);
1125 }; 1228 };
1126 1229
1127 1230
1231 class HNumericConstraint : public HTemplateInstruction<2> {
1232 public:
1233 static HNumericConstraint* New(HInstruction* insertion_point,
1234 HValue* constrained_value,
1235 HValue* related_value,
1236 NumericRelation relation);
1237
1238 HValue* constrained_value() { return OperandAt(0); }
1239 HValue* related_value() { return OperandAt(1); }
1240 NumericRelation relation() { return relation_; }
1241
1242 virtual int RedefinedOperandIndex() { return 0; }
1243
1244 virtual Representation RequiredInputRepresentation(int index) {
1245 return constrained_value()->RequiredInputRepresentation(index);
Jakob Kummerow 2013/02/12 15:10:42 return representation() (or return constrained_val
Massi 2013/02/13 11:56:42 Done.
1246 }
1247
1248 virtual void PrintDataTo(StringStream* stream);
1249
1250 virtual bool CheckRelation(NumericRelation other_relation,
1251 HValue* other_related_value) {
1252 if (related_value() == other_related_value) {
1253 return relation().Implies(other_relation);
1254 } else {
1255 return false;
1256 }
1257 }
1258
1259 DECLARE_CONCRETE_INSTRUCTION(NumericConstraint)
1260
1261 private:
1262 explicit HNumericConstraint(HValue* constrained_value,
Jakob Kummerow 2013/02/12 15:10:42 no "explicit"
Massi 2013/02/13 11:56:42 Done.
1263 HValue* related_value,
Jakob Kummerow 2013/02/12 15:10:42 please swap the last two arguments
Massi 2013/02/13 11:56:42 Done.
1264 NumericRelation relation)
1265 : relation_(relation) {
Jakob Kummerow 2013/02/12 15:10:42 nit: 4-space indent
Massi 2013/02/13 11:56:42 Done.
1266 SetOperandAt(0, constrained_value);
1267 SetOperandAt(1, related_value);
1268 set_representation(constrained_value->representation());
1269 }
1270
1271 NumericRelation relation_;
1272 };
1273
1274
1128 // We insert soft-deoptimize when we hit code with unknown typefeedback, 1275 // We insert soft-deoptimize when we hit code with unknown typefeedback,
1129 // so that we get a chance of re-optimizing with useful typefeedback. 1276 // so that we get a chance of re-optimizing with useful typefeedback.
1130 // HSoftDeoptimize does not end a basic block as opposed to HDeoptimize. 1277 // HSoftDeoptimize does not end a basic block as opposed to HDeoptimize.
1131 class HSoftDeoptimize: public HTemplateInstruction<0> { 1278 class HSoftDeoptimize: public HTemplateInstruction<0> {
1132 public: 1279 public:
1133 virtual Representation RequiredInputRepresentation(int index) { 1280 virtual Representation RequiredInputRepresentation(int index) {
1134 return Representation::None(); 1281 return Representation::None();
1135 } 1282 }
1136 1283
1137 DECLARE_CONCRETE_INSTRUCTION(SoftDeoptimize) 1284 DECLARE_CONCRETE_INSTRUCTION(SoftDeoptimize)
(...skipping 2009 matching lines...) Expand 10 before | Expand all | Expand 10 after
3147 bool skip_check() { return skip_check_; } 3294 bool skip_check() { return skip_check_; }
3148 void set_skip_check(bool skip_check) { skip_check_ = skip_check; } 3295 void set_skip_check(bool skip_check) { skip_check_ = skip_check; }
3149 3296
3150 virtual Representation RequiredInputRepresentation(int arg_index) { 3297 virtual Representation RequiredInputRepresentation(int arg_index) {
3151 return representation(); 3298 return representation();
3152 } 3299 }
3153 virtual Representation observed_input_representation(int index) { 3300 virtual Representation observed_input_representation(int index) {
3154 return Representation::Integer32(); 3301 return Representation::Integer32();
3155 } 3302 }
3156 3303
3304 virtual bool CheckRelation(NumericRelation relation, HValue* related_value);
3305
3157 virtual void PrintDataTo(StringStream* stream); 3306 virtual void PrintDataTo(StringStream* stream);
3158 virtual void InferRepresentation(HInferRepresentation* h_infer); 3307 virtual void InferRepresentation(HInferRepresentation* h_infer);
3159 3308
3160 HValue* index() { return OperandAt(0); } 3309 HValue* index() { return OperandAt(0); }
3161 HValue* length() { return OperandAt(1); } 3310 HValue* length() { return OperandAt(1); }
3162 3311
3163 virtual int RedefinedOperandIndex() { return 0; } 3312 virtual int RedefinedOperandIndex() { return 0; }
3164 3313
3165 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck) 3314 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck)
3166 3315
(...skipping 2618 matching lines...) Expand 10 before | Expand all | Expand 10 after
5785 virtual bool IsDeletable() const { return true; } 5934 virtual bool IsDeletable() const { return true; }
5786 }; 5935 };
5787 5936
5788 5937
5789 #undef DECLARE_INSTRUCTION 5938 #undef DECLARE_INSTRUCTION
5790 #undef DECLARE_CONCRETE_INSTRUCTION 5939 #undef DECLARE_CONCRETE_INSTRUCTION
5791 5940
5792 } } // namespace v8::internal 5941 } } // namespace v8::internal
5793 5942
5794 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ 5943 #endif // V8_HYDROGEN_INSTRUCTIONS_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698