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

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

Issue 12377072: Handling expression decomposition and array bounds check hoisting: working code with lots of debugg… (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 9 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 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
68 V(AllocateObject) \ 68 V(AllocateObject) \
69 V(ApplyArguments) \ 69 V(ApplyArguments) \
70 V(ArgumentsElements) \ 70 V(ArgumentsElements) \
71 V(ArgumentsLength) \ 71 V(ArgumentsLength) \
72 V(ArgumentsObject) \ 72 V(ArgumentsObject) \
73 V(ArrayLiteral) \ 73 V(ArrayLiteral) \
74 V(Bitwise) \ 74 V(Bitwise) \
75 V(BitNot) \ 75 V(BitNot) \
76 V(BlockEntry) \ 76 V(BlockEntry) \
77 V(BoundsCheck) \ 77 V(BoundsCheck) \
78 V(BoundsCheckBaseIndexInformation) \
78 V(Branch) \ 79 V(Branch) \
79 V(CallConstantFunction) \ 80 V(CallConstantFunction) \
80 V(CallFunction) \ 81 V(CallFunction) \
81 V(CallGlobal) \ 82 V(CallGlobal) \
82 V(CallKeyed) \ 83 V(CallKeyed) \
83 V(CallKnownGlobal) \ 84 V(CallKnownGlobal) \
84 V(CallNamed) \ 85 V(CallNamed) \
85 V(CallNew) \ 86 V(CallNew) \
86 V(CallRuntime) \ 87 V(CallRuntime) \
87 V(CallStub) \ 88 V(CallStub) \
(...skipping 571 matching lines...) Expand 10 before | Expand all | Expand 10 after
659 case GT: return (direction >= 0); 660 case GT: return (direction >= 0);
660 case GE: return (direction >= 0); 661 case GE: return (direction >= 0);
661 case LT: return (direction <= 0); 662 case LT: return (direction <= 0);
662 case LE: return (direction <= 0); 663 case LE: return (direction <= 0);
663 case NE: return false; 664 case NE: return false;
664 } 665 }
665 UNREACHABLE(); 666 UNREACHABLE();
666 return false; 667 return false;
667 } 668 }
668 669
670 // CompoundOperandsAreCompatible returns true when
671 // "((x + my_offset) >> my_scale) rel y" implies
672 // "((x + other_offset) >> other_scale) rel y".
673 bool CompoundOperandsAreCompatible(int my_offset,
Jakob Kummerow 2013/03/11 11:55:02 I don't like this name. "compatible" in what sense
674 int my_scale,
675 int other_offset,
676 int other_scale) {
677 switch (kind_) {
678 case NONE: return false;
679 case EQ: return my_offset == other_offset && my_scale == other_scale;
Jakob Kummerow 2013/03/11 11:55:02 let's combine identical cases, i.e.: switch (
680 case GT: return my_offset <= other_offset && my_scale >= other_scale;
681 case GE: return my_offset <= other_offset && my_scale >= other_scale;
682 case LT: return my_offset >= other_offset && my_scale <= other_scale;
683 case LE: return my_offset >= other_offset && my_scale <= other_scale;
684 case NE: return my_offset == other_offset && my_scale == other_scale;
685 }
686 UNREACHABLE();
687 return false;
688 }
689
690 // CompoundOperandsAreCompatible returns true when
Jakob Kummerow 2013/03/11 11:55:02 comment is about the wrong method.
691 // "((x + my_offset) >> my_scale) rel y" implies
692 // "((x + other_offset) >> other_scale) other_relation y".
693 bool CompoundImplies(NumericRelation other_relation,
694 int my_offset,
695 int my_scale,
696 int other_offset = 0,
697 int other_scale = 0) {
698 return Implies(other_relation) && CompoundOperandsAreCompatible(
699 my_offset, my_scale, other_offset, other_scale);
700 }
701
669 private: 702 private:
670 explicit NumericRelation(Kind kind) : kind_(kind) {} 703 explicit NumericRelation(Kind kind) : kind_(kind) {}
671 704
672 Kind kind_; 705 Kind kind_;
673 }; 706 };
674 707
675 708
676 typedef EnumSet<GVNFlag> GVNFlagSet; 709 typedef EnumSet<GVNFlag> GVNFlagSet;
677 710
678 711
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
783 virtual void AssumeRepresentation(Representation r); 816 virtual void AssumeRepresentation(Representation r);
784 817
785 virtual bool IsConvertibleToInteger() const { return true; } 818 virtual bool IsConvertibleToInteger() const { return true; }
786 819
787 HType type() const { return type_; } 820 HType type() const { return type_; }
788 void set_type(HType new_type) { 821 void set_type(HType new_type) {
789 ASSERT(new_type.IsSubtypeOf(type_)); 822 ASSERT(new_type.IsSubtypeOf(type_));
790 type_ = new_type; 823 type_ = new_type;
791 } 824 }
792 825
826 // +++++++++++++
827 void SimplyPrint() {
828 HValue* base = NULL;
829 int offset = 0;
830 int scale = 0;
831 PrintF("%s%d(", representation().Mnemonic(), id());
832 if (TryDecompose(&base, &offset, &scale)) {
833 PrintF("(%s%d + %d) >> %d",
834 base->representation().Mnemonic(), base->id(), offset, scale);
835 } else if (IsInteger32Constant()) {
836 PrintF("CONSTANT %d", GetInteger32Constant());
837 } else {
838 PrintF("%s", Mnemonic());
839 }
840 PrintF(")");
841 }
842
843
793 // An operation needs to override this function iff: 844 // An operation needs to override this function iff:
794 // 1) it can produce an int32 output. 845 // 1) it can produce an int32 output.
795 // 2) the true value of its output can potentially be minus zero. 846 // 2) the true value of its output can potentially be minus zero.
796 // The implementation must set a flag so that it bails out in the case where 847 // The implementation must set a flag so that it bails out in the case where
797 // it would otherwise output what should be a minus zero as an int32 zero. 848 // it would otherwise output what should be a minus zero as an int32 zero.
798 // If the operation also exists in a form that takes int32 and outputs int32 849 // If the operation also exists in a form that takes int32 and outputs int32
799 // then the operation should return its input value so that we can propagate 850 // then the operation should return its input value so that we can propagate
800 // back. There are three operations that need to propagate back to more than 851 // back. There are three operations that need to propagate back to more than
801 // one input. They are phi and binary div and mul. They always return NULL 852 // one input. They are phi and binary div and mul. They always return NULL
802 // and expect the caller to take care of things. 853 // and expect the caller to take care of things.
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
968 bool IsDead() const { 1019 bool IsDead() const {
969 return HasNoUses() && !HasObservableSideEffects() && IsDeletable(); 1020 return HasNoUses() && !HasObservableSideEffects() && IsDeletable();
970 } 1021 }
971 1022
972 #ifdef DEBUG 1023 #ifdef DEBUG
973 virtual void Verify() = 0; 1024 virtual void Verify() = 0;
974 #endif 1025 #endif
975 1026
976 // This method is recursive but it is guaranteed to terminate because 1027 // This method is recursive but it is guaranteed to terminate because
977 // RedefinedOperand() always dominates "this". 1028 // RedefinedOperand() always dominates "this".
978 bool IsRelationTrue(NumericRelation relation, HValue* other) { 1029 bool IsRelationTrue(
Jakob Kummerow 2013/03/11 11:55:02 This method is big enough to move its implementati
1030 NumericRelation relation, HValue* other, int offset = 0, int scale = 0) {
Jakob Kummerow 2013/03/11 11:55:02 for method/function declarations (as opposed to ca
979 if (this == other) { 1031 if (this == other) {
980 return NumericRelation::Eq().Implies(relation); 1032 return NumericRelation::Eq().Implies(relation);
Jakob Kummerow 2013/03/11 11:55:02 Doesn't this need updating to account for offset/s
Massi 2013/03/13 15:58:14 No, this is a real identity check, if "this" and "
981 } 1033 }
982 1034
983 bool result = IsRelationTrueInternal(relation, other) || 1035 // Test the direct relation.
984 other->IsRelationTrueInternal(relation.Reversed(), this); 1036 if (IsRelationTrueInternal(relation, other, offset, scale)) return true;
985 if (!result) { 1037
986 HValue* redefined = RedefinedOperand(); 1038 // TODO: do we need the recursive pass? We are not doing it now...
987 if (redefined != NULL) { 1039 // If scale is 0 try the reversed relation (with the full recursive pass).
988 result = redefined->IsRelationTrue(relation, other); 1040 if (scale == 0 && other->IsRelationTrueInternal(relation.Reversed(), this,
989 } 1041 -offset)) return true;
Jakob Kummerow 2013/03/11 11:55:02 if-statements that span multiple lines need {}. I'
1042
1043 // Try decomposition.
1044 HValue* my_base = NULL;
1045 int my_offset = 0;
1046 int my_scale = 0;
1047 if (TryDecompose(&my_base, &my_offset, &my_scale) && my_scale == 0 &&
1048 my_base->IsRelationTrue(relation, other, offset + my_offset, scale)) {
1049 return true;
990 } 1050 }
991 return result; 1051
1052 // Pass the request to the redefined value.
1053 HValue* redefined = RedefinedOperand();
1054 return redefined != NULL && redefined->IsRelationTrue(relation, other,
1055 offset, scale);
1056 }
1057
1058 bool TryGuaranteeRange(HValue* upper_bound);
1059 virtual bool TryDecompose(HValue** base, int* offset, int* scale) {
1060 if (RedefinedOperand() != NULL) {
1061 return RedefinedOperand()->TryDecompose(base, offset, scale);
1062 } else {
1063 return false;
1064 }
992 } 1065 }
993 1066
994 protected: 1067 protected:
1068 class RangeEvaluationContext BASE_EMBEDDED {
Jakob Kummerow 2013/03/11 11:55:02 I'd prefer this to be a top-level class.
1069 public:
1070 HValue* lower_bound() { return lower_bound_; }
1071 HValue* lower_check_guarantee() { return lower_check_guarantee_; }
1072 HValue* origin() { return origin_; }
1073 HValue* upper_bound() { return upper_bound_; }
1074 HValue* upper_check_guarantee() { return upper_check_guarantee_; }
1075 int offset() { return offset_; }
1076 int scale() { return scale_; }
1077
1078 bool lower_check_satisfied() { return lower_check_guarantee_ != NULL; }
Jakob Kummerow 2013/03/11 11:55:02 I'd prefer not to have this method, because it add
Massi 2013/03/13 15:58:14 I ended up renaming the methods, and at this point
1079 bool upper_check_satisfied() { return upper_check_guarantee_ != NULL; }
1080 bool RangeSatisfied() {
Jakob Kummerow 2013/03/11 11:55:02 is_range_satisfied()
1081 return lower_check_satisfied() && upper_check_satisfied();
1082 }
1083
1084 void set_lower_check_guarantee(HValue* guarantee) {
1085 lower_check_guarantee_ = ConvertGuarantee(guarantee);
1086 }
1087 void set_upper_check_guarantee(HValue* guarantee) {
1088 upper_check_guarantee_ = ConvertGuarantee(guarantee);
1089 }
1090
1091 template <class T> void swap(T& a, T& b) {
Jakob Kummerow 2013/03/11 11:55:02 Private helper function should be private (or glob
1092 T c(a); a=b; b=c;
Jakob Kummerow 2013/03/11 11:55:02 nit: formatting: one statement per line, spaces ar
1093 }
1094
1095 void swap_origin(HValue*& other_origin,
Jakob Kummerow 2013/03/11 11:55:02 Again, all references must be const. Use pointers.
1096 int& other_offset,
1097 int& other_scale) {
1098 swap(origin_, other_origin);
1099 swap(offset_, other_offset);
1100 swap(scale_, other_scale);
1101 }
1102
1103 RangeEvaluationContext(HValue* value, HValue* upper);
Jakob Kummerow 2013/03/11 11:55:02 nit: constructor should be before methods (http://
1104 private:
Jakob Kummerow 2013/03/11 11:55:02 nit: empty line before "private:"
1105 HValue* ConvertGuarantee(HValue* guarantee);
1106
1107 HValue* lower_bound_;
1108 HValue* lower_check_guarantee_;
1109 HValue* origin_;
Jakob Kummerow 2013/03/11 11:55:02 I'm not too happy with the name "origin_", it's bi
1110 HValue* upper_bound_;
1111 HValue* upper_check_guarantee_;
1112 int offset_;
1113 int scale_;
1114 };
1115
1116 void TryGuaranteeRangeRecursive(RangeEvaluationContext* context);
1117 virtual void TryGuaranteeRangeInner(RangeEvaluationContext* context) {
1118
1119 if (FLAG_log_abcd) {
1120 PrintF(" !!! TryGuaranteeRangeInner(%s%d:%s): DEFAULT\n",
1121 representation().Mnemonic(), id(), Mnemonic());
1122 }
1123
1124 }
1125
995 // This function must be overridden for instructions with flag kUseGVN, to 1126 // This function must be overridden for instructions with flag kUseGVN, to
996 // compare the non-Operand parts of the instruction. 1127 // compare the non-Operand parts of the instruction.
997 virtual bool DataEquals(HValue* other) { 1128 virtual bool DataEquals(HValue* other) {
998 UNREACHABLE(); 1129 UNREACHABLE();
999 return false; 1130 return false;
1000 } 1131 }
1001 1132
1002 virtual Representation RepresentationFromInputs() { 1133 virtual Representation RepresentationFromInputs() {
1003 return representation(); 1134 return representation();
1004 } 1135 }
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1047 for (HUseIterator uses = input->uses(); !uses.Done(); uses.Advance()) { 1178 for (HUseIterator uses = input->uses(); !uses.Done(); uses.Advance()) {
1048 HValue* use = uses.value(); 1179 HValue* use = uses.value();
1049 if (TestDominance(this, use)) { 1180 if (TestDominance(this, use)) {
1050 use->SetOperandAt(uses.index(), this); 1181 use->SetOperandAt(uses.index(), this);
1051 } 1182 }
1052 } 1183 }
1053 } 1184 }
1054 } 1185 }
1055 1186
1056 // Informative definitions can override this method to state any numeric 1187 // Informative definitions can override this method to state any numeric
1057 // relation they provide on the redefined value. 1188 // relation they provide on the redefined value.
Jakob Kummerow 2013/03/11 11:55:02 Please extend this comment: // Returns true if it
1058 virtual bool IsRelationTrueInternal(NumericRelation relation, HValue* other) { 1189 virtual bool IsRelationTrueInternal(NumericRelation relation, HValue* other,
Jakob Kummerow 2013/03/11 11:55:02 for method/function declarations (as opposed to ca
1190 int offset = 0, int scale = 0) {
1059 return false; 1191 return false;
1060 } 1192 }
1061 1193
1062 static GVNFlagSet AllDependsOnFlagSet() { 1194 static GVNFlagSet AllDependsOnFlagSet() {
1063 GVNFlagSet result; 1195 GVNFlagSet result;
1064 // Create changes mask. 1196 // Create changes mask.
1065 #define ADD_FLAG(type) result.Add(kDependsOn##type); 1197 #define ADD_FLAG(type) result.Add(kDependsOn##type);
1066 GVN_TRACKED_FLAG_LIST(ADD_FLAG) 1198 GVN_TRACKED_FLAG_LIST(ADD_FLAG)
1067 GVN_UNTRACKED_FLAG_LIST(ADD_FLAG) 1199 GVN_UNTRACKED_FLAG_LIST(ADD_FLAG)
1068 #undef ADD_FLAG 1200 #undef ADD_FLAG
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after
1297 virtual int RedefinedOperandIndex() { return 0; } 1429 virtual int RedefinedOperandIndex() { return 0; }
1298 virtual bool IsPurelyInformativeDefinition() { return true; } 1430 virtual bool IsPurelyInformativeDefinition() { return true; }
1299 1431
1300 virtual Representation RequiredInputRepresentation(int index) { 1432 virtual Representation RequiredInputRepresentation(int index) {
1301 return representation(); 1433 return representation();
1302 } 1434 }
1303 1435
1304 virtual void PrintDataTo(StringStream* stream); 1436 virtual void PrintDataTo(StringStream* stream);
1305 1437
1306 virtual bool IsRelationTrueInternal(NumericRelation other_relation, 1438 virtual bool IsRelationTrueInternal(NumericRelation other_relation,
1307 HValue* other_related_value) { 1439 HValue* other_related_value,
1440 int offset = 0,
1441 int scale = 0) {
1308 if (related_value() == other_related_value) { 1442 if (related_value() == other_related_value) {
1309 return relation().Implies(other_relation); 1443 return relation().CompoundImplies(other_relation, offset, scale);
1310 } else { 1444 } else {
1311 return false; 1445 return false;
1312 } 1446 }
1313 } 1447 }
1314 1448
1315 DECLARE_CONCRETE_INSTRUCTION(NumericConstraint) 1449 DECLARE_CONCRETE_INSTRUCTION(NumericConstraint)
1316 1450
1317 private: 1451 private:
1318 HNumericConstraint(HValue* constrained_value, 1452 HNumericConstraint(HValue* constrained_value,
1319 NumericRelation relation, 1453 NumericRelation relation,
(...skipping 1632 matching lines...) Expand 10 before | Expand all | Expand 10 after
2952 } 3086 }
2953 return true; 3087 return true;
2954 } 3088 }
2955 3089
2956 protected: 3090 protected:
2957 virtual void DeleteFromGraph(); 3091 virtual void DeleteFromGraph();
2958 virtual void InternalSetOperandAt(int index, HValue* value) { 3092 virtual void InternalSetOperandAt(int index, HValue* value) {
2959 inputs_[index] = value; 3093 inputs_[index] = value;
2960 } 3094 }
2961 3095
2962 virtual bool IsRelationTrueInternal(NumericRelation relation, HValue* other); 3096 virtual bool IsRelationTrueInternal(
Jakob Kummerow 2013/03/11 11:55:02 for method/function declarations (as opposed to ca
3097 NumericRelation relation, HValue* other, int offset = 0, int scale = 0);
2963 3098
2964 private: 3099 private:
2965 ZoneList<HValue*> inputs_; 3100 ZoneList<HValue*> inputs_;
2966 int merged_index_; 3101 int merged_index_;
2967 3102
2968 int non_phi_uses_[Representation::kNumRepresentations]; 3103 int non_phi_uses_[Representation::kNumRepresentations];
2969 int indirect_uses_[Representation::kNumRepresentations]; 3104 int indirect_uses_[Representation::kNumRepresentations];
2970 int phi_id_; 3105 int phi_id_;
2971 bool is_live_; 3106 bool is_live_;
2972 bool is_convertible_to_integer_; 3107 bool is_convertible_to_integer_;
(...skipping 11 matching lines...) Expand all
2984 3119
2985 virtual int RedefinedOperandIndex() { return 0; } 3120 virtual int RedefinedOperandIndex() { return 0; }
2986 virtual bool IsPurelyInformativeDefinition() { return true; } 3121 virtual bool IsPurelyInformativeDefinition() { return true; }
2987 virtual Representation RequiredInputRepresentation(int index) { 3122 virtual Representation RequiredInputRepresentation(int index) {
2988 return representation(); 3123 return representation();
2989 } 3124 }
2990 3125
2991 virtual void PrintDataTo(StringStream* stream); 3126 virtual void PrintDataTo(StringStream* stream);
2992 3127
2993 virtual bool IsRelationTrueInternal(NumericRelation other_relation, 3128 virtual bool IsRelationTrueInternal(NumericRelation other_relation,
2994 HValue* other_related_value) { 3129 HValue* other_related_value,
3130 int offset = 0,
3131 int scale = 0) {
2995 if (induction_base() == other_related_value) { 3132 if (induction_base() == other_related_value) {
2996 return relation().Implies(other_relation); 3133 return relation().CompoundImplies(other_relation, offset, scale);
2997 } else { 3134 } else {
2998 return false; 3135 return false;
2999 } 3136 }
3000 } 3137 }
3001 3138
3002 DECLARE_CONCRETE_INSTRUCTION(InductionVariableAnnotation) 3139 DECLARE_CONCRETE_INSTRUCTION(InductionVariableAnnotation)
3003 3140
3004 private: 3141 private:
3005 HInductionVariableAnnotation(HPhi* phi, 3142 HInductionVariableAnnotation(HPhi* phi,
3006 NumericRelation relation, 3143 NumericRelation relation,
(...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after
3375 virtual bool DataEquals(HValue* other) { return true; } 3512 virtual bool DataEquals(HValue* other) { return true; }
3376 }; 3513 };
3377 3514
3378 3515
3379 enum BoundsCheckKeyMode { 3516 enum BoundsCheckKeyMode {
3380 DONT_ALLOW_SMI_KEY, 3517 DONT_ALLOW_SMI_KEY,
3381 ALLOW_SMI_KEY 3518 ALLOW_SMI_KEY
3382 }; 3519 };
3383 3520
3384 3521
3522 class HBoundsCheckBaseIndexInformation;
3523
3524
3385 class HBoundsCheck: public HTemplateInstruction<2> { 3525 class HBoundsCheck: public HTemplateInstruction<2> {
3386 public: 3526 public:
3527 friend class HBoundsCheckBaseIndexInformation;
Jakob Kummerow 2013/03/11 11:55:02 Friend declarations should always be in the "priva
3528
3387 // Normally HBoundsCheck should be created using the 3529 // Normally HBoundsCheck should be created using the
3388 // HGraphBuilder::AddBoundsCheck() helper, which also guards the index with 3530 // HGraphBuilder::AddBoundsCheck() helper, which also guards the index with
3389 // a HCheckSmiOrInt32 check. 3531 // a HCheckSmiOrInt32 check.
3390 // However when building stubs, where we know that the arguments are Int32, 3532 // However when building stubs, where we know that the arguments are Int32,
3391 // it makes sense to invoke this constructor directly. 3533 // it makes sense to invoke this constructor directly.
3392 HBoundsCheck(HValue* index, 3534 HBoundsCheck(HValue* index,
3393 HValue* length, 3535 HValue* length,
3394 BoundsCheckKeyMode key_mode = DONT_ALLOW_SMI_KEY, 3536 BoundsCheckKeyMode key_mode = DONT_ALLOW_SMI_KEY,
3395 Representation r = Representation::None()) 3537 Representation r = Representation::None())
3396 : key_mode_(key_mode), skip_check_(false) { 3538 : key_mode_(key_mode), skip_check_(false),
Jakob Kummerow 2013/03/11 11:55:02 let's put each initializer onto its own line.
3539 base_(NULL), offset_(0), scale_(0), change_direction_(0) {
3397 SetOperandAt(0, index); 3540 SetOperandAt(0, index);
3398 SetOperandAt(1, length); 3541 SetOperandAt(1, length);
3399 if (r.IsNone()) { 3542 if (r.IsNone()) {
3400 // In the normal compilation pipeline the representation is flexible 3543 // In the normal compilation pipeline the representation is flexible
3401 // (see InferRepresentation). 3544 // (see InferRepresentation).
3402 SetFlag(kFlexibleRepresentation); 3545 SetFlag(kFlexibleRepresentation);
3403 } else { 3546 } else {
3404 // When compiling stubs we want to set the representation explicitly 3547 // When compiling stubs we want to set the representation explicitly
3405 // so the compilation pipeline can skip the HInferRepresentation phase. 3548 // so the compilation pipeline can skip the HInferRepresentation phase.
3406 set_representation(r); 3549 set_representation(r);
3407 } 3550 }
3408 SetFlag(kUseGVN); 3551 SetFlag(kUseGVN);
3409 } 3552 }
3410 3553
3411 bool skip_check() { return skip_check_; } 3554 bool skip_check() { return skip_check_; }
3412 void set_skip_check(bool skip_check) { skip_check_ = skip_check; } 3555 void set_skip_check(bool skip_check) { skip_check_ = skip_check; }
3556 HValue* base() { return base_; }
3557 int offset() { return offset_; }
3558 int scale() { return scale_; }
3559 bool index_can_increase() { return change_direction_ >= 0; }
3560 bool index_can_decrease() { return change_direction_ <= 0; }
3561 bool index_has_not_been_changed() { return change_direction_ == 0; }
3562
3563 void ApplyIndexChange();
3564 bool DetectCompoundIndex() {
3565 ASSERT(base() == NULL);
Jakob Kummerow 2013/03/11 11:55:02 nit: You're using accessors ("base()") and direct
3566
3567 HValue* index_base = NULL;
3568 int index_offset = 0;
3569 int index_scale = 0;
3570 if (index()->TryDecompose(&index_base, &index_offset, &index_scale)) {
3571 base_ = index_base;
3572 offset_ = index_offset;
3573 scale_ = index_scale;
3574 return true;
3575 } else {
3576 base_ = index();
3577 offset_ = 0;
3578 scale_ = 0;
3579 return false;
3580 }
3581 }
3582 bool HasOriginalIndex() {
3583 if (base() == NULL) return true;
3584
3585 HValue* index_base = NULL;
3586 int index_offset = 0;
3587 int index_scale = 0;
3588 if (index()->TryDecompose(&index_base, &index_offset, &index_scale)) {
3589 ASSERT(index_base == base());
3590 return index_offset == offset() && index_scale == scale();
3591 } else {
3592 ASSERT(index() == base());
3593 return offset() == 0 && scale() == 0;
3594 }
3595 }
3413 3596
3414 virtual Representation RequiredInputRepresentation(int arg_index) { 3597 virtual Representation RequiredInputRepresentation(int arg_index) {
3415 return representation(); 3598 return representation();
3416 } 3599 }
3417 virtual Representation observed_input_representation(int index) { 3600 virtual Representation observed_input_representation(int index) {
3418 return Representation::Integer32(); 3601 return Representation::Integer32();
3419 } 3602 }
3420 3603
3421 virtual bool IsRelationTrueInternal(NumericRelation relation, 3604 virtual bool IsRelationTrueInternal(NumericRelation relation,
3422 HValue* related_value); 3605 HValue* related_value,
3606 int offset = 0,
3607 int scale = 0);
3423 3608
3424 virtual void PrintDataTo(StringStream* stream); 3609 virtual void PrintDataTo(StringStream* stream);
3425 virtual void InferRepresentation(HInferRepresentation* h_infer); 3610 virtual void InferRepresentation(HInferRepresentation* h_infer);
3426 3611
3427 HValue* index() { return OperandAt(0); } 3612 HValue* index() { return OperandAt(0); }
3428 HValue* length() { return OperandAt(1); } 3613 HValue* length() { return OperandAt(1); }
3429 3614
3430 virtual int RedefinedOperandIndex() { return 0; } 3615 virtual int RedefinedOperandIndex() { return 0; }
3431 virtual bool IsPurelyInformativeDefinition() { return skip_check(); } 3616 virtual bool IsPurelyInformativeDefinition() { return skip_check(); }
3432 virtual void AddInformativeDefinitions(); 3617 virtual void AddInformativeDefinitions();
3433 3618
3434 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck) 3619 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck)
3435 3620
3436 protected: 3621 protected:
3437 virtual bool DataEquals(HValue* other) { return true; } 3622 virtual bool DataEquals(HValue* other) { return true; }
3623 virtual void TryGuaranteeRangeInner(RangeEvaluationContext* context);
3438 BoundsCheckKeyMode key_mode_; 3624 BoundsCheckKeyMode key_mode_;
3439 bool skip_check_; 3625 bool skip_check_;
3626 HValue* base_;
3627 int offset_;
3628 int scale_;
3629 int change_direction_;
3440 }; 3630 };
3441 3631
3442 3632
3633 class HBoundsCheckBaseIndexInformation: public HTemplateInstruction<2> {
3634 public:
3635 HBoundsCheckBaseIndexInformation(HBoundsCheck* check) {
Jakob Kummerow 2013/03/11 11:55:02 explicit
3636 HValue* base = NULL;
3637 int offset = 0;
3638 int scale = 0;
3639 if (check->index()->TryDecompose(&base, &offset, &scale)) {
3640 SetOperandAt(0, base);
3641 SetOperandAt(1, check);
3642 } else {
3643 UNREACHABLE();
3644 }
3645 }
3646
3647 HValue* base_index() { return OperandAt(0); }
3648 HBoundsCheck* bounds_check() { return HBoundsCheck::cast(OperandAt(1)); }
3649
3650 DECLARE_CONCRETE_INSTRUCTION(BoundsCheckBaseIndexInformation)
3651
3652 virtual Representation RequiredInputRepresentation(int arg_index) {
3653 return representation();
3654 }
3655
3656 virtual bool IsRelationTrueInternal(NumericRelation relation,
3657 HValue* related_value,
3658 int offset = 0,
3659 int scale = 0);
3660 virtual void PrintDataTo(StringStream* stream);
3661
3662 virtual int RedefinedOperandIndex() { return 0; }
3663 virtual bool IsPurelyInformativeDefinition() { return true; }
3664
3665 protected:
3666 virtual void TryGuaranteeRangeInner(RangeEvaluationContext* context) {
3667
3668 if (FLAG_log_abcd) {
3669 PrintF(" !!! TryGuaranteeRangeInner(%s%d): BOUNDS INFO START\n",
3670 representation().Mnemonic(), id());
3671 }
3672
3673 bounds_check()->TryGuaranteeRangeInner(context);
3674
3675 if (FLAG_log_abcd) {
3676 PrintF(" !!! TryGuaranteeRangeInner(%s%d): BOUNDS INFO END\n",
3677 representation().Mnemonic(), id());
3678 }
3679
3680 }
3681 };
3682
3683
3443 class HBitwiseBinaryOperation: public HBinaryOperation { 3684 class HBitwiseBinaryOperation: public HBinaryOperation {
3444 public: 3685 public:
3445 HBitwiseBinaryOperation(HValue* context, HValue* left, HValue* right) 3686 HBitwiseBinaryOperation(HValue* context, HValue* left, HValue* right)
3446 : HBinaryOperation(context, left, right) { 3687 : HBinaryOperation(context, left, right) {
3447 SetFlag(kFlexibleRepresentation); 3688 SetFlag(kFlexibleRepresentation);
3448 SetFlag(kTruncatingToInt32); 3689 SetFlag(kTruncatingToInt32);
3449 SetAllSideEffects(); 3690 SetAllSideEffects();
3450 } 3691 }
3451 3692
3452 virtual Representation RequiredInputRepresentation(int index) { 3693 virtual Representation RequiredInputRepresentation(int index) {
(...skipping 552 matching lines...) Expand 10 before | Expand all | Expand 10 after
4005 4246
4006 static HInstruction* NewHAdd(Zone* zone, 4247 static HInstruction* NewHAdd(Zone* zone,
4007 HValue* context, 4248 HValue* context,
4008 HValue* left, 4249 HValue* left,
4009 HValue* right); 4250 HValue* right);
4010 4251
4011 virtual HType CalculateInferredType(); 4252 virtual HType CalculateInferredType();
4012 4253
4013 virtual HValue* Canonicalize(); 4254 virtual HValue* Canonicalize();
4014 4255
4015 virtual bool IsRelationTrueInternal(NumericRelation relation, HValue* other) { 4256 virtual bool TryDecompose(HValue** base, int* offset, int* scale) {
4016 HValue* base = NULL;
4017 int32_t offset = 0;
4018 if (left()->IsInteger32Constant()) { 4257 if (left()->IsInteger32Constant()) {
4019 base = right(); 4258 *base = right();
4020 offset = left()->GetInteger32Constant(); 4259 *offset += left()->GetInteger32Constant();
4260 return true;
4021 } else if (right()->IsInteger32Constant()) { 4261 } else if (right()->IsInteger32Constant()) {
4022 base = left(); 4262 *base = left();
4023 offset = right()->GetInteger32Constant(); 4263 *offset += right()->GetInteger32Constant();
4264 return true;
4024 } else { 4265 } else {
4025 return false; 4266 return false;
4026 } 4267 }
4027
4028 return relation.IsExtendable(offset)
4029 ? base->IsRelationTrue(relation, other) : false;
4030 } 4268 }
4031 4269
4032 DECLARE_CONCRETE_INSTRUCTION(Add) 4270 DECLARE_CONCRETE_INSTRUCTION(Add)
4033 4271
4034 protected: 4272 protected:
4035 virtual bool DataEquals(HValue* other) { return true; } 4273 virtual bool DataEquals(HValue* other) { return true; }
4036 4274
4037 virtual Range* InferRange(Zone* zone); 4275 virtual Range* InferRange(Zone* zone);
4038 }; 4276 };
4039 4277
4040 4278
4041 class HSub: public HArithmeticBinaryOperation { 4279 class HSub: public HArithmeticBinaryOperation {
4042 public: 4280 public:
4043 HSub(HValue* context, HValue* left, HValue* right) 4281 HSub(HValue* context, HValue* left, HValue* right)
4044 : HArithmeticBinaryOperation(context, left, right) { 4282 : HArithmeticBinaryOperation(context, left, right) {
4045 SetFlag(kCanOverflow); 4283 SetFlag(kCanOverflow);
4046 } 4284 }
4047 4285
4048 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); 4286 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
4049 4287
4050 virtual HValue* Canonicalize(); 4288 virtual HValue* Canonicalize();
4051 4289
4052 static HInstruction* NewHSub(Zone* zone, 4290 static HInstruction* NewHSub(Zone* zone,
4053 HValue* context, 4291 HValue* context,
4054 HValue* left, 4292 HValue* left,
4055 HValue* right); 4293 HValue* right);
4056 4294
4057 virtual bool IsRelationTrueInternal(NumericRelation relation, HValue* other) { 4295 virtual bool TryDecompose(HValue** base, int* offset, int* scale) {
4058 if (right()->IsInteger32Constant()) { 4296 if (right()->IsInteger32Constant()) {
4059 HValue* base = left(); 4297 *base = left();
4060 int32_t offset = right()->GetInteger32Constant(); 4298 *offset -= right()->GetInteger32Constant();
4061 return relation.IsExtendable(-offset) 4299 return true;
4062 ? base->IsRelationTrue(relation, other) : false;
4063 } else { 4300 } else {
4064 return false; 4301 return false;
4065 } 4302 }
4066 } 4303 }
4067 4304
4068 DECLARE_CONCRETE_INSTRUCTION(Sub) 4305 DECLARE_CONCRETE_INSTRUCTION(Sub)
4069 4306
4070 protected: 4307 protected:
4071 virtual bool DataEquals(HValue* other) { return true; } 4308 virtual bool DataEquals(HValue* other) { return true; }
4072 4309
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
4292 }; 4529 };
4293 4530
4294 4531
4295 class HSar: public HBitwiseBinaryOperation { 4532 class HSar: public HBitwiseBinaryOperation {
4296 public: 4533 public:
4297 HSar(HValue* context, HValue* left, HValue* right) 4534 HSar(HValue* context, HValue* left, HValue* right)
4298 : HBitwiseBinaryOperation(context, left, right) { } 4535 : HBitwiseBinaryOperation(context, left, right) { }
4299 4536
4300 virtual Range* InferRange(Zone* zone); 4537 virtual Range* InferRange(Zone* zone);
4301 4538
4539 virtual bool TryDecompose(HValue** base, int* offset, int* scale) {
4540 if (!scale != 0) return false;
4541
4542 if (right()->IsInteger32Constant()) {
4543 *base = left();
4544 *scale = right()->GetInteger32Constant();
4545 // Note that this call can change *base again, this is intended to
4546 // also take HAdd and HSub effects on offset into account.
4547 (*base)->TryDecompose(base, offset, scale);
4548 return true;
4549 } else {
4550 return false;
4551 }
4552 }
4553
4302 static HInstruction* NewHSar(Zone* zone, 4554 static HInstruction* NewHSar(Zone* zone,
4303 HValue* context, 4555 HValue* context,
4304 HValue* left, 4556 HValue* left,
4305 HValue* right); 4557 HValue* right);
4306 4558
4307 DECLARE_CONCRETE_INSTRUCTION(Sar) 4559 DECLARE_CONCRETE_INSTRUCTION(Sar)
4308 4560
4309 protected: 4561 protected:
4310 virtual bool DataEquals(HValue* other) { return true; } 4562 virtual bool DataEquals(HValue* other) { return true; }
4311 }; 4563 };
(...skipping 1772 matching lines...) Expand 10 before | Expand all | Expand 10 after
6084 virtual bool IsDeletable() const { return true; } 6336 virtual bool IsDeletable() const { return true; }
6085 }; 6337 };
6086 6338
6087 6339
6088 #undef DECLARE_INSTRUCTION 6340 #undef DECLARE_INSTRUCTION
6089 #undef DECLARE_CONCRETE_INSTRUCTION 6341 #undef DECLARE_CONCRETE_INSTRUCTION
6090 6342
6091 } } // namespace v8::internal 6343 } } // namespace v8::internal
6092 6344
6093 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ 6345 #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