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

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: Rebased on master and fixed conflicts. 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
« no previous file with comments | « src/hydrogen.cc ('k') | src/hydrogen-instructions.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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(CallNewArray) \ 87 V(CallNewArray) \
87 V(CallRuntime) \ 88 V(CallRuntime) \
(...skipping 572 matching lines...) Expand 10 before | Expand all | Expand 10 after
660 case GT: return (direction >= 0); 661 case GT: return (direction >= 0);
661 case GE: return (direction >= 0); 662 case GE: return (direction >= 0);
662 case LT: return (direction <= 0); 663 case LT: return (direction <= 0);
663 case LE: return (direction <= 0); 664 case LE: return (direction <= 0);
664 case NE: return false; 665 case NE: return false;
665 } 666 }
666 UNREACHABLE(); 667 UNREACHABLE();
667 return false; 668 return false;
668 } 669 }
669 670
671 // CompoundImplies returns true when
672 // "((x + my_offset) >> my_scale) rel y" implies
673 // "((x + other_offset) >> other_scale) other_relation y".
674 bool CompoundImplies(NumericRelation other_relation,
675 int my_offset,
676 int my_scale,
677 int other_offset = 0,
678 int other_scale = 0) {
679 return Implies(other_relation) && ComponentsImply(
680 my_offset, my_scale, other_offset, other_scale);
681 }
682
670 private: 683 private:
684 // ComponentsImply returns true when
685 // "((x + my_offset) >> my_scale) rel y" implies
686 // "((x + other_offset) >> other_scale) rel y".
687 bool ComponentsImply(int my_offset,
688 int my_scale,
689 int other_offset,
690 int other_scale) {
691 switch (kind_) {
692 case NONE: break; // Fall through to UNREACHABLE().
693 case EQ:
694 case NE: return my_offset == other_offset && my_scale == other_scale;
695 case GT:
696 case GE: return my_offset <= other_offset && my_scale >= other_scale;
697 case LT:
698 case LE: return my_offset >= other_offset && my_scale <= other_scale;
699 }
700 UNREACHABLE();
701 return false;
702 }
703
671 explicit NumericRelation(Kind kind) : kind_(kind) {} 704 explicit NumericRelation(Kind kind) : kind_(kind) {}
672 705
673 Kind kind_; 706 Kind kind_;
674 }; 707 };
675 708
676 709
710 class DecompositionResult BASE_EMBEDDED {
711 public:
712 DecompositionResult() : base_(NULL), offset_(0), scale_(0) {}
713
714 HValue* base() { return base_; }
715 int offset() { return offset_; }
716 int scale() { return scale_; }
717
718 bool Apply(HValue* other_base, int other_offset, int other_scale = 0) {
719 if (base_ == NULL) {
720 base_ = other_base;
721 offset_ = other_offset;
722 scale_ = other_scale;
723 return true;
724 } else {
725 if (scale_ == 0) {
726 base_ = other_base;
727 offset_ += other_offset;
728 scale_ = other_scale;
729 return true;
730 } else {
731 return false;
732 }
733 }
734 }
735
736 void SwapValues(HValue** other_base, int* other_offset, int* other_scale) {
737 swap(&base_, other_base);
738 swap(&offset_, other_offset);
739 swap(&scale_, other_scale);
740 }
741
742 private:
743 template <class T> void swap(T* a, T* b) {
744 T c(*a);
745 *a = *b;
746 *b = c;
747 }
748
749 HValue* base_;
750 int offset_;
751 int scale_;
752 };
753
754
755 class RangeEvaluationContext BASE_EMBEDDED {
756 public:
757 RangeEvaluationContext(HValue* value, HValue* upper);
758
759 HValue* lower_bound() { return lower_bound_; }
760 HValue* lower_bound_guarantee() { return lower_bound_guarantee_; }
761 HValue* candidate() { return candidate_; }
762 HValue* upper_bound() { return upper_bound_; }
763 HValue* upper_bound_guarantee() { return upper_bound_guarantee_; }
764 int offset() { return offset_; }
765 int scale() { return scale_; }
766
767 bool is_range_satisfied() {
768 return lower_bound_guarantee() != NULL && upper_bound_guarantee() != NULL;
769 }
770
771 void set_lower_bound_guarantee(HValue* guarantee) {
772 lower_bound_guarantee_ = ConvertGuarantee(guarantee);
773 }
774 void set_upper_bound_guarantee(HValue* guarantee) {
775 upper_bound_guarantee_ = ConvertGuarantee(guarantee);
776 }
777
778 void swap_candidate(DecompositionResult* other_candicate) {
779 other_candicate->SwapValues(&candidate_, &offset_, &scale_);
780 }
781
782 private:
783 HValue* ConvertGuarantee(HValue* guarantee);
784
785 HValue* lower_bound_;
786 HValue* lower_bound_guarantee_;
787 HValue* candidate_;
788 HValue* upper_bound_;
789 HValue* upper_bound_guarantee_;
790 int offset_;
791 int scale_;
792 };
793
794
677 typedef EnumSet<GVNFlag> GVNFlagSet; 795 typedef EnumSet<GVNFlag> GVNFlagSet;
678 796
679 797
680 class HValue: public ZoneObject { 798 class HValue: public ZoneObject {
681 public: 799 public:
682 static const int kNoNumber = -1; 800 static const int kNoNumber = -1;
683 801
684 enum Flag { 802 enum Flag {
685 kFlexibleRepresentation, 803 kFlexibleRepresentation,
686 // Participate in Global Value Numbering, i.e. elimination of 804 // Participate in Global Value Numbering, i.e. elimination of
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after
970 } 1088 }
971 1089
972 bool IsDead() const { 1090 bool IsDead() const {
973 return HasNoUses() && !HasObservableSideEffects() && IsDeletable(); 1091 return HasNoUses() && !HasObservableSideEffects() && IsDeletable();
974 } 1092 }
975 1093
976 #ifdef DEBUG 1094 #ifdef DEBUG
977 virtual void Verify() = 0; 1095 virtual void Verify() = 0;
978 #endif 1096 #endif
979 1097
980 // This method is recursive but it is guaranteed to terminate because 1098 bool IsRelationTrue(NumericRelation relation,
981 // RedefinedOperand() always dominates "this". 1099 HValue* other,
982 bool IsRelationTrue(NumericRelation relation, HValue* other) { 1100 int offset = 0,
983 if (this == other) { 1101 int scale = 0);
984 return NumericRelation::Eq().Implies(relation); 1102
1103 bool TryGuaranteeRange(HValue* upper_bound);
1104 virtual bool TryDecompose(DecompositionResult* decomposition) {
1105 if (RedefinedOperand() != NULL) {
1106 return RedefinedOperand()->TryDecompose(decomposition);
1107 } else {
1108 return false;
985 } 1109 }
986
987 bool result = IsRelationTrueInternal(relation, other) ||
988 other->IsRelationTrueInternal(relation.Reversed(), this);
989 if (!result) {
990 HValue* redefined = RedefinedOperand();
991 if (redefined != NULL) {
992 result = redefined->IsRelationTrue(relation, other);
993 }
994 }
995 return result;
996 } 1110 }
997 1111
998 protected: 1112 protected:
1113 void TryGuaranteeRangeRecursive(RangeEvaluationContext* context);
1114
1115 enum RangeGuaranteeDirection {
1116 DIRECTION_NONE = 0,
1117 DIRECTION_UPPER = 1,
1118 DIRECTION_LOWER = 2,
1119 DIRECTION_BOTH = DIRECTION_UPPER | DIRECTION_LOWER
1120 };
1121 virtual void SetResponsibilityForRange(RangeGuaranteeDirection direction) {}
1122 virtual void TryGuaranteeRangeChanging(RangeEvaluationContext* context) {}
1123
999 // This function must be overridden for instructions with flag kUseGVN, to 1124 // This function must be overridden for instructions with flag kUseGVN, to
1000 // compare the non-Operand parts of the instruction. 1125 // compare the non-Operand parts of the instruction.
1001 virtual bool DataEquals(HValue* other) { 1126 virtual bool DataEquals(HValue* other) {
1002 UNREACHABLE(); 1127 UNREACHABLE();
1003 return false; 1128 return false;
1004 } 1129 }
1005 1130
1006 virtual Representation RepresentationFromInputs() { 1131 virtual Representation RepresentationFromInputs() {
1007 return representation(); 1132 return representation();
1008 } 1133 }
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1052 HValue* use = uses.value(); 1177 HValue* use = uses.value();
1053 if (TestDominance(this, use)) { 1178 if (TestDominance(this, use)) {
1054 use->SetOperandAt(uses.index(), this); 1179 use->SetOperandAt(uses.index(), this);
1055 } 1180 }
1056 } 1181 }
1057 } 1182 }
1058 } 1183 }
1059 1184
1060 // Informative definitions can override this method to state any numeric 1185 // Informative definitions can override this method to state any numeric
1061 // relation they provide on the redefined value. 1186 // relation they provide on the redefined value.
1062 virtual bool IsRelationTrueInternal(NumericRelation relation, HValue* other) { 1187 // Returns true if it is guaranteed that:
1188 // ((this + offset) >> scale) relation other
1189 virtual bool IsRelationTrueInternal(NumericRelation relation,
1190 HValue* other,
1191 int offset = 0,
1192 int scale = 0) {
1063 return false; 1193 return false;
1064 } 1194 }
1065 1195
1066 static GVNFlagSet AllDependsOnFlagSet() { 1196 static GVNFlagSet AllDependsOnFlagSet() {
1067 GVNFlagSet result; 1197 GVNFlagSet result;
1068 // Create changes mask. 1198 // Create changes mask.
1069 #define ADD_FLAG(type) result.Add(kDependsOn##type); 1199 #define ADD_FLAG(type) result.Add(kDependsOn##type);
1070 GVN_TRACKED_FLAG_LIST(ADD_FLAG) 1200 GVN_TRACKED_FLAG_LIST(ADD_FLAG)
1071 GVN_UNTRACKED_FLAG_LIST(ADD_FLAG) 1201 GVN_UNTRACKED_FLAG_LIST(ADD_FLAG)
1072 #undef ADD_FLAG 1202 #undef ADD_FLAG
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after
1301 virtual int RedefinedOperandIndex() { return 0; } 1431 virtual int RedefinedOperandIndex() { return 0; }
1302 virtual bool IsPurelyInformativeDefinition() { return true; } 1432 virtual bool IsPurelyInformativeDefinition() { return true; }
1303 1433
1304 virtual Representation RequiredInputRepresentation(int index) { 1434 virtual Representation RequiredInputRepresentation(int index) {
1305 return representation(); 1435 return representation();
1306 } 1436 }
1307 1437
1308 virtual void PrintDataTo(StringStream* stream); 1438 virtual void PrintDataTo(StringStream* stream);
1309 1439
1310 virtual bool IsRelationTrueInternal(NumericRelation other_relation, 1440 virtual bool IsRelationTrueInternal(NumericRelation other_relation,
1311 HValue* other_related_value) { 1441 HValue* other_related_value,
1442 int offset = 0,
1443 int scale = 0) {
1312 if (related_value() == other_related_value) { 1444 if (related_value() == other_related_value) {
1313 return relation().Implies(other_relation); 1445 return relation().CompoundImplies(other_relation, offset, scale);
1314 } else { 1446 } else {
1315 return false; 1447 return false;
1316 } 1448 }
1317 } 1449 }
1318 1450
1319 DECLARE_CONCRETE_INSTRUCTION(NumericConstraint) 1451 DECLARE_CONCRETE_INSTRUCTION(NumericConstraint)
1320 1452
1321 private: 1453 private:
1322 HNumericConstraint(HValue* constrained_value, 1454 HNumericConstraint(HValue* constrained_value,
1323 NumericRelation relation, 1455 NumericRelation relation,
1324 HValue* related_value) 1456 HValue* related_value)
1325 : relation_(relation) { 1457 : relation_(relation) {
1326 SetOperandAt(0, constrained_value); 1458 SetOperandAt(0, constrained_value);
1327 SetOperandAt(1, related_value); 1459 SetOperandAt(1, related_value);
1328 set_representation(constrained_value->representation());
1329 } 1460 }
1330 1461
1331 NumericRelation relation_; 1462 NumericRelation relation_;
1332 }; 1463 };
1333 1464
1334 1465
1335 // We insert soft-deoptimize when we hit code with unknown typefeedback, 1466 // We insert soft-deoptimize when we hit code with unknown typefeedback,
1336 // so that we get a chance of re-optimizing with useful typefeedback. 1467 // so that we get a chance of re-optimizing with useful typefeedback.
1337 // HSoftDeoptimize does not end a basic block as opposed to HDeoptimize. 1468 // HSoftDeoptimize does not end a basic block as opposed to HDeoptimize.
1338 class HSoftDeoptimize: public HTemplateInstruction<0> { 1469 class HSoftDeoptimize: public HTemplateInstruction<0> {
(...skipping 1646 matching lines...) Expand 10 before | Expand all | Expand 10 after
2985 } 3116 }
2986 return true; 3117 return true;
2987 } 3118 }
2988 3119
2989 protected: 3120 protected:
2990 virtual void DeleteFromGraph(); 3121 virtual void DeleteFromGraph();
2991 virtual void InternalSetOperandAt(int index, HValue* value) { 3122 virtual void InternalSetOperandAt(int index, HValue* value) {
2992 inputs_[index] = value; 3123 inputs_[index] = value;
2993 } 3124 }
2994 3125
2995 virtual bool IsRelationTrueInternal(NumericRelation relation, HValue* other); 3126 virtual bool IsRelationTrueInternal(NumericRelation relation,
3127 HValue* other,
3128 int offset = 0,
3129 int scale = 0);
2996 3130
2997 private: 3131 private:
2998 ZoneList<HValue*> inputs_; 3132 ZoneList<HValue*> inputs_;
2999 int merged_index_; 3133 int merged_index_;
3000 3134
3001 int non_phi_uses_[Representation::kNumRepresentations]; 3135 int non_phi_uses_[Representation::kNumRepresentations];
3002 int indirect_uses_[Representation::kNumRepresentations]; 3136 int indirect_uses_[Representation::kNumRepresentations];
3003 int phi_id_; 3137 int phi_id_;
3004 bool is_live_; 3138 bool is_live_;
3005 bool is_convertible_to_integer_; 3139 bool is_convertible_to_integer_;
(...skipping 11 matching lines...) Expand all
3017 3151
3018 virtual int RedefinedOperandIndex() { return 0; } 3152 virtual int RedefinedOperandIndex() { return 0; }
3019 virtual bool IsPurelyInformativeDefinition() { return true; } 3153 virtual bool IsPurelyInformativeDefinition() { return true; }
3020 virtual Representation RequiredInputRepresentation(int index) { 3154 virtual Representation RequiredInputRepresentation(int index) {
3021 return representation(); 3155 return representation();
3022 } 3156 }
3023 3157
3024 virtual void PrintDataTo(StringStream* stream); 3158 virtual void PrintDataTo(StringStream* stream);
3025 3159
3026 virtual bool IsRelationTrueInternal(NumericRelation other_relation, 3160 virtual bool IsRelationTrueInternal(NumericRelation other_relation,
3027 HValue* other_related_value) { 3161 HValue* other_related_value,
3162 int offset = 0,
3163 int scale = 0) {
3028 if (induction_base() == other_related_value) { 3164 if (induction_base() == other_related_value) {
3029 return relation().Implies(other_relation); 3165 return relation().CompoundImplies(other_relation, offset, scale);
3030 } else { 3166 } else {
3031 return false; 3167 return false;
3032 } 3168 }
3033 } 3169 }
3034 3170
3035 DECLARE_CONCRETE_INSTRUCTION(InductionVariableAnnotation) 3171 DECLARE_CONCRETE_INSTRUCTION(InductionVariableAnnotation)
3036 3172
3037 private: 3173 private:
3038 HInductionVariableAnnotation(HPhi* phi, 3174 HInductionVariableAnnotation(HPhi* phi,
3039 NumericRelation relation, 3175 NumericRelation relation,
3040 int operand_index) 3176 int operand_index)
3041 : HUnaryOperation(phi), 3177 : HUnaryOperation(phi),
3042 phi_(phi), relation_(relation), operand_index_(operand_index) { 3178 phi_(phi), relation_(relation), operand_index_(operand_index) {
3043 set_representation(phi->representation());
3044 } 3179 }
3045 3180
3046 // We need to store the phi both here and in the instruction operand because 3181 // We need to store the phi both here and in the instruction operand because
3047 // the operand can change if a new idef of the phi is added between the phi 3182 // the operand can change if a new idef of the phi is added between the phi
3048 // and this instruction (inserting an idef updates every use). 3183 // and this instruction (inserting an idef updates every use).
3049 HPhi* phi_; 3184 HPhi* phi_;
3050 NumericRelation relation_; 3185 NumericRelation relation_;
3051 int operand_index_; 3186 int operand_index_;
3052 }; 3187 };
3053 3188
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after
3438 virtual bool DataEquals(HValue* other) { return true; } 3573 virtual bool DataEquals(HValue* other) { return true; }
3439 }; 3574 };
3440 3575
3441 3576
3442 enum BoundsCheckKeyMode { 3577 enum BoundsCheckKeyMode {
3443 DONT_ALLOW_SMI_KEY, 3578 DONT_ALLOW_SMI_KEY,
3444 ALLOW_SMI_KEY 3579 ALLOW_SMI_KEY
3445 }; 3580 };
3446 3581
3447 3582
3583 class HBoundsCheckBaseIndexInformation;
3584
3585
3448 class HBoundsCheck: public HTemplateInstruction<2> { 3586 class HBoundsCheck: public HTemplateInstruction<2> {
3449 public: 3587 public:
3450 // Normally HBoundsCheck should be created using the 3588 // Normally HBoundsCheck should be created using the
3451 // HGraphBuilder::AddBoundsCheck() helper, which also guards the index with 3589 // HGraphBuilder::AddBoundsCheck() helper, which also guards the index with
3452 // a HCheckSmiOrInt32 check. 3590 // a HCheckSmiOrInt32 check.
3453 // However when building stubs, where we know that the arguments are Int32, 3591 // However when building stubs, where we know that the arguments are Int32,
3454 // it makes sense to invoke this constructor directly. 3592 // it makes sense to invoke this constructor directly.
3455 HBoundsCheck(HValue* index, 3593 HBoundsCheck(HValue* index,
3456 HValue* length, 3594 HValue* length,
3457 BoundsCheckKeyMode key_mode = DONT_ALLOW_SMI_KEY, 3595 BoundsCheckKeyMode key_mode = DONT_ALLOW_SMI_KEY,
3458 Representation r = Representation::None()) 3596 Representation r = Representation::None())
3459 : key_mode_(key_mode), skip_check_(false) { 3597 : key_mode_(key_mode), skip_check_(false),
3598 base_(NULL), offset_(0), scale_(0),
3599 responsibility_direction_(DIRECTION_NONE) {
3460 SetOperandAt(0, index); 3600 SetOperandAt(0, index);
3461 SetOperandAt(1, length); 3601 SetOperandAt(1, length);
3462 if (r.IsNone()) { 3602 if (r.IsNone()) {
3463 // In the normal compilation pipeline the representation is flexible 3603 // In the normal compilation pipeline the representation is flexible
3464 // (see InferRepresentation). 3604 // (see InferRepresentation).
3465 SetFlag(kFlexibleRepresentation); 3605 SetFlag(kFlexibleRepresentation);
3466 } else { 3606 } else {
3467 // When compiling stubs we want to set the representation explicitly 3607 // When compiling stubs we want to set the representation explicitly
3468 // so the compilation pipeline can skip the HInferRepresentation phase. 3608 // so the compilation pipeline can skip the HInferRepresentation phase.
3469 set_representation(r); 3609 set_representation(r);
3470 } 3610 }
3471 SetFlag(kUseGVN); 3611 SetFlag(kUseGVN);
3472 } 3612 }
3473 3613
3474 bool skip_check() { return skip_check_; } 3614 bool skip_check() { return skip_check_; }
3475 void set_skip_check(bool skip_check) { skip_check_ = skip_check; } 3615 void set_skip_check(bool skip_check) { skip_check_ = skip_check; }
3616 HValue* base() { return base_; }
3617 int offset() { return offset_; }
3618 int scale() { return scale_; }
3619 bool index_can_increase() {
3620 return (responsibility_direction_ & DIRECTION_LOWER) == 0;
3621 }
3622 bool index_can_decrease() {
3623 return (responsibility_direction_ & DIRECTION_UPPER) == 0;
3624 }
3625
3626 void ApplyIndexChange();
3627 bool DetectCompoundIndex() {
3628 ASSERT(base() == NULL);
3629
3630 DecompositionResult decomposition;
3631 if (index()->TryDecompose(&decomposition)) {
3632 base_ = decomposition.base();
3633 offset_ = decomposition.offset();
3634 scale_ = decomposition.scale();
3635 return true;
3636 } else {
3637 base_ = index();
3638 offset_ = 0;
3639 scale_ = 0;
3640 return false;
3641 }
3642 }
3476 3643
3477 virtual Representation RequiredInputRepresentation(int arg_index) { 3644 virtual Representation RequiredInputRepresentation(int arg_index) {
3478 return representation(); 3645 return representation();
3479 } 3646 }
3480 virtual Representation observed_input_representation(int index) { 3647 virtual Representation observed_input_representation(int index) {
3481 return Representation::Integer32(); 3648 return Representation::Integer32();
3482 } 3649 }
3483 3650
3484 virtual bool IsRelationTrueInternal(NumericRelation relation, 3651 virtual bool IsRelationTrueInternal(NumericRelation relation,
3485 HValue* related_value); 3652 HValue* related_value,
3653 int offset = 0,
3654 int scale = 0);
3486 3655
3487 virtual void PrintDataTo(StringStream* stream); 3656 virtual void PrintDataTo(StringStream* stream);
3488 virtual void InferRepresentation(HInferRepresentation* h_infer); 3657 virtual void InferRepresentation(HInferRepresentation* h_infer);
3489 3658
3490 HValue* index() { return OperandAt(0); } 3659 HValue* index() { return OperandAt(0); }
3491 HValue* length() { return OperandAt(1); } 3660 HValue* length() { return OperandAt(1); }
3492 3661
3493 virtual int RedefinedOperandIndex() { return 0; } 3662 virtual int RedefinedOperandIndex() { return 0; }
3494 virtual bool IsPurelyInformativeDefinition() { return skip_check(); } 3663 virtual bool IsPurelyInformativeDefinition() { return skip_check(); }
3495 virtual void AddInformativeDefinitions(); 3664 virtual void AddInformativeDefinitions();
3496 3665
3497 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck) 3666 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck)
3498 3667
3499 protected: 3668 protected:
3669 friend class HBoundsCheckBaseIndexInformation;
3670
3671 virtual void SetResponsibilityForRange(RangeGuaranteeDirection direction) {
3672 responsibility_direction_ = static_cast<RangeGuaranteeDirection>(
3673 responsibility_direction_ | direction);
3674 }
3675
3500 virtual bool DataEquals(HValue* other) { return true; } 3676 virtual bool DataEquals(HValue* other) { return true; }
3677 virtual void TryGuaranteeRangeChanging(RangeEvaluationContext* context);
3501 BoundsCheckKeyMode key_mode_; 3678 BoundsCheckKeyMode key_mode_;
3502 bool skip_check_; 3679 bool skip_check_;
3680 HValue* base_;
3681 int offset_;
3682 int scale_;
3683 RangeGuaranteeDirection responsibility_direction_;
3503 }; 3684 };
3504 3685
3505 3686
3687 class HBoundsCheckBaseIndexInformation: public HTemplateInstruction<2> {
3688 public:
3689 explicit HBoundsCheckBaseIndexInformation(HBoundsCheck* check) {
3690 DecompositionResult decomposition;
3691 if (check->index()->TryDecompose(&decomposition)) {
3692 SetOperandAt(0, decomposition.base());
3693 SetOperandAt(1, check);
3694 } else {
3695 UNREACHABLE();
3696 }
3697 }
3698
3699 HValue* base_index() { return OperandAt(0); }
3700 HBoundsCheck* bounds_check() { return HBoundsCheck::cast(OperandAt(1)); }
3701
3702 DECLARE_CONCRETE_INSTRUCTION(BoundsCheckBaseIndexInformation)
3703
3704 virtual Representation RequiredInputRepresentation(int arg_index) {
3705 return representation();
3706 }
3707
3708 virtual bool IsRelationTrueInternal(NumericRelation relation,
3709 HValue* related_value,
3710 int offset = 0,
3711 int scale = 0);
3712 virtual void PrintDataTo(StringStream* stream);
3713
3714 virtual int RedefinedOperandIndex() { return 0; }
3715 virtual bool IsPurelyInformativeDefinition() { return true; }
3716
3717 protected:
3718 virtual void SetResponsibilityForRange(RangeGuaranteeDirection direction) {
3719 bounds_check()->SetResponsibilityForRange(direction);
3720 }
3721 virtual void TryGuaranteeRangeChanging(RangeEvaluationContext* context) {
3722 bounds_check()->TryGuaranteeRangeChanging(context);
3723 }
3724 };
3725
3726
3506 class HBitwiseBinaryOperation: public HBinaryOperation { 3727 class HBitwiseBinaryOperation: public HBinaryOperation {
3507 public: 3728 public:
3508 HBitwiseBinaryOperation(HValue* context, HValue* left, HValue* right) 3729 HBitwiseBinaryOperation(HValue* context, HValue* left, HValue* right)
3509 : HBinaryOperation(context, left, right) { 3730 : HBinaryOperation(context, left, right) {
3510 SetFlag(kFlexibleRepresentation); 3731 SetFlag(kFlexibleRepresentation);
3511 SetFlag(kTruncatingToInt32); 3732 SetFlag(kTruncatingToInt32);
3512 SetAllSideEffects(); 3733 SetAllSideEffects();
3513 } 3734 }
3514 3735
3515 virtual Representation RequiredInputRepresentation(int index) { 3736 virtual Representation RequiredInputRepresentation(int index) {
(...skipping 569 matching lines...) Expand 10 before | Expand all | Expand 10 after
4085 virtual bool IsCommutative() const { 4306 virtual bool IsCommutative() const {
4086 return !representation().IsTagged(); 4307 return !representation().IsTagged();
4087 } 4308 }
4088 4309
4089 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); 4310 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
4090 4311
4091 virtual HType CalculateInferredType(); 4312 virtual HType CalculateInferredType();
4092 4313
4093 virtual HValue* Canonicalize(); 4314 virtual HValue* Canonicalize();
4094 4315
4095 virtual bool IsRelationTrueInternal(NumericRelation relation, HValue* other) { 4316 virtual bool TryDecompose(DecompositionResult* decomposition) {
4096 HValue* base = NULL;
4097 int32_t offset = 0;
4098 if (left()->IsInteger32Constant()) { 4317 if (left()->IsInteger32Constant()) {
4099 base = right(); 4318 decomposition->Apply(right(), left()->GetInteger32Constant());
4100 offset = left()->GetInteger32Constant(); 4319 return true;
4101 } else if (right()->IsInteger32Constant()) { 4320 } else if (right()->IsInteger32Constant()) {
4102 base = left(); 4321 decomposition->Apply(left(), right()->GetInteger32Constant());
4103 offset = right()->GetInteger32Constant(); 4322 return true;
4104 } else { 4323 } else {
4105 return false; 4324 return false;
4106 } 4325 }
4107
4108 return relation.IsExtendable(offset)
4109 ? base->IsRelationTrue(relation, other) : false;
4110 } 4326 }
4111 4327
4112 DECLARE_CONCRETE_INSTRUCTION(Add) 4328 DECLARE_CONCRETE_INSTRUCTION(Add)
4113 4329
4114 protected: 4330 protected:
4115 virtual bool DataEquals(HValue* other) { return true; } 4331 virtual bool DataEquals(HValue* other) { return true; }
4116 4332
4117 virtual Range* InferRange(Zone* zone); 4333 virtual Range* InferRange(Zone* zone);
4118 4334
4119 private: 4335 private:
4120 HAdd(HValue* context, HValue* left, HValue* right) 4336 HAdd(HValue* context, HValue* left, HValue* right)
4121 : HArithmeticBinaryOperation(context, left, right) { 4337 : HArithmeticBinaryOperation(context, left, right) {
4122 SetFlag(kCanOverflow); 4338 SetFlag(kCanOverflow);
4123 } 4339 }
4124 }; 4340 };
4125 4341
4126 4342
4127 class HSub: public HArithmeticBinaryOperation { 4343 class HSub: public HArithmeticBinaryOperation {
4128 public: 4344 public:
4129 static HInstruction* New(Zone* zone, 4345 static HInstruction* New(Zone* zone,
4130 HValue* context, 4346 HValue* context,
4131 HValue* left, 4347 HValue* left,
4132 HValue* right); 4348 HValue* right);
4133 4349
4134 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); 4350 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
4135 4351
4136 virtual HValue* Canonicalize(); 4352 virtual HValue* Canonicalize();
4137 4353
4138 virtual bool IsRelationTrueInternal(NumericRelation relation, HValue* other) { 4354 virtual bool TryDecompose(DecompositionResult* decomposition) {
4139 if (right()->IsInteger32Constant()) { 4355 if (right()->IsInteger32Constant()) {
4140 HValue* base = left(); 4356 decomposition->Apply(left(), -right()->GetInteger32Constant());
4141 int32_t offset = right()->GetInteger32Constant(); 4357 return true;
4142 return relation.IsExtendable(-offset)
4143 ? base->IsRelationTrue(relation, other) : false;
4144 } else { 4358 } else {
4145 return false; 4359 return false;
4146 } 4360 }
4147 } 4361 }
4148 4362
4149 DECLARE_CONCRETE_INSTRUCTION(Sub) 4363 DECLARE_CONCRETE_INSTRUCTION(Sub)
4150 4364
4151 protected: 4365 protected:
4152 virtual bool DataEquals(HValue* other) { return true; } 4366 virtual bool DataEquals(HValue* other) { return true; }
4153 4367
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after
4368 }; 4582 };
4369 4583
4370 4584
4371 class HShr: public HBitwiseBinaryOperation { 4585 class HShr: public HBitwiseBinaryOperation {
4372 public: 4586 public:
4373 static HInstruction* New(Zone* zone, 4587 static HInstruction* New(Zone* zone,
4374 HValue* context, 4588 HValue* context,
4375 HValue* left, 4589 HValue* left,
4376 HValue* right); 4590 HValue* right);
4377 4591
4592 virtual bool TryDecompose(DecompositionResult* decomposition) {
4593 if (right()->IsInteger32Constant()) {
4594 if (decomposition->Apply(left(), 0, right()->GetInteger32Constant())) {
4595 // This is intended to look for HAdd and HSub, to handle compounds
4596 // like ((base + offset) >> scale) with one single decomposition.
4597 left()->TryDecompose(decomposition);
4598 return true;
4599 }
4600 }
4601 return false;
4602 }
4603
4378 virtual Range* InferRange(Zone* zone); 4604 virtual Range* InferRange(Zone* zone);
4379 4605
4380 DECLARE_CONCRETE_INSTRUCTION(Shr) 4606 DECLARE_CONCRETE_INSTRUCTION(Shr)
4381 4607
4382 protected: 4608 protected:
4383 virtual bool DataEquals(HValue* other) { return true; } 4609 virtual bool DataEquals(HValue* other) { return true; }
4384 4610
4385 private: 4611 private:
4386 HShr(HValue* context, HValue* left, HValue* right) 4612 HShr(HValue* context, HValue* left, HValue* right)
4387 : HBitwiseBinaryOperation(context, left, right) { } 4613 : HBitwiseBinaryOperation(context, left, right) { }
4388 }; 4614 };
4389 4615
4390 4616
4391 class HSar: public HBitwiseBinaryOperation { 4617 class HSar: public HBitwiseBinaryOperation {
4392 public: 4618 public:
4393 static HInstruction* New(Zone* zone, 4619 static HInstruction* New(Zone* zone,
4394 HValue* context, 4620 HValue* context,
4395 HValue* left, 4621 HValue* left,
4396 HValue* right); 4622 HValue* right);
4397 4623
4624 virtual bool TryDecompose(DecompositionResult* decomposition) {
4625 if (right()->IsInteger32Constant()) {
4626 if (decomposition->Apply(left(), 0, right()->GetInteger32Constant())) {
4627 // This is intended to look for HAdd and HSub, to handle compounds
4628 // like ((base + offset) >> scale) with one single decomposition.
4629 left()->TryDecompose(decomposition);
4630 return true;
4631 }
4632 }
4633 return false;
4634 }
4635
4398 virtual Range* InferRange(Zone* zone); 4636 virtual Range* InferRange(Zone* zone);
4399 4637
4400 DECLARE_CONCRETE_INSTRUCTION(Sar) 4638 DECLARE_CONCRETE_INSTRUCTION(Sar)
4401 4639
4402 protected: 4640 protected:
4403 virtual bool DataEquals(HValue* other) { return true; } 4641 virtual bool DataEquals(HValue* other) { return true; }
4404 4642
4405 private: 4643 private:
4406 HSar(HValue* context, HValue* left, HValue* right) 4644 HSar(HValue* context, HValue* left, HValue* right)
4407 : HBitwiseBinaryOperation(context, left, right) { } 4645 : HBitwiseBinaryOperation(context, left, right) { }
(...skipping 1814 matching lines...) Expand 10 before | Expand all | Expand 10 after
6222 virtual bool IsDeletable() const { return true; } 6460 virtual bool IsDeletable() const { return true; }
6223 }; 6461 };
6224 6462
6225 6463
6226 #undef DECLARE_INSTRUCTION 6464 #undef DECLARE_INSTRUCTION
6227 #undef DECLARE_CONCRETE_INSTRUCTION 6465 #undef DECLARE_CONCRETE_INSTRUCTION
6228 6466
6229 } } // namespace v8::internal 6467 } } // namespace v8::internal
6230 6468
6231 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ 6469 #endif // V8_HYDROGEN_INSTRUCTIONS_H_
OLDNEW
« no previous file with comments | « src/hydrogen.cc ('k') | src/hydrogen-instructions.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698