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

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

Issue 21579003: Remove instructions and infrastructure related to IDEFs that is now obsolete (and was never turned … (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Remove TODO. Created 7 years, 4 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 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
115 V(ForceRepresentation) \ 115 V(ForceRepresentation) \
116 V(ForInCacheArray) \ 116 V(ForInCacheArray) \
117 V(ForInPrepareMap) \ 117 V(ForInPrepareMap) \
118 V(FunctionLiteral) \ 118 V(FunctionLiteral) \
119 V(GetCachedArrayIndex) \ 119 V(GetCachedArrayIndex) \
120 V(GlobalObject) \ 120 V(GlobalObject) \
121 V(GlobalReceiver) \ 121 V(GlobalReceiver) \
122 V(Goto) \ 122 V(Goto) \
123 V(HasCachedArrayIndexAndBranch) \ 123 V(HasCachedArrayIndexAndBranch) \
124 V(HasInstanceTypeAndBranch) \ 124 V(HasInstanceTypeAndBranch) \
125 V(InductionVariableAnnotation) \
126 V(InnerAllocatedObject) \ 125 V(InnerAllocatedObject) \
127 V(InstanceOf) \ 126 V(InstanceOf) \
128 V(InstanceOfKnownGlobal) \ 127 V(InstanceOfKnownGlobal) \
129 V(InstanceSize) \ 128 V(InstanceSize) \
130 V(InvokeFunction) \ 129 V(InvokeFunction) \
131 V(IsConstructCallAndBranch) \ 130 V(IsConstructCallAndBranch) \
132 V(IsObjectAndBranch) \ 131 V(IsObjectAndBranch) \
133 V(IsNumberAndBranch) \ 132 V(IsNumberAndBranch) \
134 V(IsStringAndBranch) \ 133 V(IsStringAndBranch) \
135 V(IsSmiAndBranch) \ 134 V(IsSmiAndBranch) \
136 V(IsUndetectableAndBranch) \ 135 V(IsUndetectableAndBranch) \
137 V(LeaveInlined) \ 136 V(LeaveInlined) \
138 V(LoadContextSlot) \ 137 V(LoadContextSlot) \
139 V(LoadExternalArrayPointer) \ 138 V(LoadExternalArrayPointer) \
140 V(LoadFieldByIndex) \ 139 V(LoadFieldByIndex) \
141 V(LoadFunctionPrototype) \ 140 V(LoadFunctionPrototype) \
142 V(LoadGlobalCell) \ 141 V(LoadGlobalCell) \
143 V(LoadGlobalGeneric) \ 142 V(LoadGlobalGeneric) \
144 V(LoadKeyed) \ 143 V(LoadKeyed) \
145 V(LoadKeyedGeneric) \ 144 V(LoadKeyedGeneric) \
146 V(LoadNamedField) \ 145 V(LoadNamedField) \
147 V(LoadNamedFieldPolymorphic) \ 146 V(LoadNamedFieldPolymorphic) \
148 V(LoadNamedGeneric) \ 147 V(LoadNamedGeneric) \
149 V(MapEnumLength) \ 148 V(MapEnumLength) \
150 V(MathFloorOfDiv) \ 149 V(MathFloorOfDiv) \
151 V(MathMinMax) \ 150 V(MathMinMax) \
152 V(Mod) \ 151 V(Mod) \
153 V(Mul) \ 152 V(Mul) \
154 V(NumericConstraint) \
155 V(OsrEntry) \ 153 V(OsrEntry) \
156 V(OuterContext) \ 154 V(OuterContext) \
157 V(Parameter) \ 155 V(Parameter) \
158 V(Power) \ 156 V(Power) \
159 V(PushArgument) \ 157 V(PushArgument) \
160 V(Random) \ 158 V(Random) \
161 V(RegExpLiteral) \ 159 V(RegExpLiteral) \
162 V(Return) \ 160 V(Return) \
163 V(Ror) \ 161 V(Ror) \
164 V(Sar) \ 162 V(Sar) \
(...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after
535 GVN_UNTRACKED_FLAG_LIST(DECLARE_FLAG) 533 GVN_UNTRACKED_FLAG_LIST(DECLARE_FLAG)
536 #undef DECLARE_FLAG 534 #undef DECLARE_FLAG
537 kAfterLastFlag, 535 kAfterLastFlag,
538 kLastFlag = kAfterLastFlag - 1, 536 kLastFlag = kAfterLastFlag - 1,
539 #define COUNT_FLAG(type) + 1 537 #define COUNT_FLAG(type) + 1
540 kNumberOfTrackedSideEffects = 0 GVN_TRACKED_FLAG_LIST(COUNT_FLAG) 538 kNumberOfTrackedSideEffects = 0 GVN_TRACKED_FLAG_LIST(COUNT_FLAG)
541 #undef COUNT_FLAG 539 #undef COUNT_FLAG
542 }; 540 };
543 541
544 542
545 class NumericRelation {
546 public:
547 enum Kind { NONE, EQ, GT, GE, LT, LE, NE };
548 static const char* MnemonicFromKind(Kind kind) {
549 switch (kind) {
550 case NONE: return "NONE";
551 case EQ: return "EQ";
552 case GT: return "GT";
553 case GE: return "GE";
554 case LT: return "LT";
555 case LE: return "LE";
556 case NE: return "NE";
557 }
558 UNREACHABLE();
559 return NULL;
560 }
561 const char* Mnemonic() const { return MnemonicFromKind(kind_); }
562
563 static NumericRelation None() { return NumericRelation(NONE); }
564 static NumericRelation Eq() { return NumericRelation(EQ); }
565 static NumericRelation Gt() { return NumericRelation(GT); }
566 static NumericRelation Ge() { return NumericRelation(GE); }
567 static NumericRelation Lt() { return NumericRelation(LT); }
568 static NumericRelation Le() { return NumericRelation(LE); }
569 static NumericRelation Ne() { return NumericRelation(NE); }
570
571 bool IsNone() { return kind_ == NONE; }
572
573 static NumericRelation FromToken(Token::Value token) {
574 switch (token) {
575 case Token::EQ: return Eq();
576 case Token::EQ_STRICT: return Eq();
577 case Token::LT: return Lt();
578 case Token::GT: return Gt();
579 case Token::LTE: return Le();
580 case Token::GTE: return Ge();
581 case Token::NE: return Ne();
582 case Token::NE_STRICT: return Ne();
583 default: return None();
584 }
585 }
586
587 // The semantics of "Reversed" is that if "x rel y" is true then also
588 // "y rel.Reversed() x" is true, and that rel.Reversed().Reversed() == rel.
589 NumericRelation Reversed() {
590 switch (kind_) {
591 case NONE: return None();
592 case EQ: return Eq();
593 case GT: return Lt();
594 case GE: return Le();
595 case LT: return Gt();
596 case LE: return Ge();
597 case NE: return Ne();
598 }
599 UNREACHABLE();
600 return None();
601 }
602
603 // The semantics of "Negated" is that if "x rel y" is true then also
604 // "!(x rel.Negated() y)" is true.
605 NumericRelation Negated() {
606 switch (kind_) {
607 case NONE: return None();
608 case EQ: return Ne();
609 case GT: return Le();
610 case GE: return Lt();
611 case LT: return Ge();
612 case LE: return Gt();
613 case NE: return Eq();
614 }
615 UNREACHABLE();
616 return None();
617 }
618
619 // The semantics of "Implies" is that if "x rel y" is true
620 // then also "x other_relation y" is true.
621 bool Implies(NumericRelation other_relation) {
622 switch (kind_) {
623 case NONE: return false;
624 case EQ: return (other_relation.kind_ == EQ)
625 || (other_relation.kind_ == GE)
626 || (other_relation.kind_ == LE);
627 case GT: return (other_relation.kind_ == GT)
628 || (other_relation.kind_ == GE)
629 || (other_relation.kind_ == NE);
630 case LT: return (other_relation.kind_ == LT)
631 || (other_relation.kind_ == LE)
632 || (other_relation.kind_ == NE);
633 case GE: return (other_relation.kind_ == GE);
634 case LE: return (other_relation.kind_ == LE);
635 case NE: return (other_relation.kind_ == NE);
636 }
637 UNREACHABLE();
638 return false;
639 }
640
641 // The semantics of "IsExtendable" is that if
642 // "rel.IsExtendable(direction)" is true then
643 // "x rel y" implies "(x + direction) rel y" .
644 bool IsExtendable(int direction) {
645 switch (kind_) {
646 case NONE: return false;
647 case EQ: return false;
648 case GT: return (direction >= 0);
649 case GE: return (direction >= 0);
650 case LT: return (direction <= 0);
651 case LE: return (direction <= 0);
652 case NE: return false;
653 }
654 UNREACHABLE();
655 return false;
656 }
657
658 // CompoundImplies returns true when
659 // "((x + my_offset) >> my_scale) rel y" implies
660 // "((x + other_offset) >> other_scale) other_relation y".
661 bool CompoundImplies(NumericRelation other_relation,
662 int my_offset,
663 int my_scale,
664 int other_offset = 0,
665 int other_scale = 0) {
666 return Implies(other_relation) && ComponentsImply(
667 my_offset, my_scale, other_offset, other_scale);
668 }
669
670 private:
671 // ComponentsImply returns true when
672 // "((x + my_offset) >> my_scale) rel y" implies
673 // "((x + other_offset) >> other_scale) rel y".
674 bool ComponentsImply(int my_offset,
675 int my_scale,
676 int other_offset,
677 int other_scale) {
678 switch (kind_) {
679 case NONE: break; // Fall through to UNREACHABLE().
680 case EQ:
681 case NE: return my_offset == other_offset && my_scale == other_scale;
682 case GT:
683 case GE: return my_offset <= other_offset && my_scale >= other_scale;
684 case LT:
685 case LE: return my_offset >= other_offset && my_scale <= other_scale;
686 }
687 UNREACHABLE();
688 return false;
689 }
690
691 explicit NumericRelation(Kind kind) : kind_(kind) {}
692
693 Kind kind_;
694 };
695
696
697 class DecompositionResult BASE_EMBEDDED { 543 class DecompositionResult BASE_EMBEDDED {
698 public: 544 public:
699 DecompositionResult() : base_(NULL), offset_(0), scale_(0) {} 545 DecompositionResult() : base_(NULL), offset_(0), scale_(0) {}
700 546
701 HValue* base() { return base_; } 547 HValue* base() { return base_; }
702 int offset() { return offset_; } 548 int offset() { return offset_; }
703 int scale() { return scale_; } 549 int scale() { return scale_; }
704 550
705 bool Apply(HValue* other_base, int other_offset, int other_scale = 0) { 551 bool Apply(HValue* other_base, int other_offset, int other_scale = 0) {
706 if (base_ == NULL) { 552 if (base_ == NULL) {
(...skipping 25 matching lines...) Expand all
732 *a = *b; 578 *a = *b;
733 *b = c; 579 *b = c;
734 } 580 }
735 581
736 HValue* base_; 582 HValue* base_;
737 int offset_; 583 int offset_;
738 int scale_; 584 int scale_;
739 }; 585 };
740 586
741 587
742 class RangeEvaluationContext BASE_EMBEDDED {
743 public:
744 RangeEvaluationContext(HValue* value, HValue* upper);
745
746 HValue* lower_bound() { return lower_bound_; }
747 HValue* lower_bound_guarantee() { return lower_bound_guarantee_; }
748 HValue* candidate() { return candidate_; }
749 HValue* upper_bound() { return upper_bound_; }
750 HValue* upper_bound_guarantee() { return upper_bound_guarantee_; }
751 int offset() { return offset_; }
752 int scale() { return scale_; }
753
754 bool is_range_satisfied() {
755 return lower_bound_guarantee() != NULL && upper_bound_guarantee() != NULL;
756 }
757
758 void set_lower_bound_guarantee(HValue* guarantee) {
759 lower_bound_guarantee_ = ConvertGuarantee(guarantee);
760 }
761 void set_upper_bound_guarantee(HValue* guarantee) {
762 upper_bound_guarantee_ = ConvertGuarantee(guarantee);
763 }
764
765 void swap_candidate(DecompositionResult* other_candicate) {
766 other_candicate->SwapValues(&candidate_, &offset_, &scale_);
767 }
768
769 private:
770 HValue* ConvertGuarantee(HValue* guarantee);
771
772 HValue* lower_bound_;
773 HValue* lower_bound_guarantee_;
774 HValue* candidate_;
775 HValue* upper_bound_;
776 HValue* upper_bound_guarantee_;
777 int offset_;
778 int scale_;
779 };
780
781
782 typedef EnumSet<GVNFlag> GVNFlagSet; 588 typedef EnumSet<GVNFlag> GVNFlagSet;
783 589
784 590
785 class HValue: public ZoneObject { 591 class HValue: public ZoneObject {
786 public: 592 public:
787 static const int kNoNumber = -1; 593 static const int kNoNumber = -1;
788 594
789 enum Flag { 595 enum Flag {
790 kFlexibleRepresentation, 596 kFlexibleRepresentation,
791 kCannotBeTagged, 597 kCannotBeTagged,
(...skipping 17 matching lines...) Expand all
809 kAllUsesTruncatingToSmi, 615 kAllUsesTruncatingToSmi,
810 // Set after an instruction is killed. 616 // Set after an instruction is killed.
811 kIsDead, 617 kIsDead,
812 // Instructions that are allowed to produce full range unsigned integer 618 // Instructions that are allowed to produce full range unsigned integer
813 // values are marked with kUint32 flag. If arithmetic shift or a load from 619 // values are marked with kUint32 flag. If arithmetic shift or a load from
814 // EXTERNAL_UNSIGNED_INT_ELEMENTS array is not marked with this flag 620 // EXTERNAL_UNSIGNED_INT_ELEMENTS array is not marked with this flag
815 // it will deoptimize if result does not fit into signed integer range. 621 // it will deoptimize if result does not fit into signed integer range.
816 // HGraph::ComputeSafeUint32Operations is responsible for setting this 622 // HGraph::ComputeSafeUint32Operations is responsible for setting this
817 // flag. 623 // flag.
818 kUint32, 624 kUint32,
819 // If a phi is involved in the evaluation of a numeric constraint the
820 // recursion can cause an endless cycle: we use this flag to exit the loop.
821 kNumericConstraintEvaluationInProgress,
822 // This flag is set to true after the SetupInformativeDefinitions() pass
823 // has processed this instruction.
824 kIDefsProcessingDone,
825 kHasNoObservableSideEffects, 625 kHasNoObservableSideEffects,
826 // Indicates the instruction is live during dead code elimination. 626 // Indicates the instruction is live during dead code elimination.
827 kIsLive, 627 kIsLive,
828 628
829 // HEnvironmentMarkers are deleted before dead code 629 // HEnvironmentMarkers are deleted before dead code
830 // elimination takes place, so they can repurpose the kIsLive flag: 630 // elimination takes place, so they can repurpose the kIsLive flag:
831 kEndsLiveRange = kIsLive, 631 kEndsLiveRange = kIsLive,
832 632
833 // TODO(everyone): Don't forget to update this! 633 // TODO(everyone): Don't forget to update this!
834 kLastFlag = kIsLive 634 kLastFlag = kIsLive
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
952 // One of the iDef operands is special because it is the value that is 752 // One of the iDef operands is special because it is the value that is
953 // "transferred" to the output, we call it the "redefined operand". 753 // "transferred" to the output, we call it the "redefined operand".
954 // If an HValue is an iDef it must override RedefinedOperandIndex() so that 754 // If an HValue is an iDef it must override RedefinedOperandIndex() so that
955 // it does not return kNoRedefinedOperand; 755 // it does not return kNoRedefinedOperand;
956 static const int kNoRedefinedOperand = -1; 756 static const int kNoRedefinedOperand = -1;
957 virtual int RedefinedOperandIndex() { return kNoRedefinedOperand; } 757 virtual int RedefinedOperandIndex() { return kNoRedefinedOperand; }
958 bool IsInformativeDefinition() { 758 bool IsInformativeDefinition() {
959 return RedefinedOperandIndex() != kNoRedefinedOperand; 759 return RedefinedOperandIndex() != kNoRedefinedOperand;
960 } 760 }
961 HValue* RedefinedOperand() { 761 HValue* RedefinedOperand() {
962 return IsInformativeDefinition() ? OperandAt(RedefinedOperandIndex()) 762 int index = RedefinedOperandIndex();
963 : NULL; 763 return index == kNoRedefinedOperand ? NULL : OperandAt(index);
964 } 764 }
965 765
966 // A purely informative definition is an idef that will not emit code and 766 // A purely informative definition is an idef that will not emit code and
967 // should therefore be removed from the graph in the RestoreActualValues 767 // should therefore be removed from the graph in the RestoreActualValues
968 // phase (so that live ranges will be shorter). 768 // phase (so that live ranges will be shorter).
969 virtual bool IsPurelyInformativeDefinition() { return false; } 769 virtual bool IsPurelyInformativeDefinition() { return false; }
970 770
971 // This method must always return the original HValue SSA definition 771 // This method must always return the original HValue SSA definition
972 // (regardless of any iDef of this value). 772 // (regardless of any iDef of this value).
973 HValue* ActualValue() { 773 HValue* ActualValue() {
974 return IsInformativeDefinition() ? RedefinedOperand()->ActualValue() 774 int index = RedefinedOperandIndex();
975 : this; 775 return index == kNoRedefinedOperand ? this : OperandAt(index);
976 }
977
978 virtual void AddInformativeDefinitions() {}
979
980 void UpdateRedefinedUsesWhileSettingUpInformativeDefinitions() {
981 UpdateRedefinedUsesInner<TestDominanceUsingProcessedFlag>();
982 }
983 void UpdateRedefinedUses() {
984 UpdateRedefinedUsesInner<Dominates>();
985 } 776 }
986 777
987 bool IsInteger32Constant(); 778 bool IsInteger32Constant();
988 int32_t GetInteger32Constant(); 779 int32_t GetInteger32Constant();
989 bool EqualsInteger32Constant(int32_t value); 780 bool EqualsInteger32Constant(int32_t value);
990 781
991 bool IsDefinedAfter(HBasicBlock* other) const; 782 bool IsDefinedAfter(HBasicBlock* other) const;
992 783
993 // Operands. 784 // Operands.
994 virtual int OperandCount() = 0; 785 virtual int OperandCount() = 0;
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
1125 916
1126 // Check if this instruction has some reason that prevents elimination. 917 // Check if this instruction has some reason that prevents elimination.
1127 bool CannotBeEliminated() const { 918 bool CannotBeEliminated() const {
1128 return HasObservableSideEffects() || !IsDeletable(); 919 return HasObservableSideEffects() || !IsDeletable();
1129 } 920 }
1130 921
1131 #ifdef DEBUG 922 #ifdef DEBUG
1132 virtual void Verify() = 0; 923 virtual void Verify() = 0;
1133 #endif 924 #endif
1134 925
1135 bool IsRelationTrue(NumericRelation relation,
1136 HValue* other,
1137 int offset = 0,
1138 int scale = 0);
1139
1140 bool TryGuaranteeRange(HValue* upper_bound);
1141 virtual bool TryDecompose(DecompositionResult* decomposition) { 926 virtual bool TryDecompose(DecompositionResult* decomposition) {
1142 if (RedefinedOperand() != NULL) { 927 if (RedefinedOperand() != NULL) {
1143 return RedefinedOperand()->TryDecompose(decomposition); 928 return RedefinedOperand()->TryDecompose(decomposition);
1144 } else { 929 } else {
1145 return false; 930 return false;
1146 } 931 }
1147 } 932 }
1148 933
1149 // Returns true conservatively if the program might be able to observe a 934 // Returns true conservatively if the program might be able to observe a
1150 // ToString() operation on this value. 935 // ToString() operation on this value.
1151 bool ToStringCanBeObserved() const { 936 bool ToStringCanBeObserved() const {
1152 return type().ToStringOrToNumberCanBeObserved(representation()); 937 return type().ToStringOrToNumberCanBeObserved(representation());
1153 } 938 }
1154 939
1155 // Returns true conservatively if the program might be able to observe a 940 // Returns true conservatively if the program might be able to observe a
1156 // ToNumber() operation on this value. 941 // ToNumber() operation on this value.
1157 bool ToNumberCanBeObserved() const { 942 bool ToNumberCanBeObserved() const {
1158 return type().ToStringOrToNumberCanBeObserved(representation()); 943 return type().ToStringOrToNumberCanBeObserved(representation());
1159 } 944 }
1160 945
1161 protected: 946 protected:
1162 void TryGuaranteeRangeRecursive(RangeEvaluationContext* context);
1163
1164 enum RangeGuaranteeDirection {
1165 DIRECTION_NONE = 0,
1166 DIRECTION_UPPER = 1,
1167 DIRECTION_LOWER = 2,
1168 DIRECTION_BOTH = DIRECTION_UPPER | DIRECTION_LOWER
1169 };
1170 virtual void SetResponsibilityForRange(RangeGuaranteeDirection direction) {}
1171 virtual void TryGuaranteeRangeChanging(RangeEvaluationContext* context) {}
1172
1173 // This function must be overridden for instructions with flag kUseGVN, to 947 // This function must be overridden for instructions with flag kUseGVN, to
1174 // compare the non-Operand parts of the instruction. 948 // compare the non-Operand parts of the instruction.
1175 virtual bool DataEquals(HValue* other) { 949 virtual bool DataEquals(HValue* other) {
1176 UNREACHABLE(); 950 UNREACHABLE();
1177 return false; 951 return false;
1178 } 952 }
1179 953
1180 virtual Representation RepresentationFromInputs() { 954 virtual Representation RepresentationFromInputs() {
1181 return representation(); 955 return representation();
1182 } 956 }
(...skipping 13 matching lines...) Expand all
1196 void clear_block() { 970 void clear_block() {
1197 ASSERT(block_ != NULL); 971 ASSERT(block_ != NULL);
1198 block_ = NULL; 972 block_ = NULL;
1199 } 973 }
1200 974
1201 void set_representation(Representation r) { 975 void set_representation(Representation r) {
1202 ASSERT(representation_.IsNone() && !r.IsNone()); 976 ASSERT(representation_.IsNone() && !r.IsNone());
1203 representation_ = r; 977 representation_ = r;
1204 } 978 }
1205 979
1206 // Signature of a function testing if a HValue properly dominates another.
1207 typedef bool (*DominanceTest)(HValue*, HValue*);
1208
1209 // Simple implementation of DominanceTest implemented walking the chain
1210 // of Hinstructions (used in UpdateRedefinedUsesInner).
1211 static bool Dominates(HValue* dominator, HValue* dominated);
1212
1213 // A fast implementation of DominanceTest that works only for the
1214 // "current" instruction in the SetupInformativeDefinitions() phase.
1215 // During that phase we use a flag to mark processed instructions, and by
1216 // checking the flag we can quickly test if an instruction comes before or
1217 // after the "current" one.
1218 static bool TestDominanceUsingProcessedFlag(HValue* dominator,
1219 HValue* dominated);
1220
1221 // If we are redefining an operand, update all its dominated uses (the
1222 // function that checks if a use is dominated is the template argument).
1223 template<DominanceTest TestDominance>
1224 void UpdateRedefinedUsesInner() {
1225 HValue* input = RedefinedOperand();
1226 if (input != NULL) {
1227 for (HUseIterator uses = input->uses(); !uses.Done(); uses.Advance()) {
1228 HValue* use = uses.value();
1229 if (TestDominance(this, use)) {
1230 use->SetOperandAt(uses.index(), this);
1231 }
1232 }
1233 }
1234 }
1235
1236 // Informative definitions can override this method to state any numeric
1237 // relation they provide on the redefined value.
1238 // Returns true if it is guaranteed that:
1239 // ((this + offset) >> scale) relation other
1240 virtual bool IsRelationTrueInternal(NumericRelation relation,
1241 HValue* other,
1242 int offset = 0,
1243 int scale = 0) {
1244 return false;
1245 }
1246
1247 static GVNFlagSet AllDependsOnFlagSet() { 980 static GVNFlagSet AllDependsOnFlagSet() {
1248 GVNFlagSet result; 981 GVNFlagSet result;
1249 // Create changes mask. 982 // Create changes mask.
1250 #define ADD_FLAG(type) result.Add(kDependsOn##type); 983 #define ADD_FLAG(type) result.Add(kDependsOn##type);
1251 GVN_TRACKED_FLAG_LIST(ADD_FLAG) 984 GVN_TRACKED_FLAG_LIST(ADD_FLAG)
1252 GVN_UNTRACKED_FLAG_LIST(ADD_FLAG) 985 GVN_UNTRACKED_FLAG_LIST(ADD_FLAG)
1253 #undef ADD_FLAG 986 #undef ADD_FLAG
1254 return result; 987 return result;
1255 } 988 }
1256 989
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after
1507 virtual Representation RequiredInputRepresentation(int index) { 1240 virtual Representation RequiredInputRepresentation(int index) {
1508 return Representation::None(); 1241 return Representation::None();
1509 } 1242 }
1510 1243
1511 virtual void PrintDataTo(StringStream* stream); 1244 virtual void PrintDataTo(StringStream* stream);
1512 1245
1513 DECLARE_CONCRETE_INSTRUCTION(DummyUse); 1246 DECLARE_CONCRETE_INSTRUCTION(DummyUse);
1514 }; 1247 };
1515 1248
1516 1249
1517 class HNumericConstraint : public HTemplateInstruction<2> {
1518 public:
1519 static HNumericConstraint* AddToGraph(HValue* constrained_value,
1520 NumericRelation relation,
1521 HValue* related_value,
1522 HInstruction* insertion_point = NULL);
1523
1524 HValue* constrained_value() { return OperandAt(0); }
1525 HValue* related_value() { return OperandAt(1); }
1526 NumericRelation relation() { return relation_; }
1527
1528 virtual int RedefinedOperandIndex() { return 0; }
1529 virtual bool IsPurelyInformativeDefinition() { return true; }
1530
1531 virtual Representation RequiredInputRepresentation(int index) {
1532 return representation();
1533 }
1534
1535 virtual void PrintDataTo(StringStream* stream);
1536
1537 virtual bool IsRelationTrueInternal(NumericRelation other_relation,
1538 HValue* other_related_value,
1539 int offset = 0,
1540 int scale = 0) {
1541 if (related_value() == other_related_value) {
1542 return relation().CompoundImplies(other_relation, offset, scale);
1543 } else {
1544 return false;
1545 }
1546 }
1547
1548 DECLARE_CONCRETE_INSTRUCTION(NumericConstraint)
1549
1550 private:
1551 HNumericConstraint(HValue* constrained_value,
1552 NumericRelation relation,
1553 HValue* related_value)
1554 : relation_(relation) {
1555 SetOperandAt(0, constrained_value);
1556 SetOperandAt(1, related_value);
1557 }
1558
1559 NumericRelation relation_;
1560 };
1561
1562
1563 class HDeoptimize: public HTemplateInstruction<0> { 1250 class HDeoptimize: public HTemplateInstruction<0> {
1564 public: 1251 public:
1565 DECLARE_INSTRUCTION_FACTORY_P1(HDeoptimize, Deoptimizer::BailoutType); 1252 DECLARE_INSTRUCTION_FACTORY_P1(HDeoptimize, Deoptimizer::BailoutType);
1566 1253
1567 virtual Representation RequiredInputRepresentation(int index) { 1254 virtual Representation RequiredInputRepresentation(int index) {
1568 return Representation::None(); 1255 return Representation::None();
1569 } 1256 }
1570 1257
1571 Deoptimizer::BailoutType type() { return type_; } 1258 Deoptimizer::BailoutType type() { return type_; }
1572 1259
(...skipping 1900 matching lines...) Expand 10 before | Expand all | Expand 10 after
3473 } 3160 }
3474 bool IsLimitedInductionVariable() { 3161 bool IsLimitedInductionVariable() {
3475 return IsInductionVariable() && 3162 return IsInductionVariable() &&
3476 induction_variable_data_->limit() != NULL; 3163 induction_variable_data_->limit() != NULL;
3477 } 3164 }
3478 void DetectInductionVariable() { 3165 void DetectInductionVariable() {
3479 ASSERT(induction_variable_data_ == NULL); 3166 ASSERT(induction_variable_data_ == NULL);
3480 induction_variable_data_ = InductionVariableData::ExaminePhi(this); 3167 induction_variable_data_ = InductionVariableData::ExaminePhi(this);
3481 } 3168 }
3482 3169
3483 virtual void AddInformativeDefinitions();
3484
3485 virtual void PrintTo(StringStream* stream); 3170 virtual void PrintTo(StringStream* stream);
3486 3171
3487 #ifdef DEBUG 3172 #ifdef DEBUG
3488 virtual void Verify(); 3173 virtual void Verify();
3489 #endif 3174 #endif
3490 3175
3491 void InitRealUses(int id); 3176 void InitRealUses(int id);
3492 void AddNonPhiUsesFrom(HPhi* other); 3177 void AddNonPhiUsesFrom(HPhi* other);
3493 void AddIndirectUsesTo(int* use_count); 3178 void AddIndirectUsesTo(int* use_count);
3494 3179
(...skipping 30 matching lines...) Expand all
3525 virtual Opcode opcode() const { return HValue::kPhi; } 3210 virtual Opcode opcode() const { return HValue::kPhi; }
3526 3211
3527 void SimplifyConstantInputs(); 3212 void SimplifyConstantInputs();
3528 3213
3529 protected: 3214 protected:
3530 virtual void DeleteFromGraph(); 3215 virtual void DeleteFromGraph();
3531 virtual void InternalSetOperandAt(int index, HValue* value) { 3216 virtual void InternalSetOperandAt(int index, HValue* value) {
3532 inputs_[index] = value; 3217 inputs_[index] = value;
3533 } 3218 }
3534 3219
3535 virtual bool IsRelationTrueInternal(NumericRelation relation,
3536 HValue* other,
3537 int offset = 0,
3538 int scale = 0);
3539
3540 private: 3220 private:
3541 ZoneList<HValue*> inputs_; 3221 ZoneList<HValue*> inputs_;
3542 int merged_index_; 3222 int merged_index_;
3543 3223
3544 int non_phi_uses_[Representation::kNumRepresentations]; 3224 int non_phi_uses_[Representation::kNumRepresentations];
3545 int indirect_uses_[Representation::kNumRepresentations]; 3225 int indirect_uses_[Representation::kNumRepresentations];
3546 int phi_id_; 3226 int phi_id_;
3547 InductionVariableData* induction_variable_data_; 3227 InductionVariableData* induction_variable_data_;
3548 3228
3549 // TODO(titzer): we can't eliminate the receiver for generating backtraces 3229 // TODO(titzer): we can't eliminate the receiver for generating backtraces
3550 virtual bool IsDeletable() const { return !IsReceiver(); } 3230 virtual bool IsDeletable() const { return !IsReceiver(); }
3551 }; 3231 };
3552 3232
3553 3233
3554 class HInductionVariableAnnotation : public HUnaryOperation {
3555 public:
3556 static HInductionVariableAnnotation* AddToGraph(HPhi* phi,
3557 NumericRelation relation,
3558 int operand_index);
3559
3560 NumericRelation relation() { return relation_; }
3561 HValue* induction_base() { return phi_->OperandAt(operand_index_); }
3562
3563 virtual int RedefinedOperandIndex() { return 0; }
3564 virtual bool IsPurelyInformativeDefinition() { return true; }
3565 virtual Representation RequiredInputRepresentation(int index) {
3566 return representation();
3567 }
3568
3569 virtual void PrintDataTo(StringStream* stream);
3570
3571 virtual bool IsRelationTrueInternal(NumericRelation other_relation,
3572 HValue* other_related_value,
3573 int offset = 0,
3574 int scale = 0) {
3575 if (induction_base() == other_related_value) {
3576 return relation().CompoundImplies(other_relation, offset, scale);
3577 } else {
3578 return false;
3579 }
3580 }
3581
3582 DECLARE_CONCRETE_INSTRUCTION(InductionVariableAnnotation)
3583
3584 private:
3585 HInductionVariableAnnotation(HPhi* phi,
3586 NumericRelation relation,
3587 int operand_index)
3588 : HUnaryOperation(phi),
3589 phi_(phi), relation_(relation), operand_index_(operand_index) {
3590 }
3591
3592 // We need to store the phi both here and in the instruction operand because
3593 // the operand can change if a new idef of the phi is added between the phi
3594 // and this instruction (inserting an idef updates every use).
3595 HPhi* phi_;
3596 NumericRelation relation_;
3597 int operand_index_;
3598 };
3599
3600
3601 class HArgumentsObject: public HTemplateInstruction<0> { 3234 class HArgumentsObject: public HTemplateInstruction<0> {
3602 public: 3235 public:
3603 static HArgumentsObject* New(Zone* zone, 3236 static HArgumentsObject* New(Zone* zone,
3604 HValue* context, 3237 HValue* context,
3605 int count) { 3238 int count) {
3606 return new(zone) HArgumentsObject(count, zone); 3239 return new(zone) HArgumentsObject(count, zone);
3607 } 3240 }
3608 3241
3609 const ZoneList<HValue*>* arguments_values() const { return &values_; } 3242 const ZoneList<HValue*>* arguments_values() const { return &values_; }
3610 int arguments_count() const { return values_.length(); } 3243 int arguments_count() const { return values_.length(); }
(...skipping 497 matching lines...) Expand 10 before | Expand all | Expand 10 after
4108 class HBoundsCheck: public HTemplateInstruction<2> { 3741 class HBoundsCheck: public HTemplateInstruction<2> {
4109 public: 3742 public:
4110 DECLARE_INSTRUCTION_FACTORY_P2(HBoundsCheck, HValue*, HValue*); 3743 DECLARE_INSTRUCTION_FACTORY_P2(HBoundsCheck, HValue*, HValue*);
4111 3744
4112 bool skip_check() const { return skip_check_; } 3745 bool skip_check() const { return skip_check_; }
4113 void set_skip_check() { skip_check_ = true; } 3746 void set_skip_check() { skip_check_ = true; }
4114 3747
4115 HValue* base() { return base_; } 3748 HValue* base() { return base_; }
4116 int offset() { return offset_; } 3749 int offset() { return offset_; }
4117 int scale() { return scale_; } 3750 int scale() { return scale_; }
4118 bool index_can_increase() {
4119 return (responsibility_direction_ & DIRECTION_LOWER) == 0;
4120 }
4121 bool index_can_decrease() {
4122 return (responsibility_direction_ & DIRECTION_UPPER) == 0;
4123 }
4124 3751
4125 void ApplyIndexChange(); 3752 void ApplyIndexChange();
4126 bool DetectCompoundIndex() { 3753 bool DetectCompoundIndex() {
4127 ASSERT(base() == NULL); 3754 ASSERT(base() == NULL);
4128 3755
4129 DecompositionResult decomposition; 3756 DecompositionResult decomposition;
4130 if (index()->TryDecompose(&decomposition)) { 3757 if (index()->TryDecompose(&decomposition)) {
4131 base_ = decomposition.base(); 3758 base_ = decomposition.base();
4132 offset_ = decomposition.offset(); 3759 offset_ = decomposition.offset();
4133 scale_ = decomposition.scale(); 3760 scale_ = decomposition.scale();
4134 return true; 3761 return true;
4135 } else { 3762 } else {
4136 base_ = index(); 3763 base_ = index();
4137 offset_ = 0; 3764 offset_ = 0;
4138 scale_ = 0; 3765 scale_ = 0;
4139 return false; 3766 return false;
4140 } 3767 }
4141 } 3768 }
4142 3769
4143 virtual Representation RequiredInputRepresentation(int arg_index) { 3770 virtual Representation RequiredInputRepresentation(int arg_index) {
4144 return representation(); 3771 return representation();
4145 } 3772 }
4146 3773
4147 virtual bool IsRelationTrueInternal(NumericRelation relation,
4148 HValue* related_value,
4149 int offset = 0,
4150 int scale = 0);
4151
4152 virtual void PrintDataTo(StringStream* stream); 3774 virtual void PrintDataTo(StringStream* stream);
4153 virtual void InferRepresentation(HInferRepresentationPhase* h_infer); 3775 virtual void InferRepresentation(HInferRepresentationPhase* h_infer);
4154 3776
4155 HValue* index() { return OperandAt(0); } 3777 HValue* index() { return OperandAt(0); }
4156 HValue* length() { return OperandAt(1); } 3778 HValue* length() { return OperandAt(1); }
4157 bool allow_equality() { return allow_equality_; } 3779 bool allow_equality() { return allow_equality_; }
4158 void set_allow_equality(bool v) { allow_equality_ = v; } 3780 void set_allow_equality(bool v) { allow_equality_ = v; }
4159 3781
4160 virtual int RedefinedOperandIndex() { return 0; } 3782 virtual int RedefinedOperandIndex() { return 0; }
4161 virtual bool IsPurelyInformativeDefinition() { return skip_check(); } 3783 virtual bool IsPurelyInformativeDefinition() { return skip_check(); }
4162 virtual void AddInformativeDefinitions();
4163 3784
4164 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck) 3785 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck)
4165 3786
4166 protected: 3787 protected:
4167 friend class HBoundsCheckBaseIndexInformation; 3788 friend class HBoundsCheckBaseIndexInformation;
4168 3789
4169 virtual void SetResponsibilityForRange(RangeGuaranteeDirection direction) {
4170 responsibility_direction_ = static_cast<RangeGuaranteeDirection>(
4171 responsibility_direction_ | direction);
4172 }
4173
4174 virtual bool DataEquals(HValue* other) { return true; } 3790 virtual bool DataEquals(HValue* other) { return true; }
4175 virtual void TryGuaranteeRangeChanging(RangeEvaluationContext* context);
4176 bool skip_check_; 3791 bool skip_check_;
4177 HValue* base_; 3792 HValue* base_;
4178 int offset_; 3793 int offset_;
4179 int scale_; 3794 int scale_;
4180 RangeGuaranteeDirection responsibility_direction_;
4181 bool allow_equality_; 3795 bool allow_equality_;
4182 3796
4183 private: 3797 private:
4184 // Normally HBoundsCheck should be created using the 3798 // Normally HBoundsCheck should be created using the
4185 // HGraphBuilder::AddBoundsCheck() helper. 3799 // HGraphBuilder::AddBoundsCheck() helper.
4186 // However when building stubs, where we know that the arguments are Int32, 3800 // However when building stubs, where we know that the arguments are Int32,
4187 // it makes sense to invoke this constructor directly. 3801 // it makes sense to invoke this constructor directly.
4188 HBoundsCheck(HValue* index, HValue* length) 3802 HBoundsCheck(HValue* index, HValue* length)
4189 : skip_check_(false), 3803 : skip_check_(false),
4190 base_(NULL), offset_(0), scale_(0), 3804 base_(NULL), offset_(0), scale_(0),
4191 responsibility_direction_(DIRECTION_NONE),
4192 allow_equality_(false) { 3805 allow_equality_(false) {
4193 SetOperandAt(0, index); 3806 SetOperandAt(0, index);
4194 SetOperandAt(1, length); 3807 SetOperandAt(1, length);
4195 SetFlag(kFlexibleRepresentation); 3808 SetFlag(kFlexibleRepresentation);
4196 SetFlag(kUseGVN); 3809 SetFlag(kUseGVN);
4197 } 3810 }
4198 3811
4199 virtual bool IsDeletable() const { 3812 virtual bool IsDeletable() const {
4200 return skip_check() && !FLAG_debug_code; 3813 return skip_check() && !FLAG_debug_code;
4201 } 3814 }
(...skipping 14 matching lines...) Expand all
4216 3829
4217 HValue* base_index() { return OperandAt(0); } 3830 HValue* base_index() { return OperandAt(0); }
4218 HBoundsCheck* bounds_check() { return HBoundsCheck::cast(OperandAt(1)); } 3831 HBoundsCheck* bounds_check() { return HBoundsCheck::cast(OperandAt(1)); }
4219 3832
4220 DECLARE_CONCRETE_INSTRUCTION(BoundsCheckBaseIndexInformation) 3833 DECLARE_CONCRETE_INSTRUCTION(BoundsCheckBaseIndexInformation)
4221 3834
4222 virtual Representation RequiredInputRepresentation(int arg_index) { 3835 virtual Representation RequiredInputRepresentation(int arg_index) {
4223 return representation(); 3836 return representation();
4224 } 3837 }
4225 3838
4226 virtual bool IsRelationTrueInternal(NumericRelation relation,
4227 HValue* related_value,
4228 int offset = 0,
4229 int scale = 0);
4230 virtual void PrintDataTo(StringStream* stream); 3839 virtual void PrintDataTo(StringStream* stream);
4231 3840
4232 virtual int RedefinedOperandIndex() { return 0; } 3841 virtual int RedefinedOperandIndex() { return 0; }
4233 virtual bool IsPurelyInformativeDefinition() { return true; } 3842 virtual bool IsPurelyInformativeDefinition() { return true; }
4234
4235 protected:
4236 virtual void SetResponsibilityForRange(RangeGuaranteeDirection direction) {
4237 bounds_check()->SetResponsibilityForRange(direction);
4238 }
4239 virtual void TryGuaranteeRangeChanging(RangeEvaluationContext* context) {
4240 bounds_check()->TryGuaranteeRangeChanging(context);
4241 }
4242 }; 3843 };
4243 3844
4244 3845
4245 class HBitwiseBinaryOperation: public HBinaryOperation { 3846 class HBitwiseBinaryOperation: public HBinaryOperation {
4246 public: 3847 public:
4247 HBitwiseBinaryOperation(HValue* context, HValue* left, HValue* right, 3848 HBitwiseBinaryOperation(HValue* context, HValue* left, HValue* right,
4248 HType type = HType::Tagged()) 3849 HType type = HType::Tagged())
4249 : HBinaryOperation(context, left, right, type) { 3850 : HBinaryOperation(context, left, right, type) {
4250 SetFlag(kFlexibleRepresentation); 3851 SetFlag(kFlexibleRepresentation);
4251 SetFlag(kTruncatingToInt32); 3852 SetFlag(kTruncatingToInt32);
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
4404 virtual void InferRepresentation(HInferRepresentationPhase* h_infer); 4005 virtual void InferRepresentation(HInferRepresentationPhase* h_infer);
4405 4006
4406 virtual Representation RequiredInputRepresentation(int index) { 4007 virtual Representation RequiredInputRepresentation(int index) {
4407 return representation(); 4008 return representation();
4408 } 4009 }
4409 virtual Representation observed_input_representation(int index) { 4010 virtual Representation observed_input_representation(int index) {
4410 return observed_input_representation_[index]; 4011 return observed_input_representation_[index];
4411 } 4012 }
4412 virtual void PrintDataTo(StringStream* stream); 4013 virtual void PrintDataTo(StringStream* stream);
4413 4014
4414 virtual void AddInformativeDefinitions();
4415
4416 DECLARE_CONCRETE_INSTRUCTION(CompareNumericAndBranch) 4015 DECLARE_CONCRETE_INSTRUCTION(CompareNumericAndBranch)
4417 4016
4418 private: 4017 private:
4419 Representation observed_input_representation_[2]; 4018 Representation observed_input_representation_[2];
4420 Token::Value token_; 4019 Token::Value token_;
4421 }; 4020 };
4422 4021
4423 4022
4424 class HCompareObjectEqAndBranch: public HTemplateControlInstruction<2, 2> { 4023 class HCompareObjectEqAndBranch: public HTemplateControlInstruction<2, 2> {
4425 public: 4024 public:
(...skipping 2823 matching lines...) Expand 10 before | Expand all | Expand 10 after
7249 virtual bool IsDeletable() const { return true; } 6848 virtual bool IsDeletable() const { return true; }
7250 }; 6849 };
7251 6850
7252 6851
7253 #undef DECLARE_INSTRUCTION 6852 #undef DECLARE_INSTRUCTION
7254 #undef DECLARE_CONCRETE_INSTRUCTION 6853 #undef DECLARE_CONCRETE_INSTRUCTION
7255 6854
7256 } } // namespace v8::internal 6855 } } // namespace v8::internal
7257 6856
7258 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ 6857 #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