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

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: Addressed review comments. 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 // CompoundImplies returns true when
671 // "((x + my_offset) >> my_scale) rel y" implies
672 // "((x + other_offset) >> other_scale) other_relation y".
673 bool CompoundImplies(NumericRelation other_relation,
674 int my_offset,
675 int my_scale,
676 int other_offset = 0,
677 int other_scale = 0) {
678 return Implies(other_relation) && ComponentsImply(
679 my_offset, my_scale, other_offset, other_scale);
680 }
681
669 private: 682 private:
683 // ComponentsImply returns true when
684 // "((x + my_offset) >> my_scale) rel y" implies
685 // "((x + other_offset) >> other_scale) rel y".
686 bool ComponentsImply(int my_offset,
687 int my_scale,
688 int other_offset,
689 int other_scale) {
690 switch (kind_) {
691 case NONE: break; // Fall through to UNREACHABLE().
692 case EQ:
693 case NE: return my_offset == other_offset && my_scale == other_scale;
694 case GT:
695 case GE: return my_offset <= other_offset && my_scale >= other_scale;
696 case LT:
697 case LE: return my_offset >= other_offset && my_scale <= other_scale;
698 }
699 UNREACHABLE();
700 return false;
701 }
702
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
709 class DecompositionResult BASE_EMBEDDED {
710 public:
711 DecompositionResult() : base_(NULL), offset_(0), scale_(0) {}
712
713 HValue* base() { return base_; }
714 int offset() { return offset_; }
715 int scale() { return scale_; }
716
717 bool Apply(HValue* b, int o, int s = 0) {
Jakob Kummerow 2013/03/14 16:16:32 nit: please spell out the names ("base", "offset",
718 if (base() == NULL) {
Jakob Kummerow 2013/03/14 16:16:32 nit: s/base()/base_/ [for consistency with "base_
719 base_ = b;
720 offset_ = o;
721 scale_ = s;
722 return true;
723 } else {
724 if (scale_ == 0) {
725 base_ = b;
726 offset_ += o;
727 scale_ = s;
728 return true;
729 } else {
730 return false;
731 }
732 }
733 }
734
735 void SwapValues(HValue** b, int* o, int* s) {
Jakob Kummerow 2013/03/14 16:16:32 again
736 swap(&base_, b);
737 swap(&offset_, o);
738 swap(&scale_, s);
739 }
740
741 private:
742 template <class T> void swap(T* a, T* b) {
743 T c(*a);
744 *a = *b;
745 *b = c;
746 }
747
748 HValue* base_;
749 int offset_;
750 int scale_;
751 };
752
753
754 class RangeEvaluationContext BASE_EMBEDDED {
755 public:
756 RangeEvaluationContext(HValue* value, HValue* upper);
757
758 HValue* lower_bound() { return lower_bound_; }
759 HValue* lower_bound_guarantee() { return lower_bound_guarantee_; }
760 HValue* candidate() { return candidate_; }
761 HValue* upper_bound() { return upper_bound_; }
762 HValue* upper_bound_guarantee() { return upper_bound_guarantee_; }
763 int offset() { return offset_; }
764 int scale() { return scale_; }
765
766 bool is_range_satisfied() {
767 return lower_bound_guarantee() != NULL && upper_bound_guarantee() != NULL;
768 }
769
770 void set_lower_bound_guarantee(HValue* guarantee) {
771 lower_bound_guarantee_ = ConvertGuarantee(guarantee);
772 }
773 void set_upper_bound_guarantee(HValue* guarantee) {
774 upper_bound_guarantee_ = ConvertGuarantee(guarantee);
775 }
776
777 void swap_candidate(DecompositionResult* other_candicate) {
778 other_candicate->SwapValues(&candidate_, &offset_, &scale_);
779 }
780
781 private:
782 HValue* ConvertGuarantee(HValue* guarantee);
783
784 HValue* lower_bound_;
785 HValue* lower_bound_guarantee_;
786 HValue* candidate_;
787 HValue* upper_bound_;
788 HValue* upper_bound_guarantee_;
789 int offset_;
790 int scale_;
791 };
792
793
676 typedef EnumSet<GVNFlag> GVNFlagSet; 794 typedef EnumSet<GVNFlag> GVNFlagSet;
677 795
678 796
679 class HValue: public ZoneObject { 797 class HValue: public ZoneObject {
680 public: 798 public:
681 static const int kNoNumber = -1; 799 static const int kNoNumber = -1;
682 800
683 enum Flag { 801 enum Flag {
684 kFlexibleRepresentation, 802 kFlexibleRepresentation,
685 // Participate in Global Value Numbering, i.e. elimination of 803 // Participate in Global Value Numbering, i.e. elimination of
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after
966 } 1084 }
967 1085
968 bool IsDead() const { 1086 bool IsDead() const {
969 return HasNoUses() && !HasObservableSideEffects() && IsDeletable(); 1087 return HasNoUses() && !HasObservableSideEffects() && IsDeletable();
970 } 1088 }
971 1089
972 #ifdef DEBUG 1090 #ifdef DEBUG
973 virtual void Verify() = 0; 1091 virtual void Verify() = 0;
974 #endif 1092 #endif
975 1093
976 // This method is recursive but it is guaranteed to terminate because 1094 bool IsRelationTrue(NumericRelation relation,
977 // RedefinedOperand() always dominates "this". 1095 HValue* other,
978 bool IsRelationTrue(NumericRelation relation, HValue* other) { 1096 int offset = 0,
979 if (this == other) { 1097 int scale = 0);
980 return NumericRelation::Eq().Implies(relation); 1098
1099 bool TryGuaranteeRange(HValue* upper_bound);
1100 virtual bool TryDecompose(DecompositionResult* decomposition) {
1101 if (RedefinedOperand() != NULL) {
1102 return RedefinedOperand()->TryDecompose(decomposition);
1103 } else {
1104 return false;
981 } 1105 }
982
983 bool result = IsRelationTrueInternal(relation, other) ||
984 other->IsRelationTrueInternal(relation.Reversed(), this);
985 if (!result) {
986 HValue* redefined = RedefinedOperand();
987 if (redefined != NULL) {
988 result = redefined->IsRelationTrue(relation, other);
989 }
990 }
991 return result;
992 } 1106 }
993 1107
994 protected: 1108 protected:
1109 void TryGuaranteeRangeRecursive(RangeEvaluationContext* context);
1110
1111 enum RangeGuaranteeDirection {
1112 DIRECTION_NONE = 0,
1113 DIRECTION_UPPER = 1,
1114 DIRECTION_LOWER = 2,
1115 DIRECTION_BOTH = DIRECTION_UPPER|DIRECTION_LOWER
Jakob Kummerow 2013/03/14 16:16:32 nit: spaces around '|'
1116 };
1117 virtual void SetResponsibilityForRange(RangeGuaranteeDirection direction) {}
1118 virtual void TryGuaranteeRangeChanging(RangeEvaluationContext* context) {}
1119
995 // This function must be overridden for instructions with flag kUseGVN, to 1120 // This function must be overridden for instructions with flag kUseGVN, to
996 // compare the non-Operand parts of the instruction. 1121 // compare the non-Operand parts of the instruction.
997 virtual bool DataEquals(HValue* other) { 1122 virtual bool DataEquals(HValue* other) {
998 UNREACHABLE(); 1123 UNREACHABLE();
999 return false; 1124 return false;
1000 } 1125 }
1001 1126
1002 virtual Representation RepresentationFromInputs() { 1127 virtual Representation RepresentationFromInputs() {
1003 return representation(); 1128 return representation();
1004 } 1129 }
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1048 HValue* use = uses.value(); 1173 HValue* use = uses.value();
1049 if (TestDominance(this, use)) { 1174 if (TestDominance(this, use)) {
1050 use->SetOperandAt(uses.index(), this); 1175 use->SetOperandAt(uses.index(), this);
1051 } 1176 }
1052 } 1177 }
1053 } 1178 }
1054 } 1179 }
1055 1180
1056 // Informative definitions can override this method to state any numeric 1181 // Informative definitions can override this method to state any numeric
1057 // relation they provide on the redefined value. 1182 // relation they provide on the redefined value.
1058 virtual bool IsRelationTrueInternal(NumericRelation relation, HValue* other) { 1183 // Returns true if it is guaranteed that:
1184 // ((this + offset) >> scale) relation other
1185 virtual bool IsRelationTrueInternal(NumericRelation relation,
1186 HValue* other,
1187 int offset = 0,
1188 int scale = 0) {
1059 return false; 1189 return false;
1060 } 1190 }
1061 1191
1062 static GVNFlagSet AllDependsOnFlagSet() { 1192 static GVNFlagSet AllDependsOnFlagSet() {
1063 GVNFlagSet result; 1193 GVNFlagSet result;
1064 // Create changes mask. 1194 // Create changes mask.
1065 #define ADD_FLAG(type) result.Add(kDependsOn##type); 1195 #define ADD_FLAG(type) result.Add(kDependsOn##type);
1066 GVN_TRACKED_FLAG_LIST(ADD_FLAG) 1196 GVN_TRACKED_FLAG_LIST(ADD_FLAG)
1067 GVN_UNTRACKED_FLAG_LIST(ADD_FLAG) 1197 GVN_UNTRACKED_FLAG_LIST(ADD_FLAG)
1068 #undef ADD_FLAG 1198 #undef ADD_FLAG
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after
1297 virtual int RedefinedOperandIndex() { return 0; } 1427 virtual int RedefinedOperandIndex() { return 0; }
1298 virtual bool IsPurelyInformativeDefinition() { return true; } 1428 virtual bool IsPurelyInformativeDefinition() { return true; }
1299 1429
1300 virtual Representation RequiredInputRepresentation(int index) { 1430 virtual Representation RequiredInputRepresentation(int index) {
1301 return representation(); 1431 return representation();
1302 } 1432 }
1303 1433
1304 virtual void PrintDataTo(StringStream* stream); 1434 virtual void PrintDataTo(StringStream* stream);
1305 1435
1306 virtual bool IsRelationTrueInternal(NumericRelation other_relation, 1436 virtual bool IsRelationTrueInternal(NumericRelation other_relation,
1307 HValue* other_related_value) { 1437 HValue* other_related_value,
1438 int offset = 0,
1439 int scale = 0) {
1308 if (related_value() == other_related_value) { 1440 if (related_value() == other_related_value) {
1309 return relation().Implies(other_relation); 1441 return relation().CompoundImplies(other_relation, offset, scale);
1310 } else { 1442 } else {
1311 return false; 1443 return false;
1312 } 1444 }
1313 } 1445 }
1314 1446
1315 DECLARE_CONCRETE_INSTRUCTION(NumericConstraint) 1447 DECLARE_CONCRETE_INSTRUCTION(NumericConstraint)
1316 1448
1317 private: 1449 private:
1318 HNumericConstraint(HValue* constrained_value, 1450 HNumericConstraint(HValue* constrained_value,
1319 NumericRelation relation, 1451 NumericRelation relation,
1320 HValue* related_value) 1452 HValue* related_value)
1321 : relation_(relation) { 1453 : relation_(relation) {
1322 SetOperandAt(0, constrained_value); 1454 SetOperandAt(0, constrained_value);
1323 SetOperandAt(1, related_value); 1455 SetOperandAt(1, related_value);
1324 set_representation(constrained_value->representation());
1325 } 1456 }
1326 1457
1327 NumericRelation relation_; 1458 NumericRelation relation_;
1328 }; 1459 };
1329 1460
1330 1461
1331 // We insert soft-deoptimize when we hit code with unknown typefeedback, 1462 // We insert soft-deoptimize when we hit code with unknown typefeedback,
1332 // so that we get a chance of re-optimizing with useful typefeedback. 1463 // so that we get a chance of re-optimizing with useful typefeedback.
1333 // HSoftDeoptimize does not end a basic block as opposed to HDeoptimize. 1464 // HSoftDeoptimize does not end a basic block as opposed to HDeoptimize.
1334 class HSoftDeoptimize: public HTemplateInstruction<0> { 1465 class HSoftDeoptimize: public HTemplateInstruction<0> {
(...skipping 1617 matching lines...) Expand 10 before | Expand all | Expand 10 after
2952 } 3083 }
2953 return true; 3084 return true;
2954 } 3085 }
2955 3086
2956 protected: 3087 protected:
2957 virtual void DeleteFromGraph(); 3088 virtual void DeleteFromGraph();
2958 virtual void InternalSetOperandAt(int index, HValue* value) { 3089 virtual void InternalSetOperandAt(int index, HValue* value) {
2959 inputs_[index] = value; 3090 inputs_[index] = value;
2960 } 3091 }
2961 3092
2962 virtual bool IsRelationTrueInternal(NumericRelation relation, HValue* other); 3093 virtual bool IsRelationTrueInternal(NumericRelation relation,
3094 HValue* other,
3095 int offset = 0,
3096 int scale = 0);
2963 3097
2964 private: 3098 private:
2965 ZoneList<HValue*> inputs_; 3099 ZoneList<HValue*> inputs_;
2966 int merged_index_; 3100 int merged_index_;
2967 3101
2968 int non_phi_uses_[Representation::kNumRepresentations]; 3102 int non_phi_uses_[Representation::kNumRepresentations];
2969 int indirect_uses_[Representation::kNumRepresentations]; 3103 int indirect_uses_[Representation::kNumRepresentations];
2970 int phi_id_; 3104 int phi_id_;
2971 bool is_live_; 3105 bool is_live_;
2972 bool is_convertible_to_integer_; 3106 bool is_convertible_to_integer_;
(...skipping 11 matching lines...) Expand all
2984 3118
2985 virtual int RedefinedOperandIndex() { return 0; } 3119 virtual int RedefinedOperandIndex() { return 0; }
2986 virtual bool IsPurelyInformativeDefinition() { return true; } 3120 virtual bool IsPurelyInformativeDefinition() { return true; }
2987 virtual Representation RequiredInputRepresentation(int index) { 3121 virtual Representation RequiredInputRepresentation(int index) {
2988 return representation(); 3122 return representation();
2989 } 3123 }
2990 3124
2991 virtual void PrintDataTo(StringStream* stream); 3125 virtual void PrintDataTo(StringStream* stream);
2992 3126
2993 virtual bool IsRelationTrueInternal(NumericRelation other_relation, 3127 virtual bool IsRelationTrueInternal(NumericRelation other_relation,
2994 HValue* other_related_value) { 3128 HValue* other_related_value,
3129 int offset = 0,
3130 int scale = 0) {
2995 if (induction_base() == other_related_value) { 3131 if (induction_base() == other_related_value) {
2996 return relation().Implies(other_relation); 3132 return relation().CompoundImplies(other_relation, offset, scale);
2997 } else { 3133 } else {
2998 return false; 3134 return false;
2999 } 3135 }
3000 } 3136 }
3001 3137
3002 DECLARE_CONCRETE_INSTRUCTION(InductionVariableAnnotation) 3138 DECLARE_CONCRETE_INSTRUCTION(InductionVariableAnnotation)
3003 3139
3004 private: 3140 private:
3005 HInductionVariableAnnotation(HPhi* phi, 3141 HInductionVariableAnnotation(HPhi* phi,
3006 NumericRelation relation, 3142 NumericRelation relation,
3007 int operand_index) 3143 int operand_index)
3008 : HUnaryOperation(phi), 3144 : HUnaryOperation(phi),
3009 phi_(phi), relation_(relation), operand_index_(operand_index) { 3145 phi_(phi), relation_(relation), operand_index_(operand_index) {
3010 set_representation(phi->representation());
3011 } 3146 }
3012 3147
3013 // We need to store the phi both here and in the instruction operand because 3148 // We need to store the phi both here and in the instruction operand because
3014 // the operand can change if a new idef of the phi is added between the phi 3149 // the operand can change if a new idef of the phi is added between the phi
3015 // and this instruction (inserting an idef updates every use). 3150 // and this instruction (inserting an idef updates every use).
3016 HPhi* phi_; 3151 HPhi* phi_;
3017 NumericRelation relation_; 3152 NumericRelation relation_;
3018 int operand_index_; 3153 int operand_index_;
3019 }; 3154 };
3020 3155
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after
3375 virtual bool DataEquals(HValue* other) { return true; } 3510 virtual bool DataEquals(HValue* other) { return true; }
3376 }; 3511 };
3377 3512
3378 3513
3379 enum BoundsCheckKeyMode { 3514 enum BoundsCheckKeyMode {
3380 DONT_ALLOW_SMI_KEY, 3515 DONT_ALLOW_SMI_KEY,
3381 ALLOW_SMI_KEY 3516 ALLOW_SMI_KEY
3382 }; 3517 };
3383 3518
3384 3519
3520 class HBoundsCheckBaseIndexInformation;
3521
3522
3385 class HBoundsCheck: public HTemplateInstruction<2> { 3523 class HBoundsCheck: public HTemplateInstruction<2> {
3386 public: 3524 public:
3387 // Normally HBoundsCheck should be created using the 3525 // Normally HBoundsCheck should be created using the
3388 // HGraphBuilder::AddBoundsCheck() helper, which also guards the index with 3526 // HGraphBuilder::AddBoundsCheck() helper, which also guards the index with
3389 // a HCheckSmiOrInt32 check. 3527 // a HCheckSmiOrInt32 check.
3390 // However when building stubs, where we know that the arguments are Int32, 3528 // However when building stubs, where we know that the arguments are Int32,
3391 // it makes sense to invoke this constructor directly. 3529 // it makes sense to invoke this constructor directly.
3392 HBoundsCheck(HValue* index, 3530 HBoundsCheck(HValue* index,
3393 HValue* length, 3531 HValue* length,
3394 BoundsCheckKeyMode key_mode = DONT_ALLOW_SMI_KEY, 3532 BoundsCheckKeyMode key_mode = DONT_ALLOW_SMI_KEY,
3395 Representation r = Representation::None()) 3533 Representation r = Representation::None())
3396 : key_mode_(key_mode), skip_check_(false) { 3534 : key_mode_(key_mode), skip_check_(false),
3535 base_(NULL), offset_(0), scale_(0),
3536 responsibility_direction_(DIRECTION_NONE) {
3397 SetOperandAt(0, index); 3537 SetOperandAt(0, index);
3398 SetOperandAt(1, length); 3538 SetOperandAt(1, length);
3399 if (r.IsNone()) { 3539 if (r.IsNone()) {
3400 // In the normal compilation pipeline the representation is flexible 3540 // In the normal compilation pipeline the representation is flexible
3401 // (see InferRepresentation). 3541 // (see InferRepresentation).
3402 SetFlag(kFlexibleRepresentation); 3542 SetFlag(kFlexibleRepresentation);
3403 } else { 3543 } else {
3404 // When compiling stubs we want to set the representation explicitly 3544 // When compiling stubs we want to set the representation explicitly
3405 // so the compilation pipeline can skip the HInferRepresentation phase. 3545 // so the compilation pipeline can skip the HInferRepresentation phase.
3406 set_representation(r); 3546 set_representation(r);
3407 } 3547 }
3408 SetFlag(kUseGVN); 3548 SetFlag(kUseGVN);
3409 } 3549 }
3410 3550
3411 bool skip_check() { return skip_check_; } 3551 bool skip_check() { return skip_check_; }
3412 void set_skip_check(bool skip_check) { skip_check_ = skip_check; } 3552 void set_skip_check(bool skip_check) { skip_check_ = skip_check; }
3553 HValue* base() { return base_; }
3554 int offset() { return offset_; }
3555 int scale() { return scale_; }
3556 bool index_can_increase() {
3557 return (responsibility_direction_ & DIRECTION_LOWER) == 0;
3558 }
3559 bool index_can_decrease() {
3560 return (responsibility_direction_ & DIRECTION_UPPER) == 0;
3561 }
3562
3563 void ApplyIndexChange();
3564 bool DetectCompoundIndex() {
3565 ASSERT(base() == NULL);
3566
3567 DecompositionResult decomposition;
3568 if (index()->TryDecompose(&decomposition)) {
3569 base_ = decomposition.base();
3570 offset_ = decomposition.offset();
3571 scale_ = decomposition.scale();
3572 return true;
3573 } else {
3574 base_ = index();
3575 offset_ = 0;
3576 scale_ = 0;
3577 return false;
3578 }
3579 }
3413 3580
3414 virtual Representation RequiredInputRepresentation(int arg_index) { 3581 virtual Representation RequiredInputRepresentation(int arg_index) {
3415 return representation(); 3582 return representation();
3416 } 3583 }
3417 virtual Representation observed_input_representation(int index) { 3584 virtual Representation observed_input_representation(int index) {
3418 return Representation::Integer32(); 3585 return Representation::Integer32();
3419 } 3586 }
3420 3587
3421 virtual bool IsRelationTrueInternal(NumericRelation relation, 3588 virtual bool IsRelationTrueInternal(NumericRelation relation,
3422 HValue* related_value); 3589 HValue* related_value,
3590 int offset = 0,
3591 int scale = 0);
3423 3592
3424 virtual void PrintDataTo(StringStream* stream); 3593 virtual void PrintDataTo(StringStream* stream);
3425 virtual void InferRepresentation(HInferRepresentation* h_infer); 3594 virtual void InferRepresentation(HInferRepresentation* h_infer);
3426 3595
3427 HValue* index() { return OperandAt(0); } 3596 HValue* index() { return OperandAt(0); }
3428 HValue* length() { return OperandAt(1); } 3597 HValue* length() { return OperandAt(1); }
3429 3598
3430 virtual int RedefinedOperandIndex() { return 0; } 3599 virtual int RedefinedOperandIndex() { return 0; }
3431 virtual bool IsPurelyInformativeDefinition() { return skip_check(); } 3600 virtual bool IsPurelyInformativeDefinition() { return skip_check(); }
3432 virtual void AddInformativeDefinitions(); 3601 virtual void AddInformativeDefinitions();
3433 3602
3434 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck) 3603 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck)
3435 3604
3436 protected: 3605 protected:
3606 friend class HBoundsCheckBaseIndexInformation;
3607
3608 virtual void SetResponsibilityForRange(RangeGuaranteeDirection direction) {
3609 responsibility_direction_ = static_cast<RangeGuaranteeDirection>(
3610 responsibility_direction_ | direction);
3611 }
3612
3437 virtual bool DataEquals(HValue* other) { return true; } 3613 virtual bool DataEquals(HValue* other) { return true; }
3614 virtual void TryGuaranteeRangeChanging(RangeEvaluationContext* context);
3438 BoundsCheckKeyMode key_mode_; 3615 BoundsCheckKeyMode key_mode_;
3439 bool skip_check_; 3616 bool skip_check_;
3617 HValue* base_;
3618 int offset_;
3619 int scale_;
3620 RangeGuaranteeDirection responsibility_direction_;
3440 }; 3621 };
3441 3622
3442 3623
3624 class HBoundsCheckBaseIndexInformation: public HTemplateInstruction<2> {
3625 public:
3626 explicit HBoundsCheckBaseIndexInformation(HBoundsCheck* check) {
3627 DecompositionResult decomposition;
3628 if (check->index()->TryDecompose(&decomposition)) {
3629 SetOperandAt(0, decomposition.base());
3630 SetOperandAt(1, check);
3631 } else {
3632 UNREACHABLE();
3633 }
3634 }
3635
3636 HValue* base_index() { return OperandAt(0); }
3637 HBoundsCheck* bounds_check() { return HBoundsCheck::cast(OperandAt(1)); }
3638
3639 DECLARE_CONCRETE_INSTRUCTION(BoundsCheckBaseIndexInformation)
3640
3641 virtual Representation RequiredInputRepresentation(int arg_index) {
3642 return representation();
3643 }
3644
3645 virtual bool IsRelationTrueInternal(NumericRelation relation,
3646 HValue* related_value,
3647 int offset = 0,
3648 int scale = 0);
3649 virtual void PrintDataTo(StringStream* stream);
3650
3651 virtual int RedefinedOperandIndex() { return 0; }
3652 virtual bool IsPurelyInformativeDefinition() { return true; }
3653
3654 protected:
3655 virtual void SetResponsibilityForRange(RangeGuaranteeDirection direction) {
3656 bounds_check()->SetResponsibilityForRange(direction);
3657 }
3658 virtual void TryGuaranteeRangeChanging(RangeEvaluationContext* context) {
3659 bounds_check()->TryGuaranteeRangeChanging(context);
3660 }
3661 };
3662
3663
3443 class HBitwiseBinaryOperation: public HBinaryOperation { 3664 class HBitwiseBinaryOperation: public HBinaryOperation {
3444 public: 3665 public:
3445 HBitwiseBinaryOperation(HValue* context, HValue* left, HValue* right) 3666 HBitwiseBinaryOperation(HValue* context, HValue* left, HValue* right)
3446 : HBinaryOperation(context, left, right) { 3667 : HBinaryOperation(context, left, right) {
3447 SetFlag(kFlexibleRepresentation); 3668 SetFlag(kFlexibleRepresentation);
3448 SetFlag(kTruncatingToInt32); 3669 SetFlag(kTruncatingToInt32);
3449 SetAllSideEffects(); 3670 SetAllSideEffects();
3450 } 3671 }
3451 3672
3452 virtual Representation RequiredInputRepresentation(int index) { 3673 virtual Representation RequiredInputRepresentation(int index) {
(...skipping 552 matching lines...) Expand 10 before | Expand all | Expand 10 after
4005 4226
4006 static HInstruction* NewHAdd(Zone* zone, 4227 static HInstruction* NewHAdd(Zone* zone,
4007 HValue* context, 4228 HValue* context,
4008 HValue* left, 4229 HValue* left,
4009 HValue* right); 4230 HValue* right);
4010 4231
4011 virtual HType CalculateInferredType(); 4232 virtual HType CalculateInferredType();
4012 4233
4013 virtual HValue* Canonicalize(); 4234 virtual HValue* Canonicalize();
4014 4235
4015 virtual bool IsRelationTrueInternal(NumericRelation relation, HValue* other) { 4236 virtual bool TryDecompose(DecompositionResult* decomposition) {
4016 HValue* base = NULL;
4017 int32_t offset = 0;
4018 if (left()->IsInteger32Constant()) { 4237 if (left()->IsInteger32Constant()) {
4019 base = right(); 4238 decomposition->Apply(right(), left()->GetInteger32Constant());
4020 offset = left()->GetInteger32Constant(); 4239 return true;
4021 } else if (right()->IsInteger32Constant()) { 4240 } else if (right()->IsInteger32Constant()) {
4022 base = left(); 4241 decomposition->Apply(left(), right()->GetInteger32Constant());
4023 offset = right()->GetInteger32Constant(); 4242 return true;
4024 } else { 4243 } else {
4025 return false; 4244 return false;
4026 } 4245 }
4027
4028 return relation.IsExtendable(offset)
4029 ? base->IsRelationTrue(relation, other) : false;
4030 } 4246 }
4031 4247
4032 DECLARE_CONCRETE_INSTRUCTION(Add) 4248 DECLARE_CONCRETE_INSTRUCTION(Add)
4033 4249
4034 protected: 4250 protected:
4035 virtual bool DataEquals(HValue* other) { return true; } 4251 virtual bool DataEquals(HValue* other) { return true; }
4036 4252
4037 virtual Range* InferRange(Zone* zone); 4253 virtual Range* InferRange(Zone* zone);
4038 }; 4254 };
4039 4255
4040 4256
4041 class HSub: public HArithmeticBinaryOperation { 4257 class HSub: public HArithmeticBinaryOperation {
4042 public: 4258 public:
4043 HSub(HValue* context, HValue* left, HValue* right) 4259 HSub(HValue* context, HValue* left, HValue* right)
4044 : HArithmeticBinaryOperation(context, left, right) { 4260 : HArithmeticBinaryOperation(context, left, right) {
4045 SetFlag(kCanOverflow); 4261 SetFlag(kCanOverflow);
4046 } 4262 }
4047 4263
4048 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); 4264 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
4049 4265
4050 virtual HValue* Canonicalize(); 4266 virtual HValue* Canonicalize();
4051 4267
4052 static HInstruction* NewHSub(Zone* zone, 4268 static HInstruction* NewHSub(Zone* zone,
4053 HValue* context, 4269 HValue* context,
4054 HValue* left, 4270 HValue* left,
4055 HValue* right); 4271 HValue* right);
4056 4272
4057 virtual bool IsRelationTrueInternal(NumericRelation relation, HValue* other) { 4273 virtual bool TryDecompose(DecompositionResult* decomposition) {
4058 if (right()->IsInteger32Constant()) { 4274 if (right()->IsInteger32Constant()) {
4059 HValue* base = left(); 4275 decomposition->Apply(left(), -right()->GetInteger32Constant());
4060 int32_t offset = right()->GetInteger32Constant(); 4276 return true;
4061 return relation.IsExtendable(-offset)
4062 ? base->IsRelationTrue(relation, other) : false;
4063 } else { 4277 } else {
4064 return false; 4278 return false;
4065 } 4279 }
4066 } 4280 }
4067 4281
4068 DECLARE_CONCRETE_INSTRUCTION(Sub) 4282 DECLARE_CONCRETE_INSTRUCTION(Sub)
4069 4283
4070 protected: 4284 protected:
4071 virtual bool DataEquals(HValue* other) { return true; } 4285 virtual bool DataEquals(HValue* other) { return true; }
4072 4286
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
4292 }; 4506 };
4293 4507
4294 4508
4295 class HSar: public HBitwiseBinaryOperation { 4509 class HSar: public HBitwiseBinaryOperation {
4296 public: 4510 public:
4297 HSar(HValue* context, HValue* left, HValue* right) 4511 HSar(HValue* context, HValue* left, HValue* right)
4298 : HBitwiseBinaryOperation(context, left, right) { } 4512 : HBitwiseBinaryOperation(context, left, right) { }
4299 4513
4300 virtual Range* InferRange(Zone* zone); 4514 virtual Range* InferRange(Zone* zone);
4301 4515
4516 virtual bool TryDecompose(DecompositionResult* decomposition) {
Jakob Kummerow 2013/03/14 16:16:32 Shouldn't we make the same change to HShr too?
4517 if (right()->IsInteger32Constant()) {
4518 if (decomposition->Apply(left(), 0, right()->GetInteger32Constant())) {
4519 // This is intended to look for HAdd and HSub, to handle compounds
4520 // like ((base = offset) >> scale) with one single decomposition.
Jakob Kummerow 2013/03/14 16:16:32 nit: s/=/+/
4521 left()->TryDecompose(decomposition);
4522 return true;
4523 }
4524 }
4525 return false;
4526 }
4527
4302 static HInstruction* NewHSar(Zone* zone, 4528 static HInstruction* NewHSar(Zone* zone,
4303 HValue* context, 4529 HValue* context,
4304 HValue* left, 4530 HValue* left,
4305 HValue* right); 4531 HValue* right);
4306 4532
4307 DECLARE_CONCRETE_INSTRUCTION(Sar) 4533 DECLARE_CONCRETE_INSTRUCTION(Sar)
4308 4534
4309 protected: 4535 protected:
4310 virtual bool DataEquals(HValue* other) { return true; } 4536 virtual bool DataEquals(HValue* other) { return true; }
4311 }; 4537 };
(...skipping 1772 matching lines...) Expand 10 before | Expand all | Expand 10 after
6084 virtual bool IsDeletable() const { return true; } 6310 virtual bool IsDeletable() const { return true; }
6085 }; 6311 };
6086 6312
6087 6313
6088 #undef DECLARE_INSTRUCTION 6314 #undef DECLARE_INSTRUCTION
6089 #undef DECLARE_CONCRETE_INSTRUCTION 6315 #undef DECLARE_CONCRETE_INSTRUCTION
6090 6316
6091 } } // namespace v8::internal 6317 } } // namespace v8::internal
6092 6318
6093 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ 6319 #endif // V8_HYDROGEN_INSTRUCTIONS_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698