OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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_ |
OLD | NEW |