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

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

Issue 14046017: Abcd for performance check. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fixes and speedups in induction variable detection. Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 631 matching lines...) Expand 10 before | Expand all | Expand 10 after
642 || (other_relation.kind_ == LE) 642 || (other_relation.kind_ == LE)
643 || (other_relation.kind_ == NE); 643 || (other_relation.kind_ == NE);
644 case GE: return (other_relation.kind_ == GE); 644 case GE: return (other_relation.kind_ == GE);
645 case LE: return (other_relation.kind_ == LE); 645 case LE: return (other_relation.kind_ == LE);
646 case NE: return (other_relation.kind_ == NE); 646 case NE: return (other_relation.kind_ == NE);
647 } 647 }
648 UNREACHABLE(); 648 UNREACHABLE();
649 return false; 649 return false;
650 } 650 }
651 651
652 // The semantics of "ImpliedByEquality" is that if
653 // "rel.ImpliedByEquality(offset)" is true then
654 // "x == y" implies "(x + offset) rel y" .
655 bool ImpliedByEquality(int offset) {
656 switch (kind_) {
657 case NONE: return false;
658 case EQ: return (offset == 0);
659 case GT: return (offset > 0);
660 case GE: return (offset >= 0);
661 case LT: return (offset < 0);
662 case LE: return (offset <= 0);
663 case NE: return false;
664 }
665 UNREACHABLE();
666 return false;
667 }
668
652 // The semantics of "IsExtendable" is that if 669 // The semantics of "IsExtendable" is that if
653 // "rel.IsExtendable(direction)" is true then 670 // "rel.IsExtendable(direction)" is true then
654 // "x rel y" implies "(x + direction) rel y" . 671 // "x rel y" implies "(x + direction) rel y" .
655 bool IsExtendable(int direction) { 672 bool IsExtendable(int direction) {
656 switch (kind_) { 673 switch (kind_) {
657 case NONE: return false; 674 case NONE: return false;
658 case EQ: return false; 675 case EQ: return false;
659 case GT: return (direction >= 0); 676 case GT: return (direction >= 0);
660 case GE: return (direction >= 0); 677 case GE: return (direction >= 0);
661 case LT: return (direction <= 0); 678 case LT: return (direction <= 0);
662 case LE: return (direction <= 0); 679 case LE: return (direction <= 0);
663 case NE: return false; 680 case NE: return false;
664 } 681 }
665 UNREACHABLE(); 682 UNREACHABLE();
666 return false; 683 return false;
667 } 684 }
668 685
669 // CompoundImplies returns true when 686 // CompoundImplies returns true when
670 // "((x + my_offset) >> my_scale) rel y" implies 687 // "((x + my_offset) >> my_scale) rel y" implies
671 // "((x + other_offset) >> other_scale) other_relation y". 688 // "((x + other_offset) >> other_scale) other_relation y".
672 bool CompoundImplies(NumericRelation other_relation, 689 bool CompoundImplies(NumericRelation other_relation,
673 int my_offset, 690 int my_offset,
674 int my_scale, 691 int my_scale,
675 int other_offset = 0, 692 int other_offset = 0,
676 int other_scale = 0) { 693 int other_scale = 0) {
677 return Implies(other_relation) && ComponentsImply( 694 return Implies(other_relation) && ComponentsImply(
678 my_offset, my_scale, other_offset, other_scale); 695 my_offset, my_scale, other_offset, other_scale);
679 } 696 }
680 697
698 // CanBeChained returns true when
699 // "((x + offset) >> scale) rel limit" and "x other_relation y" imply
700 // "((y + offset) >> scale) rel limit".
701 // In other words, rel and other_relation go "in the same direction"
702 // and therefore can be "chained".
703 bool CanBeChained(NumericRelation other_relation) {
704 switch (kind_) {
705 case NONE: return false;
706 case EQ: return (other_relation.kind_ == EQ);
707 case GT:
708 case GE:
709 return (other_relation.kind_ == GT) || (other_relation.kind_ == GE);
710 case LT:
711 case LE:
712 return (other_relation.kind_ == LT) || (other_relation.kind_ == LE);
713 case NE: return false;
714 }
715 UNREACHABLE();
716 return false;
717 }
718
719 bool ApplyToValues(int32_t value, int32_t other_value) {
720 switch (kind_) {
721 case NONE: return false;
722 case EQ: return value == other_value;
723 case GT: return value > other_value;
724 case GE: return value >= other_value;
725 case LT: return value < other_value;
726 case LE: return value <= other_value;
727 case NE: return value != other_value;
728 }
729 UNREACHABLE();
730 return false;
731 }
732
733 int Compare(NumericRelation other) {
734 int my_value = static_cast<int>(kind_);
735 int other_value = static_cast<int>(other.kind_);
736 return my_value - other_value;
737 }
738
681 private: 739 private:
682 // ComponentsImply returns true when 740 // ComponentsImply returns true when
683 // "((x + my_offset) >> my_scale) rel y" implies 741 // "((x + my_offset) >> my_scale) rel y" implies
684 // "((x + other_offset) >> other_scale) rel y". 742 // "((x + other_offset) >> other_scale) rel y".
685 bool ComponentsImply(int my_offset, 743 bool ComponentsImply(int my_offset,
686 int my_scale, 744 int my_scale,
687 int other_offset, 745 int other_offset,
688 int other_scale) { 746 int other_scale) {
689 switch (kind_) { 747 switch (kind_) {
690 case NONE: break; // Fall through to UNREACHABLE(). 748 case NONE: break; // Fall through to UNREACHABLE().
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
745 } 803 }
746 804
747 HValue* base_; 805 HValue* base_;
748 int offset_; 806 int offset_;
749 int scale_; 807 int scale_;
750 }; 808 };
751 809
752 810
753 class RangeEvaluationContext BASE_EMBEDDED { 811 class RangeEvaluationContext BASE_EMBEDDED {
754 public: 812 public:
755 RangeEvaluationContext(HValue* value, HValue* upper); 813 RangeEvaluationContext(HValue* value,
814 HValue* upper,
815 HBasicBlock* starting_block);
756 816
817 HBasicBlock* starting_block() { return starting_block_; }
757 HValue* lower_bound() { return lower_bound_; } 818 HValue* lower_bound() { return lower_bound_; }
758 HValue* lower_bound_guarantee() { return lower_bound_guarantee_; } 819 HValue* lower_bound_guarantee() { return lower_bound_guarantee_; }
759 HValue* candidate() { return candidate_; } 820 HValue* candidate() { return candidate_; }
760 HValue* upper_bound() { return upper_bound_; } 821 HValue* upper_bound() { return upper_bound_; }
761 HValue* upper_bound_guarantee() { return upper_bound_guarantee_; } 822 HValue* upper_bound_guarantee() { return upper_bound_guarantee_; }
762 int offset() { return offset_; } 823 int offset() { return offset_; }
763 int scale() { return scale_; } 824 int scale() { return scale_; }
764 825
765 bool is_range_satisfied() { 826 bool is_range_satisfied() {
766 return lower_bound_guarantee() != NULL && upper_bound_guarantee() != NULL; 827 return lower_bound_guarantee() != NULL && upper_bound_guarantee() != NULL;
767 } 828 }
768 829
769 void set_lower_bound_guarantee(HValue* guarantee) { 830 void set_lower_bound_guarantee(HValue* guarantee) {
770 lower_bound_guarantee_ = ConvertGuarantee(guarantee); 831 lower_bound_guarantee_ = ConvertGuarantee(guarantee);
771 } 832 }
772 void set_upper_bound_guarantee(HValue* guarantee) { 833 void set_upper_bound_guarantee(HValue* guarantee) {
773 upper_bound_guarantee_ = ConvertGuarantee(guarantee); 834 upper_bound_guarantee_ = ConvertGuarantee(guarantee);
774 } 835 }
775 836
776 void swap_candidate(DecompositionResult* other_candicate) { 837 void swap_candidate(DecompositionResult* other_candicate) {
777 other_candicate->SwapValues(&candidate_, &offset_, &scale_); 838 other_candicate->SwapValues(&candidate_, &offset_, &scale_);
778 } 839 }
779 840
780 private: 841 private:
781 HValue* ConvertGuarantee(HValue* guarantee); 842 HValue* ConvertGuarantee(HValue* guarantee);
782 843
844 HBasicBlock* starting_block_;
783 HValue* lower_bound_; 845 HValue* lower_bound_;
784 HValue* lower_bound_guarantee_; 846 HValue* lower_bound_guarantee_;
785 HValue* candidate_; 847 HValue* candidate_;
786 HValue* upper_bound_; 848 HValue* upper_bound_;
787 HValue* upper_bound_guarantee_; 849 HValue* upper_bound_guarantee_;
788 int offset_; 850 int offset_;
789 int scale_; 851 int scale_;
790 }; 852 };
791 853
792 854
855 class NumericRelationTableElement {
856 public:
857 int value_id() const { return value_id_; }
858 NumericRelation relation() const { return relation_; }
859 int other_value_id() const { return other_value_id_; }
860 int offset() const { return offset_; }
861 int scale() const { return scale_; }
862 int block_id() const { return block_id_; }
863 bool result() const { return result_; }
864
865 NumericRelationTableElement(int value_id,
866 NumericRelation relation,
867 int other_value_id,
868 int offset,
869 int scale,
870 int block_id,
871 bool result) :
Jakob Kummerow 2013/05/15 12:56:35 nit: colon goes on the next line, with 4 spaces of
Massi 2013/05/21 12:49:56 Done.
872 value_id_(value_id),
873 relation_(relation),
874 other_value_id_(other_value_id),
875 offset_(offset),
876 scale_(scale),
877 block_id_(block_id),
878 result_(result) {}
879
880 NumericRelationTableElement(const NumericRelationTableElement& other) :
Jakob Kummerow 2013/05/15 12:56:35 nit: same here
Massi 2013/05/21 12:49:56 Done.
881 value_id_(other.value_id()),
882 relation_(other.relation()),
883 other_value_id_(other.other_value_id()),
884 offset_(other.offset()),
885 scale_(other.scale()),
886 block_id_(other.block_id()),
887 result_(other.result()) {}
888
889 int Compare(const NumericRelationTableElement& other) const {
890 int result = Comparator(value_id(), other.value_id());
891 if (result != 0) return result;
892 result = relation().Compare(other.relation());
893 if (result != 0) return result;
894 result = Comparator(other_value_id(), other.other_value_id());
895 if (result != 0) return result;
896 result = Comparator(offset(), other.offset());
897 if (result != 0) return result;
898 result = Comparator(block_id(), other.block_id());
899 if (result != 0) return result;
900 return Comparator(scale(), other.scale());
901 }
902
903 private:
904 static int Comparator(int value, int other_value) {
905 return value - other_value;
906 }
907
908 int value_id_;
909 NumericRelation relation_;
910 int other_value_id_;
911 int offset_;
912 int scale_;
913 int block_id_;
914 bool result_;
915 };
916
917
918 class NumericRelationTable {
919 public:
920 bool IsInTable(int value_id,
921 NumericRelation relation,
922 int other_value_id,
923 int offset,
924 int scale,
925 int block_id,
926 bool* result);
927
928 void AddToTable(int value_id,
929 NumericRelation relation,
930 int other_value_id,
931 int offset,
932 int scale,
933 int block_id,
934 bool result);
935
936 void Clear();
937
938 explicit NumericRelationTable(Zone* zone) : table_(8, zone), zone_(zone) {}
939
940 private:
941 int FindInsertionPoint(const NumericRelationTableElement& element,
942 bool* result);
943 void Insert(const NumericRelationTableElement& element, int index);
944
945 ZoneList<NumericRelationTableElement> table_;
946 Zone* zone_;
947 };
948
949
793 typedef EnumSet<GVNFlag> GVNFlagSet; 950 typedef EnumSet<GVNFlag> GVNFlagSet;
794 951
795 952
796 class HValue: public ZoneObject { 953 class HValue: public ZoneObject {
797 public: 954 public:
798 static const int kNoNumber = -1; 955 static const int kNoNumber = -1;
799 956
800 enum Flag { 957 enum Flag {
801 kFlexibleRepresentation, 958 kFlexibleRepresentation,
802 // Participate in Global Value Numbering, i.e. elimination of 959 // Participate in Global Value Numbering, i.e. elimination of
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after
1093 1250
1094 #ifdef DEBUG 1251 #ifdef DEBUG
1095 virtual void Verify() = 0; 1252 virtual void Verify() = 0;
1096 #endif 1253 #endif
1097 1254
1098 bool IsRelationTrue(NumericRelation relation, 1255 bool IsRelationTrue(NumericRelation relation,
1099 HValue* other, 1256 HValue* other,
1100 int offset = 0, 1257 int offset = 0,
1101 int scale = 0); 1258 int scale = 0);
1102 1259
1103 bool TryGuaranteeRange(HValue* upper_bound); 1260 bool TryGuaranteeRange(HValue* upper_bound,
1261 HBasicBlock* starting_block_for_hoisting = NULL);
1104 virtual bool TryDecompose(DecompositionResult* decomposition) { 1262 virtual bool TryDecompose(DecompositionResult* decomposition) {
1105 if (RedefinedOperand() != NULL) { 1263 if (RedefinedOperand() != NULL) {
1106 return RedefinedOperand()->TryDecompose(decomposition); 1264 return RedefinedOperand()->TryDecompose(decomposition);
1107 } else { 1265 } else {
1108 return false; 1266 return false;
1109 } 1267 }
1110 } 1268 }
1111 1269
1112 protected: 1270 protected:
1271 bool EvaluateRelationRecursively(NumericRelation relation,
1272 HValue* other,
1273 int offset = 0,
1274 int scale = 0);
1113 void TryGuaranteeRangeRecursive(RangeEvaluationContext* context); 1275 void TryGuaranteeRangeRecursive(RangeEvaluationContext* context);
1114 1276
1115 enum RangeGuaranteeDirection { 1277 enum RangeGuaranteeDirection {
1116 DIRECTION_NONE = 0, 1278 DIRECTION_NONE = 0,
1117 DIRECTION_UPPER = 1, 1279 DIRECTION_UPPER = 1,
1118 DIRECTION_LOWER = 2, 1280 DIRECTION_LOWER = 2,
1119 DIRECTION_BOTH = DIRECTION_UPPER | DIRECTION_LOWER 1281 DIRECTION_BOTH = DIRECTION_UPPER | DIRECTION_LOWER
1120 }; 1282 };
1121 virtual void SetResponsibilityForRange(RangeGuaranteeDirection direction) {} 1283 virtual void SetResponsibilityForRange(RangeGuaranteeDirection direction) {}
1122 virtual void TryGuaranteeRangeChanging(RangeEvaluationContext* context) {} 1284 virtual void TryGuaranteeRangeChanging(RangeEvaluationContext* context) {}
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after
1412 } 1574 }
1413 1575
1414 virtual void PrintDataTo(StringStream* stream); 1576 virtual void PrintDataTo(StringStream* stream);
1415 1577
1416 DECLARE_CONCRETE_INSTRUCTION(DummyUse); 1578 DECLARE_CONCRETE_INSTRUCTION(DummyUse);
1417 }; 1579 };
1418 1580
1419 1581
1420 class HNumericConstraint : public HTemplateInstruction<2> { 1582 class HNumericConstraint : public HTemplateInstruction<2> {
1421 public: 1583 public:
1422 static HNumericConstraint* AddToGraph(HValue* constrained_value, 1584 static HNumericConstraint* AddToGraph(
1423 NumericRelation relation, 1585 HValue* constrained_value,
1424 HValue* related_value, 1586 NumericRelation relation,
1425 HInstruction* insertion_point = NULL); 1587 HValue* related_value,
1588 HInstruction* insertion_point = NULL,
1589 HBasicBlock* jump_target_when_false = NULL);
1426 1590
1427 HValue* constrained_value() { return OperandAt(0); } 1591 HValue* constrained_value() { return OperandAt(0); }
1428 HValue* related_value() { return OperandAt(1); } 1592 HValue* related_value() { return OperandAt(1); }
1429 NumericRelation relation() { return relation_; } 1593 NumericRelation relation() { return relation_; }
1594 HBasicBlock* jump_target_when_false() { return jump_target_when_false_; }
1430 1595
1431 virtual int RedefinedOperandIndex() { return 0; } 1596 virtual int RedefinedOperandIndex() { return 0; }
1432 virtual bool IsPurelyInformativeDefinition() { return true; } 1597 virtual bool IsPurelyInformativeDefinition() { return true; }
1433 1598
1434 virtual Representation RequiredInputRepresentation(int index) { 1599 virtual Representation RequiredInputRepresentation(int index) {
1435 return representation(); 1600 return representation();
1436 } 1601 }
1437 1602
1438 virtual void PrintDataTo(StringStream* stream); 1603 virtual void PrintDataTo(StringStream* stream);
1439 1604
1440 virtual bool IsRelationTrueInternal(NumericRelation other_relation, 1605 virtual bool IsRelationTrueInternal(NumericRelation other_relation,
1441 HValue* other_related_value, 1606 HValue* other_related_value,
1442 int offset = 0, 1607 int offset = 0,
1443 int scale = 0) { 1608 int scale = 0) {
1444 if (related_value() == other_related_value) { 1609 if (related_value() == other_related_value) {
1445 return relation().CompoundImplies(other_relation, offset, scale); 1610 return relation().CompoundImplies(other_relation, offset, scale);
1446 } else { 1611 } else {
1447 return false; 1612 if (relation().CanBeChained(other_relation)) {
1613 return related_value()->IsRelationTrue(
1614 other_relation, other_related_value, offset, scale);
1615 } else {
1616 return false;
1617 }
1448 } 1618 }
1449 } 1619 }
1450 1620
1451 DECLARE_CONCRETE_INSTRUCTION(NumericConstraint) 1621 DECLARE_CONCRETE_INSTRUCTION(NumericConstraint)
1452 1622
1453 private: 1623 private:
1454 HNumericConstraint(HValue* constrained_value, 1624 HNumericConstraint(HValue* constrained_value,
1455 NumericRelation relation, 1625 NumericRelation relation,
1456 HValue* related_value) 1626 HValue* related_value,
1457 : relation_(relation) { 1627 HBasicBlock* jump_target_when_false)
1628 : relation_(relation), jump_target_when_false_(jump_target_when_false) {
1458 SetOperandAt(0, constrained_value); 1629 SetOperandAt(0, constrained_value);
1459 SetOperandAt(1, related_value); 1630 SetOperandAt(1, related_value);
1460 } 1631 }
1461 1632
1462 NumericRelation relation_; 1633 NumericRelation relation_;
1634 HBasicBlock* jump_target_when_false_;
1463 }; 1635 };
1464 1636
1465 1637
1466 // We insert soft-deoptimize when we hit code with unknown typefeedback, 1638 // We insert soft-deoptimize when we hit code with unknown typefeedback,
1467 // so that we get a chance of re-optimizing with useful typefeedback. 1639 // so that we get a chance of re-optimizing with useful typefeedback.
1468 // HSoftDeoptimize does not end a basic block as opposed to HDeoptimize. 1640 // HSoftDeoptimize does not end a basic block as opposed to HDeoptimize.
1469 class HSoftDeoptimize: public HTemplateInstruction<0> { 1641 class HSoftDeoptimize: public HTemplateInstruction<0> {
1470 public: 1642 public:
1471 virtual Representation RequiredInputRepresentation(int index) { 1643 virtual Representation RequiredInputRepresentation(int index) {
1472 return Representation::None(); 1644 return Representation::None();
(...skipping 1621 matching lines...) Expand 10 before | Expand all | Expand 10 after
3094 int merged_index_; 3266 int merged_index_;
3095 3267
3096 int non_phi_uses_[Representation::kNumRepresentations]; 3268 int non_phi_uses_[Representation::kNumRepresentations];
3097 int indirect_uses_[Representation::kNumRepresentations]; 3269 int indirect_uses_[Representation::kNumRepresentations];
3098 int phi_id_; 3270 int phi_id_;
3099 bool is_live_; 3271 bool is_live_;
3100 bool is_convertible_to_integer_; 3272 bool is_convertible_to_integer_;
3101 }; 3273 };
3102 3274
3103 3275
3276 class HBoundsCheck;
3277
3278
3104 class HInductionVariableAnnotation : public HUnaryOperation { 3279 class HInductionVariableAnnotation : public HUnaryOperation {
3105 public: 3280 public:
3106 static HInductionVariableAnnotation* AddToGraph(HPhi* phi, 3281 static HInductionVariableAnnotation* AddToGraph(HPhi* phi,
3107 NumericRelation relation, 3282 NumericRelation relation,
3108 int operand_index); 3283 int operand_index);
3109 3284
3110 NumericRelation relation() { return relation_; } 3285 NumericRelation relation() { return relation_; }
3111 HValue* induction_base() { return phi_->OperandAt(operand_index_); } 3286 HValue* induction_base() { return phi_->OperandAt(operand_index_); }
3112 3287
3113 virtual int RedefinedOperandIndex() { return 0; } 3288 virtual int RedefinedOperandIndex() { return 0; }
3114 virtual bool IsPurelyInformativeDefinition() { return true; } 3289 virtual bool IsPurelyInformativeDefinition() { return true; }
3115 virtual Representation RequiredInputRepresentation(int index) { 3290 virtual Representation RequiredInputRepresentation(int index) {
3116 return representation(); 3291 return representation();
3117 } 3292 }
3118 3293
3294 virtual void TryGuaranteeRangeChanging(RangeEvaluationContext* context);
3119 virtual void PrintDataTo(StringStream* stream); 3295 virtual void PrintDataTo(StringStream* stream);
3120 3296
3121 virtual bool IsRelationTrueInternal(NumericRelation other_relation, 3297 virtual bool IsRelationTrueInternal(NumericRelation other_relation,
3122 HValue* other_related_value, 3298 HValue* other_related_value,
3123 int offset = 0, 3299 int offset = 0,
3124 int scale = 0) { 3300 int scale = 0) {
3125 if (induction_base() == other_related_value) { 3301 if (induction_base() == other_related_value) {
3126 return relation().CompoundImplies(other_relation, offset, scale); 3302 return relation().CompoundImplies(other_relation, offset, scale);
3127 } else { 3303 } else {
3128 return false; 3304 if (relation().CanBeChained(other_relation)) {
3305 return induction_base()->IsRelationTrue(
3306 other_relation, other_related_value, offset, scale);
3307 } else {
3308 return false;
3309 }
3129 } 3310 }
3130 } 3311 }
3131 3312
3313 const ZoneList<HBoundsCheck*>* hoisted_checks() const {
3314 return &hoisted_checks_;
3315 }
3316 void AddHoistedCheck(HBoundsCheck* check);
3317
3132 DECLARE_CONCRETE_INSTRUCTION(InductionVariableAnnotation) 3318 DECLARE_CONCRETE_INSTRUCTION(InductionVariableAnnotation)
3133 3319
3134 private: 3320 private:
3135 HInductionVariableAnnotation(HPhi* phi, 3321 HInductionVariableAnnotation(HPhi* phi,
3136 NumericRelation relation, 3322 NumericRelation relation,
3137 int operand_index) 3323 int operand_index,
3138 : HUnaryOperation(phi), 3324 Zone* zone);
3139 phi_(phi), relation_(relation), operand_index_(operand_index) {
3140 }
3141 3325
3142 // We need to store the phi both here and in the instruction operand because 3326 // We need to store the phi both here and in the instruction operand because
3143 // the operand can change if a new idef of the phi is added between the phi 3327 // the operand can change if a new idef of the phi is added between the phi
3144 // and this instruction (inserting an idef updates every use). 3328 // and this instruction (inserting an idef updates every use).
3145 HPhi* phi_; 3329 HPhi* phi_;
3146 NumericRelation relation_; 3330 NumericRelation relation_;
3147 int operand_index_; 3331 int operand_index_;
3332 ZoneList<HBoundsCheck*> hoisted_checks_;
3148 }; 3333 };
3149 3334
3150 3335
3151 class HArgumentsObject: public HTemplateInstruction<0> { 3336 class HArgumentsObject: public HTemplateInstruction<0> {
3152 public: 3337 public:
3153 HArgumentsObject() { 3338 HArgumentsObject() {
3154 set_representation(Representation::Tagged()); 3339 set_representation(Representation::Tagged());
3155 SetFlag(kIsArguments); 3340 SetFlag(kIsArguments);
3156 } 3341 }
3157 3342
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
3285 bool HasInternalizedStringValue() const { 3470 bool HasInternalizedStringValue() const {
3286 return HasStringValue() && is_internalized_string_; 3471 return HasStringValue() && is_internalized_string_;
3287 } 3472 }
3288 3473
3289 bool BooleanValue() const { return boolean_value_; } 3474 bool BooleanValue() const { return boolean_value_; }
3290 3475
3291 bool IsUint32() { 3476 bool IsUint32() {
3292 return HasInteger32Value() && (Integer32Value() >= 0); 3477 return HasInteger32Value() && (Integer32Value() >= 0);
3293 } 3478 }
3294 3479
3480 virtual bool IsRelationTrueInternal(NumericRelation relation,
3481 HValue* related_value,
3482 int offset = 0,
3483 int scale = 0) {
3484 if (HasInteger32Value() &&
3485 related_value->IsInteger32Constant()) {
3486 int32_t value = (Integer32Value() + offset) >> scale;
3487 int32_t other_value = related_value->GetInteger32Constant();
3488 return relation.ApplyToValues(value, other_value);
3489 } else {
3490 return false;
3491 }
3492 }
3493
3295 virtual intptr_t Hashcode() { 3494 virtual intptr_t Hashcode() {
3296 ASSERT_ALLOCATION_DISABLED; 3495 ASSERT_ALLOCATION_DISABLED;
3297 intptr_t hash; 3496 intptr_t hash;
3298 3497
3299 if (has_int32_value_) { 3498 if (has_int32_value_) {
3300 hash = static_cast<intptr_t>(int32_value_); 3499 hash = static_cast<intptr_t>(int32_value_);
3301 } else if (has_double_value_) { 3500 } else if (has_double_value_) {
3302 hash = static_cast<intptr_t>(BitCast<int64_t>(double_value_)); 3501 hash = static_cast<intptr_t>(BitCast<int64_t>(double_value_));
3303 } else { 3502 } else {
3304 ASSERT(!handle_.is_null()); 3503 ASSERT(!handle_.is_null());
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
3568 // HGraphBuilder::AddBoundsCheck() helper, which also guards the index with 3767 // HGraphBuilder::AddBoundsCheck() helper, which also guards the index with
3569 // a HCheckSmiOrInt32 check. 3768 // a HCheckSmiOrInt32 check.
3570 // However when building stubs, where we know that the arguments are Int32, 3769 // However when building stubs, where we know that the arguments are Int32,
3571 // it makes sense to invoke this constructor directly. 3770 // it makes sense to invoke this constructor directly.
3572 HBoundsCheck(HValue* index, 3771 HBoundsCheck(HValue* index,
3573 HValue* length, 3772 HValue* length,
3574 BoundsCheckKeyMode key_mode = DONT_ALLOW_SMI_KEY, 3773 BoundsCheckKeyMode key_mode = DONT_ALLOW_SMI_KEY,
3575 Representation r = Representation::None()) 3774 Representation r = Representation::None())
3576 : key_mode_(key_mode), skip_check_(false), 3775 : key_mode_(key_mode), skip_check_(false),
3577 base_(NULL), offset_(0), scale_(0), 3776 base_(NULL), offset_(0), scale_(0),
3578 responsibility_direction_(DIRECTION_NONE) { 3777 responsibility_direction_(DIRECTION_NONE),
3778 allow_equality_(false) {
3579 SetOperandAt(0, index); 3779 SetOperandAt(0, index);
3580 SetOperandAt(1, length); 3780 SetOperandAt(1, length);
3581 if (r.IsNone()) { 3781 if (r.IsNone()) {
3582 // In the normal compilation pipeline the representation is flexible 3782 // In the normal compilation pipeline the representation is flexible
3583 // (see InferRepresentation). 3783 // (see InferRepresentation).
3584 SetFlag(kFlexibleRepresentation); 3784 SetFlag(kFlexibleRepresentation);
3585 } else { 3785 } else {
3586 // When compiling stubs we want to set the representation explicitly 3786 // When compiling stubs we want to set the representation explicitly
3587 // so the compilation pipeline can skip the HInferRepresentation phase. 3787 // so the compilation pipeline can skip the HInferRepresentation phase.
3588 set_representation(r); 3788 set_representation(r);
3589 } 3789 }
3590 SetFlag(kUseGVN); 3790 SetFlag(kUseGVN);
3591 } 3791 }
3592 3792
3593 bool skip_check() { return skip_check_; } 3793 bool skip_check() const { return skip_check_; }
3594 void set_skip_check(bool skip_check) { skip_check_ = skip_check; } 3794 void set_skip_check() {
3795 isolate()->counters()->bounds_checks_removed()->Increment();
3796 skip_check_ = true;
3797 }
3595 HValue* base() { return base_; } 3798 HValue* base() { return base_; }
3596 int offset() { return offset_; } 3799 int offset() { return offset_; }
3597 int scale() { return scale_; } 3800 int scale() { return scale_; }
3598 bool index_can_increase() { 3801 bool index_can_increase() {
3599 return (responsibility_direction_ & DIRECTION_LOWER) == 0; 3802 return (responsibility_direction_ & DIRECTION_LOWER) == 0;
3600 } 3803 }
3601 bool index_can_decrease() { 3804 bool index_can_decrease() {
3602 return (responsibility_direction_ & DIRECTION_UPPER) == 0; 3805 return (responsibility_direction_ & DIRECTION_UPPER) == 0;
3603 } 3806 }
3604 3807
(...skipping 14 matching lines...) Expand all
3619 return false; 3822 return false;
3620 } 3823 }
3621 } 3824 }
3622 3825
3623 virtual Representation RequiredInputRepresentation(int arg_index) { 3826 virtual Representation RequiredInputRepresentation(int arg_index) {
3624 return representation(); 3827 return representation();
3625 } 3828 }
3626 virtual Representation observed_input_representation(int index) { 3829 virtual Representation observed_input_representation(int index) {
3627 return Representation::Integer32(); 3830 return Representation::Integer32();
3628 } 3831 }
3832 virtual bool IsDeletable() const {
3833 return skip_check();
3834 }
3629 3835
3630 virtual bool IsRelationTrueInternal(NumericRelation relation, 3836 virtual bool IsRelationTrueInternal(NumericRelation relation,
3631 HValue* related_value, 3837 HValue* related_value,
3632 int offset = 0, 3838 int offset = 0,
3633 int scale = 0); 3839 int scale = 0);
3634 3840
3635 virtual void PrintDataTo(StringStream* stream); 3841 virtual void PrintDataTo(StringStream* stream);
3636 virtual void InferRepresentation(HInferRepresentation* h_infer); 3842 virtual void InferRepresentation(HInferRepresentation* h_infer);
3637 3843
3638 HValue* index() { return OperandAt(0); } 3844 HValue* index() { return OperandAt(0); }
3639 HValue* length() { return OperandAt(1); } 3845 HValue* length() { return OperandAt(1); }
3846 bool allow_equality() { return allow_equality_; }
3847 void set_allow_equality(bool v) { allow_equality_ = v; }
3640 3848
3641 virtual int RedefinedOperandIndex() { return 0; } 3849 virtual int RedefinedOperandIndex() { return 0; }
3642 virtual bool IsPurelyInformativeDefinition() { return skip_check(); } 3850 virtual bool IsPurelyInformativeDefinition() { return skip_check(); }
3643 virtual void AddInformativeDefinitions(); 3851 virtual void AddInformativeDefinitions();
3644 3852
3645 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck) 3853 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck)
3646 3854
3647 protected: 3855 protected:
3648 friend class HBoundsCheckBaseIndexInformation; 3856 friend class HBoundsCheckBaseIndexInformation;
3649 3857
3650 virtual void SetResponsibilityForRange(RangeGuaranteeDirection direction) { 3858 virtual void SetResponsibilityForRange(RangeGuaranteeDirection direction) {
3651 responsibility_direction_ = static_cast<RangeGuaranteeDirection>( 3859 responsibility_direction_ = static_cast<RangeGuaranteeDirection>(
3652 responsibility_direction_ | direction); 3860 responsibility_direction_ | direction);
3653 } 3861 }
3654 3862
3655 virtual bool DataEquals(HValue* other) { return true; } 3863 virtual bool DataEquals(HValue* other) { return true; }
3656 virtual void TryGuaranteeRangeChanging(RangeEvaluationContext* context); 3864 virtual void TryGuaranteeRangeChanging(RangeEvaluationContext* context);
3657 BoundsCheckKeyMode key_mode_; 3865 BoundsCheckKeyMode key_mode_;
3658 bool skip_check_; 3866 bool skip_check_;
3659 HValue* base_; 3867 HValue* base_;
3660 int offset_; 3868 int offset_;
3661 int scale_; 3869 int scale_;
3662 RangeGuaranteeDirection responsibility_direction_; 3870 RangeGuaranteeDirection responsibility_direction_;
3871 bool allow_equality_;
3663 }; 3872 };
3664 3873
3665 3874
3666 class HBoundsCheckBaseIndexInformation: public HTemplateInstruction<2> { 3875 class HBoundsCheckBaseIndexInformation: public HTemplateInstruction<2> {
3667 public: 3876 public:
3668 explicit HBoundsCheckBaseIndexInformation(HBoundsCheck* check) { 3877 explicit HBoundsCheckBaseIndexInformation(HBoundsCheck* check) {
3669 DecompositionResult decomposition; 3878 DecompositionResult decomposition;
3670 if (check->index()->TryDecompose(&decomposition)) { 3879 if (check->index()->TryDecompose(&decomposition)) {
3671 SetOperandAt(0, decomposition.base()); 3880 SetOperandAt(0, decomposition.base());
3672 SetOperandAt(1, check); 3881 SetOperandAt(1, check);
3673 } else { 3882 } else {
3674 UNREACHABLE(); 3883 UNREACHABLE();
3675 } 3884 }
3676 } 3885 }
3677 3886
3678 HValue* base_index() { return OperandAt(0); } 3887 HValue* base_index() { return OperandAt(0); }
3679 HBoundsCheck* bounds_check() { return HBoundsCheck::cast(OperandAt(1)); } 3888 HBoundsCheck* bounds_check() {
3889 return OperandAt(1)->IsBoundsCheck()
3890 ? HBoundsCheck::cast(OperandAt(1)) : NULL;
3891 }
3680 3892
3681 DECLARE_CONCRETE_INSTRUCTION(BoundsCheckBaseIndexInformation) 3893 DECLARE_CONCRETE_INSTRUCTION(BoundsCheckBaseIndexInformation)
3682 3894
3683 virtual Representation RequiredInputRepresentation(int arg_index) { 3895 virtual Representation RequiredInputRepresentation(int arg_index) {
3684 return representation(); 3896 return representation();
3685 } 3897 }
3686 3898
3687 virtual bool IsRelationTrueInternal(NumericRelation relation, 3899 virtual bool IsRelationTrueInternal(NumericRelation relation,
3688 HValue* related_value, 3900 HValue* related_value,
3689 int offset = 0, 3901 int offset = 0,
(...skipping 607 matching lines...) Expand 10 before | Expand all | Expand 10 after
4297 decomposition->Apply(right(), left()->GetInteger32Constant()); 4509 decomposition->Apply(right(), left()->GetInteger32Constant());
4298 return true; 4510 return true;
4299 } else if (right()->IsInteger32Constant()) { 4511 } else if (right()->IsInteger32Constant()) {
4300 decomposition->Apply(left(), right()->GetInteger32Constant()); 4512 decomposition->Apply(left(), right()->GetInteger32Constant());
4301 return true; 4513 return true;
4302 } else { 4514 } else {
4303 return false; 4515 return false;
4304 } 4516 }
4305 } 4517 }
4306 4518
4519 virtual bool IsRelationTrueInternal(NumericRelation relation,
4520 HValue* other,
4521 int offset = 0,
4522 int scale = 0);
4523
4307 DECLARE_CONCRETE_INSTRUCTION(Add) 4524 DECLARE_CONCRETE_INSTRUCTION(Add)
4308 4525
4309 protected: 4526 protected:
4310 virtual bool DataEquals(HValue* other) { return true; } 4527 virtual bool DataEquals(HValue* other) { return true; }
4311 4528
4312 virtual Range* InferRange(Zone* zone); 4529 virtual Range* InferRange(Zone* zone);
4313 4530
4314 private: 4531 private:
4315 HAdd(HValue* context, HValue* left, HValue* right) 4532 HAdd(HValue* context, HValue* left, HValue* right)
4316 : HArithmeticBinaryOperation(context, left, right) { 4533 : HArithmeticBinaryOperation(context, left, right) {
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
4541 }; 4758 };
4542 4759
4543 4760
4544 class HShl: public HBitwiseBinaryOperation { 4761 class HShl: public HBitwiseBinaryOperation {
4545 public: 4762 public:
4546 static HInstruction* New(Zone* zone, 4763 static HInstruction* New(Zone* zone,
4547 HValue* context, 4764 HValue* context,
4548 HValue* left, 4765 HValue* left,
4549 HValue* right); 4766 HValue* right);
4550 4767
4768 virtual bool TryDecompose(DecompositionResult* decomposition) {
4769 if (right()->IsInteger32Constant() &&
4770 right()->GetInteger32Constant() <= 1 &&
4771 right()->GetInteger32Constant() >= 0) {
4772 if (decomposition->Apply(left(), 0, - right()->GetInteger32Constant())) {
4773 // This is intended to look for HAdd and HSub, to handle compounds
4774 // like ((base + offset) << scale) with one single decomposition.
4775 left()->TryDecompose(decomposition);
4776 return true;
4777 }
4778 }
4779 return false;
4780 }
4781
4551 virtual Range* InferRange(Zone* zone); 4782 virtual Range* InferRange(Zone* zone);
4552 4783
4553 DECLARE_CONCRETE_INSTRUCTION(Shl) 4784 DECLARE_CONCRETE_INSTRUCTION(Shl)
4554 4785
4555 protected: 4786 protected:
4556 virtual bool DataEquals(HValue* other) { return true; } 4787 virtual bool DataEquals(HValue* other) { return true; }
4557 4788
4558 private: 4789 private:
4559 HShl(HValue* context, HValue* left, HValue* right) 4790 HShl(HValue* context, HValue* left, HValue* right)
4560 : HBitwiseBinaryOperation(context, left, right) { } 4791 : HBitwiseBinaryOperation(context, left, right) { }
4561 }; 4792 };
4562 4793
4563 4794
4564 class HShr: public HBitwiseBinaryOperation { 4795 class HShr: public HBitwiseBinaryOperation {
4565 public: 4796 public:
4566 static HInstruction* New(Zone* zone, 4797 static HInstruction* New(Zone* zone,
4567 HValue* context, 4798 HValue* context,
4568 HValue* left, 4799 HValue* left,
4569 HValue* right); 4800 HValue* right);
4570 4801
4571 virtual bool TryDecompose(DecompositionResult* decomposition) { 4802 virtual bool TryDecompose(DecompositionResult* decomposition) {
4572 if (right()->IsInteger32Constant()) { 4803 if (right()->IsInteger32Constant() &&
4804 right()->GetInteger32Constant() >= 0) {
4573 if (decomposition->Apply(left(), 0, right()->GetInteger32Constant())) { 4805 if (decomposition->Apply(left(), 0, right()->GetInteger32Constant())) {
4574 // This is intended to look for HAdd and HSub, to handle compounds 4806 // This is intended to look for HAdd and HSub, to handle compounds
4575 // like ((base + offset) >> scale) with one single decomposition. 4807 // like ((base + offset) >> scale) with one single decomposition.
4576 left()->TryDecompose(decomposition); 4808 left()->TryDecompose(decomposition);
4577 return true; 4809 return true;
4578 } 4810 }
4579 } 4811 }
4580 return false; 4812 return false;
4581 } 4813 }
4582 4814
(...skipping 11 matching lines...) Expand all
4594 4826
4595 4827
4596 class HSar: public HBitwiseBinaryOperation { 4828 class HSar: public HBitwiseBinaryOperation {
4597 public: 4829 public:
4598 static HInstruction* New(Zone* zone, 4830 static HInstruction* New(Zone* zone,
4599 HValue* context, 4831 HValue* context,
4600 HValue* left, 4832 HValue* left,
4601 HValue* right); 4833 HValue* right);
4602 4834
4603 virtual bool TryDecompose(DecompositionResult* decomposition) { 4835 virtual bool TryDecompose(DecompositionResult* decomposition) {
4604 if (right()->IsInteger32Constant()) { 4836 if (right()->IsInteger32Constant() &&
4837 right()->GetInteger32Constant() >= 0) {
4605 if (decomposition->Apply(left(), 0, right()->GetInteger32Constant())) { 4838 if (decomposition->Apply(left(), 0, right()->GetInteger32Constant())) {
4606 // This is intended to look for HAdd and HSub, to handle compounds 4839 // This is intended to look for HAdd and HSub, to handle compounds
4607 // like ((base + offset) >> scale) with one single decomposition. 4840 // like ((base + offset) >> scale) with one single decomposition.
4608 left()->TryDecompose(decomposition); 4841 left()->TryDecompose(decomposition);
4609 return true; 4842 return true;
4610 } 4843 }
4611 } 4844 }
4612 return false; 4845 return false;
4613 } 4846 }
4614 4847
(...skipping 1817 matching lines...) Expand 10 before | Expand all | Expand 10 after
6432 virtual bool IsDeletable() const { return true; } 6665 virtual bool IsDeletable() const { return true; }
6433 }; 6666 };
6434 6667
6435 6668
6436 #undef DECLARE_INSTRUCTION 6669 #undef DECLARE_INSTRUCTION
6437 #undef DECLARE_CONCRETE_INSTRUCTION 6670 #undef DECLARE_CONCRETE_INSTRUCTION
6438 6671
6439 } } // namespace v8::internal 6672 } } // namespace v8::internal
6440 6673
6441 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ 6674 #endif // V8_HYDROGEN_INSTRUCTIONS_H_
OLDNEW
« no previous file with comments | « src/hydrogen.cc ('k') | src/hydrogen-instructions.cc » ('j') | src/hydrogen-instructions.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698