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

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

Issue 12226112: Infrastructure classes for evaluating numeric relations between values. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed last comments. Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« 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 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
140 V(LoadKeyed) \ 140 V(LoadKeyed) \
141 V(LoadKeyedGeneric) \ 141 V(LoadKeyedGeneric) \
142 V(LoadNamedField) \ 142 V(LoadNamedField) \
143 V(LoadNamedFieldPolymorphic) \ 143 V(LoadNamedFieldPolymorphic) \
144 V(LoadNamedGeneric) \ 144 V(LoadNamedGeneric) \
145 V(MapEnumLength) \ 145 V(MapEnumLength) \
146 V(MathFloorOfDiv) \ 146 V(MathFloorOfDiv) \
147 V(MathMinMax) \ 147 V(MathMinMax) \
148 V(Mod) \ 148 V(Mod) \
149 V(Mul) \ 149 V(Mul) \
150 V(NumericConstraint) \
150 V(ObjectLiteral) \ 151 V(ObjectLiteral) \
151 V(OsrEntry) \ 152 V(OsrEntry) \
152 V(OuterContext) \ 153 V(OuterContext) \
153 V(Parameter) \ 154 V(Parameter) \
154 V(Power) \ 155 V(Power) \
155 V(PushArgument) \ 156 V(PushArgument) \
156 V(Random) \ 157 V(Random) \
157 V(RegExpLiteral) \ 158 V(RegExpLiteral) \
158 V(Return) \ 159 V(Return) \
159 V(Ror) \ 160 V(Ror) \
(...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after
543 GVN_TRACKED_FLAG_LIST(DECLARE_FLAG) 544 GVN_TRACKED_FLAG_LIST(DECLARE_FLAG)
544 GVN_UNTRACKED_FLAG_LIST(DECLARE_FLAG) 545 GVN_UNTRACKED_FLAG_LIST(DECLARE_FLAG)
545 #undef DECLARE_FLAG 546 #undef DECLARE_FLAG
546 kAfterLastFlag, 547 kAfterLastFlag,
547 kLastFlag = kAfterLastFlag - 1, 548 kLastFlag = kAfterLastFlag - 1,
548 #define COUNT_FLAG(type) + 1 549 #define COUNT_FLAG(type) + 1
549 kNumberOfTrackedSideEffects = 0 GVN_TRACKED_FLAG_LIST(COUNT_FLAG) 550 kNumberOfTrackedSideEffects = 0 GVN_TRACKED_FLAG_LIST(COUNT_FLAG)
550 #undef COUNT_FLAG 551 #undef COUNT_FLAG
551 }; 552 };
552 553
554
555 class NumericRelation {
556 public:
557 enum Kind { NONE, EQ, GT, GE, LT, LE, NE };
558 static const char* MnemonicFromKind(Kind kind) {
559 switch (kind) {
560 case NONE: return "NONE";
561 case EQ: return "EQ";
562 case GT: return "GT";
563 case GE: return "GE";
564 case LT: return "LT";
565 case LE: return "LE";
566 case NE: return "NE";
567 }
568 UNREACHABLE();
569 return NULL;
570 }
571 const char* Mnemonic() const { return MnemonicFromKind(kind_); }
572
573 static NumericRelation None() { return NumericRelation(NONE); }
574 static NumericRelation Eq() { return NumericRelation(EQ); }
575 static NumericRelation Gt() { return NumericRelation(GT); }
576 static NumericRelation Ge() { return NumericRelation(GE); }
577 static NumericRelation Lt() { return NumericRelation(LT); }
578 static NumericRelation Le() { return NumericRelation(LE); }
579 static NumericRelation Ne() { return NumericRelation(NE); }
580
581 bool IsNone() { return kind_ == NONE; }
582
583 static NumericRelation FromToken(Token::Value token) {
584 switch (token) {
585 case Token::EQ: return Eq();
586 case Token::EQ_STRICT: return Eq();
587 case Token::LT: return Lt();
588 case Token::GT: return Gt();
589 case Token::LTE: return Le();
590 case Token::GTE: return Ge();
591 case Token::NE: return Ne();
592 case Token::NE_STRICT: return Ne();
593 default: return None();
594 }
595 }
596
597 // The semantics of "Reversed" is that if "x rel y" is true then also
598 // "y rel.Reversed() x" is true, and that rel.Reversed().Reversed() == rel.
599 NumericRelation Reversed() {
600 switch (kind_) {
601 case NONE: return None();
602 case EQ: return Eq();
603 case GT: return Lt();
604 case GE: return Le();
605 case LT: return Gt();
606 case LE: return Ge();
607 case NE: return Ne();
608 }
609 UNREACHABLE();
610 return None();
611 }
612
613 // The semantics of "Negated" is that if "x rel y" is true then also
614 // "!(x rel.Negated() y)" is true.
615 NumericRelation Negated() {
616 switch (kind_) {
617 case NONE: return None();
618 case EQ: return Ne();
619 case GT: return Le();
620 case GE: return Lt();
621 case LT: return Ge();
622 case LE: return Gt();
623 case NE: return Eq();
624 }
625 UNREACHABLE();
626 return None();
627 }
628
629 // The semantics of "Implies" is that if "x rel y" is true
630 // then also "x other_relation y" is true.
631 bool Implies(NumericRelation other_relation) {
632 switch (kind_) {
633 case NONE: return false;
634 case EQ: return (other_relation.kind_ == EQ)
635 || (other_relation.kind_ == GE)
636 || (other_relation.kind_ == LE);
637 case GT: return (other_relation.kind_ == GT)
638 || (other_relation.kind_ == GE)
639 || (other_relation.kind_ == NE);
640 case LT: return (other_relation.kind_ == LT)
641 || (other_relation.kind_ == LE)
642 || (other_relation.kind_ == NE);
643 case GE: return (other_relation.kind_ == GE);
644 case LE: return (other_relation.kind_ == LE);
645 case NE: return (other_relation.kind_ == NE);
646 }
647 UNREACHABLE();
648 return false;
649 }
650
651 // The semantics of "IsExtendable" is that if
652 // "rel.IsExtendable(direction)" is true then
653 // "x rel y" implies "(x + direction) rel y" .
654 bool IsExtendable(int direction) {
655 switch (kind_) {
656 case NONE: return false;
657 case EQ: return false;
658 case GT: return (direction >= 0);
659 case GE: return (direction >= 0);
660 case LT: return (direction <= 0);
661 case LE: return (direction <= 0);
662 case NE: return false;
663 }
664 UNREACHABLE();
665 return false;
666 }
667
668 private:
669 explicit NumericRelation(Kind kind) : kind_(kind) {}
670
671 Kind kind_;
672 };
673
674
553 typedef EnumSet<GVNFlag> GVNFlagSet; 675 typedef EnumSet<GVNFlag> GVNFlagSet;
554 676
555 677
556 class HValue: public ZoneObject { 678 class HValue: public ZoneObject {
557 public: 679 public:
558 static const int kNoNumber = -1; 680 static const int kNoNumber = -1;
559 681
560 enum Flag { 682 enum Flag {
561 kFlexibleRepresentation, 683 kFlexibleRepresentation,
562 // Participate in Global Value Numbering, i.e. elimination of 684 // Participate in Global Value Numbering, i.e. elimination of
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
706 828
707 virtual void AddInformativeDefinitions() {} 829 virtual void AddInformativeDefinitions() {}
708 830
709 void UpdateRedefinedUsesWhileSettingUpInformativeDefinitions() { 831 void UpdateRedefinedUsesWhileSettingUpInformativeDefinitions() {
710 UpdateRedefinedUsesInner<TestDominanceUsingProcessedFlag>(); 832 UpdateRedefinedUsesInner<TestDominanceUsingProcessedFlag>();
711 } 833 }
712 void UpdateRedefinedUses() { 834 void UpdateRedefinedUses() {
713 UpdateRedefinedUsesInner<Dominates>(); 835 UpdateRedefinedUsesInner<Dominates>();
714 } 836 }
715 837
838 bool IsInteger32Constant();
839 int32_t GetInteger32Constant();
840
716 bool IsDefinedAfter(HBasicBlock* other) const; 841 bool IsDefinedAfter(HBasicBlock* other) const;
717 842
718 // Operands. 843 // Operands.
719 virtual int OperandCount() = 0; 844 virtual int OperandCount() = 0;
720 virtual HValue* OperandAt(int index) const = 0; 845 virtual HValue* OperandAt(int index) const = 0;
721 void SetOperandAt(int index, HValue* value); 846 void SetOperandAt(int index, HValue* value);
722 847
723 void DeleteAndReplaceWith(HValue* other); 848 void DeleteAndReplaceWith(HValue* other);
724 void ReplaceAllUsesWith(HValue* other); 849 void ReplaceAllUsesWith(HValue* other);
725 bool HasNoUses() const { return use_list_ == NULL; } 850 bool HasNoUses() const { return use_list_ == NULL; }
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
832 } 957 }
833 958
834 bool IsDead() const { 959 bool IsDead() const {
835 return HasNoUses() && !HasObservableSideEffects() && IsDeletable(); 960 return HasNoUses() && !HasObservableSideEffects() && IsDeletable();
836 } 961 }
837 962
838 #ifdef DEBUG 963 #ifdef DEBUG
839 virtual void Verify() = 0; 964 virtual void Verify() = 0;
840 #endif 965 #endif
841 966
967 // This method is recursive but it is guaranteed to terminate because
968 // RedefinedOperand() always dominates "this".
969 bool IsRelationTrue(NumericRelation relation, HValue* other) {
970 if (this == other) {
971 return NumericRelation::Eq().Implies(relation);
972 }
973
974 bool result = IsRelationTrueInternal(relation, other) ||
975 other->IsRelationTrueInternal(relation.Reversed(), this);
976 if (!result) {
977 HValue* redefined = RedefinedOperand();
978 if (redefined != NULL) {
979 result = redefined->IsRelationTrue(relation, other);
980 }
981 }
982 return result;
983 }
984
842 protected: 985 protected:
843 // This function must be overridden for instructions with flag kUseGVN, to 986 // This function must be overridden for instructions with flag kUseGVN, to
844 // compare the non-Operand parts of the instruction. 987 // compare the non-Operand parts of the instruction.
845 virtual bool DataEquals(HValue* other) { 988 virtual bool DataEquals(HValue* other) {
846 UNREACHABLE(); 989 UNREACHABLE();
847 return false; 990 return false;
848 } 991 }
849 992
850 virtual Representation RepresentationFromInputs() { 993 virtual Representation RepresentationFromInputs() {
851 return representation(); 994 return representation();
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
894 if (input != NULL) { 1037 if (input != NULL) {
895 for (HUseIterator uses = input->uses(); !uses.Done(); uses.Advance()) { 1038 for (HUseIterator uses = input->uses(); !uses.Done(); uses.Advance()) {
896 HValue* use = uses.value(); 1039 HValue* use = uses.value();
897 if (TestDominance(this, use)) { 1040 if (TestDominance(this, use)) {
898 use->SetOperandAt(uses.index(), this); 1041 use->SetOperandAt(uses.index(), this);
899 } 1042 }
900 } 1043 }
901 } 1044 }
902 } 1045 }
903 1046
1047 // Informative definitions can override this method to state any numeric
1048 // relation they provide on the redefined value.
1049 virtual bool IsRelationTrueInternal(NumericRelation relation, HValue* other) {
1050 return false;
1051 }
1052
904 static GVNFlagSet AllDependsOnFlagSet() { 1053 static GVNFlagSet AllDependsOnFlagSet() {
905 GVNFlagSet result; 1054 GVNFlagSet result;
906 // Create changes mask. 1055 // Create changes mask.
907 #define ADD_FLAG(type) result.Add(kDependsOn##type); 1056 #define ADD_FLAG(type) result.Add(kDependsOn##type);
908 GVN_TRACKED_FLAG_LIST(ADD_FLAG) 1057 GVN_TRACKED_FLAG_LIST(ADD_FLAG)
909 GVN_UNTRACKED_FLAG_LIST(ADD_FLAG) 1058 GVN_UNTRACKED_FLAG_LIST(ADD_FLAG)
910 #undef ADD_FLAG 1059 #undef ADD_FLAG
911 return result; 1060 return result;
912 } 1061 }
913 1062
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
1118 virtual Representation RequiredInputRepresentation(int index) { 1267 virtual Representation RequiredInputRepresentation(int index) {
1119 return Representation::None(); 1268 return Representation::None();
1120 } 1269 }
1121 1270
1122 virtual void PrintDataTo(StringStream* stream); 1271 virtual void PrintDataTo(StringStream* stream);
1123 1272
1124 DECLARE_CONCRETE_INSTRUCTION(DummyUse); 1273 DECLARE_CONCRETE_INSTRUCTION(DummyUse);
1125 }; 1274 };
1126 1275
1127 1276
1277 class HNumericConstraint : public HTemplateInstruction<2> {
1278 public:
1279 static HNumericConstraint* AddToGraph(HValue* constrained_value,
1280 NumericRelation relation,
1281 HValue* related_value,
1282 HInstruction* insertion_point = NULL);
1283
1284 HValue* constrained_value() { return OperandAt(0); }
1285 HValue* related_value() { return OperandAt(1); }
1286 NumericRelation relation() { return relation_; }
1287
1288 virtual int RedefinedOperandIndex() { return 0; }
1289
1290 virtual Representation RequiredInputRepresentation(int index) {
1291 return representation();
1292 }
1293
1294 virtual void PrintDataTo(StringStream* stream);
1295
1296 virtual bool IsRelationTrueInternal(NumericRelation other_relation,
1297 HValue* other_related_value) {
1298 if (related_value() == other_related_value) {
1299 return relation().Implies(other_relation);
1300 } else {
1301 return false;
1302 }
1303 }
1304
1305 DECLARE_CONCRETE_INSTRUCTION(NumericConstraint)
1306
1307 private:
1308 HNumericConstraint(HValue* constrained_value,
1309 NumericRelation relation,
1310 HValue* related_value)
1311 : relation_(relation) {
1312 SetOperandAt(0, constrained_value);
1313 SetOperandAt(1, related_value);
1314 set_representation(constrained_value->representation());
1315 }
1316
1317 NumericRelation relation_;
1318 };
1319
1320
1128 // We insert soft-deoptimize when we hit code with unknown typefeedback, 1321 // We insert soft-deoptimize when we hit code with unknown typefeedback,
1129 // so that we get a chance of re-optimizing with useful typefeedback. 1322 // so that we get a chance of re-optimizing with useful typefeedback.
1130 // HSoftDeoptimize does not end a basic block as opposed to HDeoptimize. 1323 // HSoftDeoptimize does not end a basic block as opposed to HDeoptimize.
1131 class HSoftDeoptimize: public HTemplateInstruction<0> { 1324 class HSoftDeoptimize: public HTemplateInstruction<0> {
1132 public: 1325 public:
1133 virtual Representation RequiredInputRepresentation(int index) { 1326 virtual Representation RequiredInputRepresentation(int index) {
1134 return Representation::None(); 1327 return Representation::None();
1135 } 1328 }
1136 1329
1137 DECLARE_CONCRETE_INSTRUCTION(SoftDeoptimize) 1330 DECLARE_CONCRETE_INSTRUCTION(SoftDeoptimize)
(...skipping 1532 matching lines...) Expand 10 before | Expand all | Expand 10 after
2670 virtual int OperandCount() { return inputs_.length(); } 2863 virtual int OperandCount() { return inputs_.length(); }
2671 virtual HValue* OperandAt(int index) const { return inputs_[index]; } 2864 virtual HValue* OperandAt(int index) const { return inputs_[index]; }
2672 HValue* GetRedundantReplacement(); 2865 HValue* GetRedundantReplacement();
2673 void AddInput(HValue* value); 2866 void AddInput(HValue* value);
2674 bool HasRealUses(); 2867 bool HasRealUses();
2675 2868
2676 bool IsReceiver() { return merged_index_ == 0; } 2869 bool IsReceiver() { return merged_index_ == 0; }
2677 2870
2678 int merged_index() const { return merged_index_; } 2871 int merged_index() const { return merged_index_; }
2679 2872
2873 virtual void AddInformativeDefinitions();
2874
2680 virtual void PrintTo(StringStream* stream); 2875 virtual void PrintTo(StringStream* stream);
2681 2876
2682 #ifdef DEBUG 2877 #ifdef DEBUG
2683 virtual void Verify(); 2878 virtual void Verify();
2684 #endif 2879 #endif
2685 2880
2686 void InitRealUses(int id); 2881 void InitRealUses(int id);
2687 void AddNonPhiUsesFrom(HPhi* other); 2882 void AddNonPhiUsesFrom(HPhi* other);
2688 void AddIndirectUsesTo(int* use_count); 2883 void AddIndirectUsesTo(int* use_count);
2689 2884
(...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after
3147 bool skip_check() { return skip_check_; } 3342 bool skip_check() { return skip_check_; }
3148 void set_skip_check(bool skip_check) { skip_check_ = skip_check; } 3343 void set_skip_check(bool skip_check) { skip_check_ = skip_check; }
3149 3344
3150 virtual Representation RequiredInputRepresentation(int arg_index) { 3345 virtual Representation RequiredInputRepresentation(int arg_index) {
3151 return representation(); 3346 return representation();
3152 } 3347 }
3153 virtual Representation observed_input_representation(int index) { 3348 virtual Representation observed_input_representation(int index) {
3154 return Representation::Integer32(); 3349 return Representation::Integer32();
3155 } 3350 }
3156 3351
3352 virtual bool IsRelationTrueInternal(NumericRelation relation,
3353 HValue* related_value);
3354
3157 virtual void PrintDataTo(StringStream* stream); 3355 virtual void PrintDataTo(StringStream* stream);
3158 virtual void InferRepresentation(HInferRepresentation* h_infer); 3356 virtual void InferRepresentation(HInferRepresentation* h_infer);
3159 3357
3160 HValue* index() { return OperandAt(0); } 3358 HValue* index() { return OperandAt(0); }
3161 HValue* length() { return OperandAt(1); } 3359 HValue* length() { return OperandAt(1); }
3162 3360
3163 virtual int RedefinedOperandIndex() { return 0; } 3361 virtual int RedefinedOperandIndex() { return 0; }
3362 virtual void AddInformativeDefinitions();
3164 3363
3165 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck) 3364 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck)
3166 3365
3167 protected: 3366 protected:
3168 virtual bool DataEquals(HValue* other) { return true; } 3367 virtual bool DataEquals(HValue* other) { return true; }
3169 BoundsCheckKeyMode key_mode_; 3368 BoundsCheckKeyMode key_mode_;
3170 bool skip_check_; 3369 bool skip_check_;
3171 }; 3370 };
3172 3371
3173 3372
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
3330 virtual void InferRepresentation(HInferRepresentation* h_infer); 3529 virtual void InferRepresentation(HInferRepresentation* h_infer);
3331 3530
3332 virtual Representation RequiredInputRepresentation(int index) { 3531 virtual Representation RequiredInputRepresentation(int index) {
3333 return representation(); 3532 return representation();
3334 } 3533 }
3335 virtual Representation observed_input_representation(int index) { 3534 virtual Representation observed_input_representation(int index) {
3336 return observed_input_representation_[index]; 3535 return observed_input_representation_[index];
3337 } 3536 }
3338 virtual void PrintDataTo(StringStream* stream); 3537 virtual void PrintDataTo(StringStream* stream);
3339 3538
3539 virtual void AddInformativeDefinitions();
3540
3340 DECLARE_CONCRETE_INSTRUCTION(CompareIDAndBranch) 3541 DECLARE_CONCRETE_INSTRUCTION(CompareIDAndBranch)
3341 3542
3342 private: 3543 private:
3343 Representation observed_input_representation_[2]; 3544 Representation observed_input_representation_[2];
3344 Token::Value token_; 3545 Token::Value token_;
3345 }; 3546 };
3346 3547
3347 3548
3348 class HCompareObjectEqAndBranch: public HTemplateControlInstruction<2, 2> { 3549 class HCompareObjectEqAndBranch: public HTemplateControlInstruction<2, 2> {
3349 public: 3550 public:
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after
3734 3935
3735 static HInstruction* NewHAdd(Zone* zone, 3936 static HInstruction* NewHAdd(Zone* zone,
3736 HValue* context, 3937 HValue* context,
3737 HValue* left, 3938 HValue* left,
3738 HValue* right); 3939 HValue* right);
3739 3940
3740 virtual HType CalculateInferredType(); 3941 virtual HType CalculateInferredType();
3741 3942
3742 virtual HValue* Canonicalize(); 3943 virtual HValue* Canonicalize();
3743 3944
3945 virtual bool IsRelationTrueInternal(NumericRelation relation, HValue* other) {
3946 HValue* base = NULL;
3947 int32_t offset = 0;
3948 if (left()->IsInteger32Constant()) {
3949 base = right();
3950 offset = left()->GetInteger32Constant();
3951 } else if (right()->IsInteger32Constant()) {
3952 base = left();
3953 offset = right()->GetInteger32Constant();
3954 } else {
3955 return false;
3956 }
3957
3958 return relation.IsExtendable(offset)
3959 ? base->IsRelationTrue(relation, other) : false;
3960 }
3961
3744 DECLARE_CONCRETE_INSTRUCTION(Add) 3962 DECLARE_CONCRETE_INSTRUCTION(Add)
3745 3963
3746 protected: 3964 protected:
3747 virtual bool DataEquals(HValue* other) { return true; } 3965 virtual bool DataEquals(HValue* other) { return true; }
3748 3966
3749 virtual Range* InferRange(Zone* zone); 3967 virtual Range* InferRange(Zone* zone);
3750 }; 3968 };
3751 3969
3752 3970
3753 class HSub: public HArithmeticBinaryOperation { 3971 class HSub: public HArithmeticBinaryOperation {
3754 public: 3972 public:
3755 HSub(HValue* context, HValue* left, HValue* right) 3973 HSub(HValue* context, HValue* left, HValue* right)
3756 : HArithmeticBinaryOperation(context, left, right) { 3974 : HArithmeticBinaryOperation(context, left, right) {
3757 SetFlag(kCanOverflow); 3975 SetFlag(kCanOverflow);
3758 } 3976 }
3759 3977
3760 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); 3978 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
3761 3979
3762 virtual HValue* Canonicalize(); 3980 virtual HValue* Canonicalize();
3763 3981
3764 static HInstruction* NewHSub(Zone* zone, 3982 static HInstruction* NewHSub(Zone* zone,
3765 HValue* context, 3983 HValue* context,
3766 HValue* left, 3984 HValue* left,
3767 HValue* right); 3985 HValue* right);
3768 3986
3987 virtual bool IsRelationTrueInternal(NumericRelation relation, HValue* other) {
3988 if (right()->IsInteger32Constant()) {
3989 HValue* base = left();
3990 int32_t offset = right()->GetInteger32Constant();
3991 return relation.IsExtendable(-offset)
3992 ? base->IsRelationTrue(relation, other) : false;
3993 } else {
3994 return false;
3995 }
3996 }
3997
3769 DECLARE_CONCRETE_INSTRUCTION(Sub) 3998 DECLARE_CONCRETE_INSTRUCTION(Sub)
3770 3999
3771 protected: 4000 protected:
3772 virtual bool DataEquals(HValue* other) { return true; } 4001 virtual bool DataEquals(HValue* other) { return true; }
3773 4002
3774 virtual Range* InferRange(Zone* zone); 4003 virtual Range* InferRange(Zone* zone);
3775 }; 4004 };
3776 4005
3777 4006
3778 class HMul: public HArithmeticBinaryOperation { 4007 class HMul: public HArithmeticBinaryOperation {
(...skipping 2006 matching lines...) Expand 10 before | Expand all | Expand 10 after
5785 virtual bool IsDeletable() const { return true; } 6014 virtual bool IsDeletable() const { return true; }
5786 }; 6015 };
5787 6016
5788 6017
5789 #undef DECLARE_INSTRUCTION 6018 #undef DECLARE_INSTRUCTION
5790 #undef DECLARE_CONCRETE_INSTRUCTION 6019 #undef DECLARE_CONCRETE_INSTRUCTION
5791 6020
5792 } } // namespace v8::internal 6021 } } // namespace v8::internal
5793 6022
5794 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ 6023 #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