Chromium Code Reviews| 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 631 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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_ |
| OLD | NEW |