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

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: Rebased on bleeding edge. 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
« no previous file with comments | « src/hydrogen.cc ('k') | src/hydrogen-instructions.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 611 matching lines...) Expand 10 before | Expand all | Expand 10 after
622 || (other_relation.kind_ == LE) 622 || (other_relation.kind_ == LE)
623 || (other_relation.kind_ == NE); 623 || (other_relation.kind_ == NE);
624 case GE: return (other_relation.kind_ == GE); 624 case GE: return (other_relation.kind_ == GE);
625 case LE: return (other_relation.kind_ == LE); 625 case LE: return (other_relation.kind_ == LE);
626 case NE: return (other_relation.kind_ == NE); 626 case NE: return (other_relation.kind_ == NE);
627 } 627 }
628 UNREACHABLE(); 628 UNREACHABLE();
629 return false; 629 return false;
630 } 630 }
631 631
632 // The semantics of "ImpliedByEquality" is that if
633 // "rel.ImpliedByEquality(offset)" is true then
634 // "x == y" implies "(x + offset) rel y" .
635 bool ImpliedByEquality(int offset) {
636 switch (kind_) {
637 case NONE: return false;
638 case EQ: return (offset == 0);
639 case GT: return (offset > 0);
640 case GE: return (offset >= 0);
641 case LT: return (offset < 0);
642 case LE: return (offset <= 0);
643 case NE: return false;
644 }
645 UNREACHABLE();
646 return false;
647 }
648
632 // The semantics of "IsExtendable" is that if 649 // The semantics of "IsExtendable" is that if
633 // "rel.IsExtendable(direction)" is true then 650 // "rel.IsExtendable(direction)" is true then
634 // "x rel y" implies "(x + direction) rel y" . 651 // "x rel y" implies "(x + direction) rel y" .
635 bool IsExtendable(int direction) { 652 bool IsExtendable(int direction) {
636 switch (kind_) { 653 switch (kind_) {
637 case NONE: return false; 654 case NONE: return false;
638 case EQ: return false; 655 case EQ: return false;
639 case GT: return (direction >= 0); 656 case GT: return (direction >= 0);
640 case GE: return (direction >= 0); 657 case GE: return (direction >= 0);
641 case LT: return (direction <= 0); 658 case LT: return (direction <= 0);
642 case LE: return (direction <= 0); 659 case LE: return (direction <= 0);
643 case NE: return false; 660 case NE: return false;
644 } 661 }
645 UNREACHABLE(); 662 UNREACHABLE();
646 return false; 663 return false;
647 } 664 }
648 665
649 // CompoundImplies returns true when 666 // CompoundImplies returns true when
650 // "((x + my_offset) >> my_scale) rel y" implies 667 // "((x + my_offset) >> my_scale) rel y" implies
651 // "((x + other_offset) >> other_scale) other_relation y". 668 // "((x + other_offset) >> other_scale) other_relation y".
652 bool CompoundImplies(NumericRelation other_relation, 669 bool CompoundImplies(NumericRelation other_relation,
653 int my_offset, 670 int my_offset,
654 int my_scale, 671 int my_scale,
655 int other_offset = 0, 672 int other_offset = 0,
656 int other_scale = 0) { 673 int other_scale = 0) {
657 return Implies(other_relation) && ComponentsImply( 674 return Implies(other_relation) && ComponentsImply(
658 my_offset, my_scale, other_offset, other_scale); 675 my_offset, my_scale, other_offset, other_scale);
659 } 676 }
660 677
678 // CanBeChained returns true when
679 // "((x + offset) >> scale) rel limit" and "x other_relation y" imply
680 // "((y + offset) >> scale) rel limit".
681 // In other words, rel and other_relation go "in the same direction"
682 // and therefore can be "chained".
683 bool CanBeChained(NumericRelation other_relation) {
684 switch (kind_) {
685 case NONE: return false;
686 case EQ: return (other_relation.kind_ == EQ);
687 case GT:
688 case GE:
689 return (other_relation.kind_ == GT) || (other_relation.kind_ == GE);
690 case LT:
691 case LE:
692 return (other_relation.kind_ == LT) || (other_relation.kind_ == LE);
693 case NE: return false;
694 }
695 UNREACHABLE();
696 return false;
697 }
698
699 bool ApplyToValues(int32_t value, int32_t other_value) {
700 switch (kind_) {
701 case NONE: return false;
702 case EQ: return value == other_value;
703 case GT: return value > other_value;
704 case GE: return value >= other_value;
705 case LT: return value < other_value;
706 case LE: return value <= other_value;
707 case NE: return value != other_value;
708 }
709 UNREACHABLE();
710 return false;
711 }
712
713 int Compare(NumericRelation other) {
714 int my_value = static_cast<int>(kind_);
715 int other_value = static_cast<int>(other.kind_);
716 return my_value - other_value;
717 }
718
661 private: 719 private:
662 // ComponentsImply returns true when 720 // ComponentsImply returns true when
663 // "((x + my_offset) >> my_scale) rel y" implies 721 // "((x + my_offset) >> my_scale) rel y" implies
664 // "((x + other_offset) >> other_scale) rel y". 722 // "((x + other_offset) >> other_scale) rel y".
665 bool ComponentsImply(int my_offset, 723 bool ComponentsImply(int my_offset,
666 int my_scale, 724 int my_scale,
667 int other_offset, 725 int other_offset,
668 int other_scale) { 726 int other_scale) {
669 switch (kind_) { 727 switch (kind_) {
670 case NONE: break; // Fall through to UNREACHABLE(). 728 case NONE: break; // Fall through to UNREACHABLE().
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
725 } 783 }
726 784
727 HValue* base_; 785 HValue* base_;
728 int offset_; 786 int offset_;
729 int scale_; 787 int scale_;
730 }; 788 };
731 789
732 790
733 class RangeEvaluationContext BASE_EMBEDDED { 791 class RangeEvaluationContext BASE_EMBEDDED {
734 public: 792 public:
735 RangeEvaluationContext(HValue* value, HValue* upper); 793 RangeEvaluationContext(HValue* value,
794 HValue* upper,
795 HBasicBlock* starting_block);
736 796
797 HBasicBlock* starting_block() { return starting_block_; }
737 HValue* lower_bound() { return lower_bound_; } 798 HValue* lower_bound() { return lower_bound_; }
738 HValue* lower_bound_guarantee() { return lower_bound_guarantee_; } 799 HValue* lower_bound_guarantee() { return lower_bound_guarantee_; }
739 HValue* candidate() { return candidate_; } 800 HValue* candidate() { return candidate_; }
740 HValue* upper_bound() { return upper_bound_; } 801 HValue* upper_bound() { return upper_bound_; }
741 HValue* upper_bound_guarantee() { return upper_bound_guarantee_; } 802 HValue* upper_bound_guarantee() { return upper_bound_guarantee_; }
742 int offset() { return offset_; } 803 int offset() { return offset_; }
743 int scale() { return scale_; } 804 int scale() { return scale_; }
744 805
745 bool is_range_satisfied() { 806 bool is_range_satisfied() {
746 return lower_bound_guarantee() != NULL && upper_bound_guarantee() != NULL; 807 return lower_bound_guarantee() != NULL && upper_bound_guarantee() != NULL;
747 } 808 }
748 809
749 void set_lower_bound_guarantee(HValue* guarantee) { 810 void set_lower_bound_guarantee(HValue* guarantee) {
750 lower_bound_guarantee_ = ConvertGuarantee(guarantee); 811 lower_bound_guarantee_ = ConvertGuarantee(guarantee);
751 } 812 }
752 void set_upper_bound_guarantee(HValue* guarantee) { 813 void set_upper_bound_guarantee(HValue* guarantee) {
753 upper_bound_guarantee_ = ConvertGuarantee(guarantee); 814 upper_bound_guarantee_ = ConvertGuarantee(guarantee);
754 } 815 }
755 816
756 void swap_candidate(DecompositionResult* other_candicate) { 817 void swap_candidate(DecompositionResult* other_candicate) {
757 other_candicate->SwapValues(&candidate_, &offset_, &scale_); 818 other_candicate->SwapValues(&candidate_, &offset_, &scale_);
758 } 819 }
759 820
760 private: 821 private:
761 HValue* ConvertGuarantee(HValue* guarantee); 822 HValue* ConvertGuarantee(HValue* guarantee);
762 823
824 HBasicBlock* starting_block_;
763 HValue* lower_bound_; 825 HValue* lower_bound_;
764 HValue* lower_bound_guarantee_; 826 HValue* lower_bound_guarantee_;
765 HValue* candidate_; 827 HValue* candidate_;
766 HValue* upper_bound_; 828 HValue* upper_bound_;
767 HValue* upper_bound_guarantee_; 829 HValue* upper_bound_guarantee_;
768 int offset_; 830 int offset_;
769 int scale_; 831 int scale_;
770 }; 832 };
771 833
772 834
835 class NumericRelationTableElement {
836 public:
837 int value_id() const { return value_id_; }
838 NumericRelation relation() const { return relation_; }
839 int other_value_id() const { return other_value_id_; }
840 int offset() const { return offset_; }
841 int scale() const { return scale_; }
842 int block_id() const { return block_id_; }
843 bool result() const { return result_; }
844
845 NumericRelationTableElement(int value_id,
846 NumericRelation relation,
847 int other_value_id,
848 int offset,
849 int scale,
850 int block_id,
851 bool result)
852 : value_id_(value_id),
853 relation_(relation),
854 other_value_id_(other_value_id),
855 offset_(offset),
856 scale_(scale),
857 block_id_(block_id),
858 result_(result) {}
859
860 NumericRelationTableElement(const NumericRelationTableElement& other)
861 : value_id_(other.value_id()),
862 relation_(other.relation()),
863 other_value_id_(other.other_value_id()),
864 offset_(other.offset()),
865 scale_(other.scale()),
866 block_id_(other.block_id()),
867 result_(other.result()) {}
868
869 int Compare(const NumericRelationTableElement& other) const {
870 int result = Comparator(value_id(), other.value_id());
871 if (result != 0) return result;
872 result = relation().Compare(other.relation());
873 if (result != 0) return result;
874 result = Comparator(other_value_id(), other.other_value_id());
875 if (result != 0) return result;
876 result = Comparator(offset(), other.offset());
877 if (result != 0) return result;
878 result = Comparator(block_id(), other.block_id());
879 if (result != 0) return result;
880 return Comparator(scale(), other.scale());
881 }
882
883 private:
884 static int Comparator(int value, int other_value) {
885 return value - other_value;
886 }
887
888 int value_id_;
889 NumericRelation relation_;
890 int other_value_id_;
891 int offset_;
892 int scale_;
893 int block_id_;
894 bool result_;
895 };
896
897
898 class NumericRelationTable {
899 public:
900 bool IsInTable(int value_id,
901 NumericRelation relation,
902 int other_value_id,
903 int offset,
904 int scale,
905 int block_id,
906 bool* result);
907
908 void AddToTable(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 void Clear();
917
918 explicit NumericRelationTable(Zone* zone) : table_(8, zone), zone_(zone) {}
919
920 private:
921 int FindInsertionPoint(const NumericRelationTableElement& element,
922 bool* result);
923 void Insert(const NumericRelationTableElement& element, int index);
924
925 ZoneList<NumericRelationTableElement> table_;
926 Zone* zone_;
927 };
928
929
773 typedef EnumSet<GVNFlag> GVNFlagSet; 930 typedef EnumSet<GVNFlag> GVNFlagSet;
774 931
775 932
776 class HValue: public ZoneObject { 933 class HValue: public ZoneObject {
777 public: 934 public:
778 static const int kNoNumber = -1; 935 static const int kNoNumber = -1;
779 936
780 enum Flag { 937 enum Flag {
781 kFlexibleRepresentation, 938 kFlexibleRepresentation,
782 // Participate in Global Value Numbering, i.e. elimination of 939 // Participate in Global Value Numbering, i.e. elimination of
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after
1081 1238
1082 #ifdef DEBUG 1239 #ifdef DEBUG
1083 virtual void Verify() = 0; 1240 virtual void Verify() = 0;
1084 #endif 1241 #endif
1085 1242
1086 bool IsRelationTrue(NumericRelation relation, 1243 bool IsRelationTrue(NumericRelation relation,
1087 HValue* other, 1244 HValue* other,
1088 int offset = 0, 1245 int offset = 0,
1089 int scale = 0); 1246 int scale = 0);
1090 1247
1091 bool TryGuaranteeRange(HValue* upper_bound); 1248 bool TryGuaranteeRange(HValue* upper_bound,
1249 HBasicBlock* starting_block_for_hoisting = NULL);
1092 virtual bool TryDecompose(DecompositionResult* decomposition) { 1250 virtual bool TryDecompose(DecompositionResult* decomposition) {
1093 if (RedefinedOperand() != NULL) { 1251 if (RedefinedOperand() != NULL) {
1094 return RedefinedOperand()->TryDecompose(decomposition); 1252 return RedefinedOperand()->TryDecompose(decomposition);
1095 } else { 1253 } else {
1096 return false; 1254 return false;
1097 } 1255 }
1098 } 1256 }
1099 1257
1100 protected: 1258 protected:
1259 bool EvaluateRelationRecursively(NumericRelation relation,
1260 HValue* other,
1261 int offset = 0,
1262 int scale = 0);
1101 void TryGuaranteeRangeRecursive(RangeEvaluationContext* context); 1263 void TryGuaranteeRangeRecursive(RangeEvaluationContext* context);
1102 1264
1103 enum RangeGuaranteeDirection { 1265 enum RangeGuaranteeDirection {
1104 DIRECTION_NONE = 0, 1266 DIRECTION_NONE = 0,
1105 DIRECTION_UPPER = 1, 1267 DIRECTION_UPPER = 1,
1106 DIRECTION_LOWER = 2, 1268 DIRECTION_LOWER = 2,
1107 DIRECTION_BOTH = DIRECTION_UPPER | DIRECTION_LOWER 1269 DIRECTION_BOTH = DIRECTION_UPPER | DIRECTION_LOWER
1108 }; 1270 };
1109 virtual void SetResponsibilityForRange(RangeGuaranteeDirection direction) {} 1271 virtual void SetResponsibilityForRange(RangeGuaranteeDirection direction) {}
1110 virtual void TryGuaranteeRangeChanging(RangeEvaluationContext* context) {} 1272 virtual void TryGuaranteeRangeChanging(RangeEvaluationContext* context) {}
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after
1400 } 1562 }
1401 1563
1402 virtual void PrintDataTo(StringStream* stream); 1564 virtual void PrintDataTo(StringStream* stream);
1403 1565
1404 DECLARE_CONCRETE_INSTRUCTION(DummyUse); 1566 DECLARE_CONCRETE_INSTRUCTION(DummyUse);
1405 }; 1567 };
1406 1568
1407 1569
1408 class HNumericConstraint : public HTemplateInstruction<2> { 1570 class HNumericConstraint : public HTemplateInstruction<2> {
1409 public: 1571 public:
1410 static HNumericConstraint* AddToGraph(HValue* constrained_value, 1572 static HNumericConstraint* AddToGraph(
1411 NumericRelation relation, 1573 HValue* constrained_value,
1412 HValue* related_value, 1574 NumericRelation relation,
1413 HInstruction* insertion_point = NULL); 1575 HValue* related_value,
1576 HInstruction* insertion_point = NULL,
1577 HBasicBlock* jump_target_when_false = NULL);
1414 1578
1415 HValue* constrained_value() { return OperandAt(0); } 1579 HValue* constrained_value() { return OperandAt(0); }
1416 HValue* related_value() { return OperandAt(1); } 1580 HValue* related_value() { return OperandAt(1); }
1417 NumericRelation relation() { return relation_; } 1581 NumericRelation relation() { return relation_; }
1582 HBasicBlock* jump_target_when_false() { return jump_target_when_false_; }
1418 1583
1419 virtual int RedefinedOperandIndex() { return 0; } 1584 virtual int RedefinedOperandIndex() { return 0; }
1420 virtual bool IsPurelyInformativeDefinition() { return true; } 1585 virtual bool IsPurelyInformativeDefinition() { return true; }
1421 1586
1422 virtual Representation RequiredInputRepresentation(int index) { 1587 virtual Representation RequiredInputRepresentation(int index) {
1423 return representation(); 1588 return representation();
1424 } 1589 }
1425 1590
1426 virtual void PrintDataTo(StringStream* stream); 1591 virtual void PrintDataTo(StringStream* stream);
1427 1592
1428 virtual bool IsRelationTrueInternal(NumericRelation other_relation, 1593 virtual bool IsRelationTrueInternal(NumericRelation other_relation,
1429 HValue* other_related_value, 1594 HValue* other_related_value,
1430 int offset = 0, 1595 int offset = 0,
1431 int scale = 0) { 1596 int scale = 0) {
1432 if (related_value() == other_related_value) { 1597 if (related_value() == other_related_value) {
1433 return relation().CompoundImplies(other_relation, offset, scale); 1598 return relation().CompoundImplies(other_relation, offset, scale);
1434 } else { 1599 } else {
1435 return false; 1600 if (relation().CanBeChained(other_relation)) {
1601 return related_value()->IsRelationTrue(
1602 other_relation, other_related_value, offset, scale);
1603 } else {
1604 return false;
1605 }
1436 } 1606 }
1437 } 1607 }
1438 1608
1439 DECLARE_CONCRETE_INSTRUCTION(NumericConstraint) 1609 DECLARE_CONCRETE_INSTRUCTION(NumericConstraint)
1440 1610
1441 private: 1611 private:
1442 HNumericConstraint(HValue* constrained_value, 1612 HNumericConstraint(HValue* constrained_value,
1443 NumericRelation relation, 1613 NumericRelation relation,
1444 HValue* related_value) 1614 HValue* related_value,
1445 : relation_(relation) { 1615 HBasicBlock* jump_target_when_false)
1616 : relation_(relation), jump_target_when_false_(jump_target_when_false) {
1446 SetOperandAt(0, constrained_value); 1617 SetOperandAt(0, constrained_value);
1447 SetOperandAt(1, related_value); 1618 SetOperandAt(1, related_value);
1448 } 1619 }
1449 1620
1450 NumericRelation relation_; 1621 NumericRelation relation_;
1622 HBasicBlock* jump_target_when_false_;
1451 }; 1623 };
1452 1624
1453 1625
1454 // We insert soft-deoptimize when we hit code with unknown typefeedback, 1626 // We insert soft-deoptimize when we hit code with unknown typefeedback,
1455 // so that we get a chance of re-optimizing with useful typefeedback. 1627 // so that we get a chance of re-optimizing with useful typefeedback.
1456 // HSoftDeoptimize does not end a basic block as opposed to HDeoptimize. 1628 // HSoftDeoptimize does not end a basic block as opposed to HDeoptimize.
1457 class HSoftDeoptimize: public HTemplateInstruction<0> { 1629 class HSoftDeoptimize: public HTemplateInstruction<0> {
1458 public: 1630 public:
1459 virtual Representation RequiredInputRepresentation(int index) { 1631 virtual Representation RequiredInputRepresentation(int index) {
1460 return Representation::None(); 1632 return Representation::None();
(...skipping 1631 matching lines...) Expand 10 before | Expand all | Expand 10 after
3092 ZoneList<HValue*> inputs_; 3264 ZoneList<HValue*> inputs_;
3093 int merged_index_; 3265 int merged_index_;
3094 3266
3095 int non_phi_uses_[Representation::kNumRepresentations]; 3267 int non_phi_uses_[Representation::kNumRepresentations];
3096 int indirect_uses_[Representation::kNumRepresentations]; 3268 int indirect_uses_[Representation::kNumRepresentations];
3097 int phi_id_; 3269 int phi_id_;
3098 bool is_convertible_to_integer_; 3270 bool is_convertible_to_integer_;
3099 }; 3271 };
3100 3272
3101 3273
3274 class HBoundsCheck;
3275
3276
3102 class HInductionVariableAnnotation : public HUnaryOperation { 3277 class HInductionVariableAnnotation : public HUnaryOperation {
3103 public: 3278 public:
3104 static HInductionVariableAnnotation* AddToGraph(HPhi* phi, 3279 static HInductionVariableAnnotation* AddToGraph(HPhi* phi,
3105 NumericRelation relation, 3280 NumericRelation relation,
3106 int operand_index); 3281 int operand_index);
3107 3282
3108 NumericRelation relation() { return relation_; } 3283 NumericRelation relation() { return relation_; }
3109 HValue* induction_base() { return phi_->OperandAt(operand_index_); } 3284 HValue* induction_base() { return phi_->OperandAt(operand_index_); }
3110 3285
3111 virtual int RedefinedOperandIndex() { return 0; } 3286 virtual int RedefinedOperandIndex() { return 0; }
3112 virtual bool IsPurelyInformativeDefinition() { return true; } 3287 virtual bool IsPurelyInformativeDefinition() { return true; }
3113 virtual Representation RequiredInputRepresentation(int index) { 3288 virtual Representation RequiredInputRepresentation(int index) {
3114 return representation(); 3289 return representation();
3115 } 3290 }
3116 3291
3292 virtual void TryGuaranteeRangeChanging(RangeEvaluationContext* context);
3117 virtual void PrintDataTo(StringStream* stream); 3293 virtual void PrintDataTo(StringStream* stream);
3118 3294
3119 virtual bool IsRelationTrueInternal(NumericRelation other_relation, 3295 virtual bool IsRelationTrueInternal(NumericRelation other_relation,
3120 HValue* other_related_value, 3296 HValue* other_related_value,
3121 int offset = 0, 3297 int offset = 0,
3122 int scale = 0) { 3298 int scale = 0) {
3123 if (induction_base() == other_related_value) { 3299 if (induction_base() == other_related_value) {
3124 return relation().CompoundImplies(other_relation, offset, scale); 3300 return relation().CompoundImplies(other_relation, offset, scale);
3125 } else { 3301 } else {
3126 return false; 3302 if (relation().CanBeChained(other_relation)) {
3303 return induction_base()->IsRelationTrue(
3304 other_relation, other_related_value, offset, scale);
3305 } else {
3306 return false;
3307 }
3127 } 3308 }
3128 } 3309 }
3129 3310
3311 const ZoneList<HBoundsCheck*>* hoisted_checks() const {
3312 return &hoisted_checks_;
3313 }
3314 void AddHoistedCheck(HBoundsCheck* check);
3315
3130 DECLARE_CONCRETE_INSTRUCTION(InductionVariableAnnotation) 3316 DECLARE_CONCRETE_INSTRUCTION(InductionVariableAnnotation)
3131 3317
3132 private: 3318 private:
3133 HInductionVariableAnnotation(HPhi* phi, 3319 HInductionVariableAnnotation(HPhi* phi,
3134 NumericRelation relation, 3320 NumericRelation relation,
3135 int operand_index) 3321 int operand_index,
3136 : HUnaryOperation(phi), 3322 Zone* zone);
3137 phi_(phi), relation_(relation), operand_index_(operand_index) {
3138 }
3139 3323
3140 // We need to store the phi both here and in the instruction operand because 3324 // We need to store the phi both here and in the instruction operand because
3141 // the operand can change if a new idef of the phi is added between the phi 3325 // the operand can change if a new idef of the phi is added between the phi
3142 // and this instruction (inserting an idef updates every use). 3326 // and this instruction (inserting an idef updates every use).
3143 HPhi* phi_; 3327 HPhi* phi_;
3144 NumericRelation relation_; 3328 NumericRelation relation_;
3145 int operand_index_; 3329 int operand_index_;
3330 ZoneList<HBoundsCheck*> hoisted_checks_;
3146 }; 3331 };
3147 3332
3148 3333
3149 class HArgumentsObject: public HTemplateInstruction<0> { 3334 class HArgumentsObject: public HTemplateInstruction<0> {
3150 public: 3335 public:
3151 HArgumentsObject() { 3336 HArgumentsObject() {
3152 set_representation(Representation::Tagged()); 3337 set_representation(Representation::Tagged());
3153 SetFlag(kIsArguments); 3338 SetFlag(kIsArguments);
3154 } 3339 }
3155 3340
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
3281 Handle<String> StringValue() const { 3466 Handle<String> StringValue() const {
3282 ASSERT(HasStringValue()); 3467 ASSERT(HasStringValue());
3283 return Handle<String>::cast(handle_); 3468 return Handle<String>::cast(handle_);
3284 } 3469 }
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
3476 virtual bool IsRelationTrueInternal(NumericRelation relation,
3477 HValue* related_value,
3478 int offset = 0,
3479 int scale = 0) {
3480 if (HasInteger32Value() &&
3481 related_value->IsInteger32Constant()) {
3482 int32_t value = (Integer32Value() + offset) >> scale;
3483 int32_t other_value = related_value->GetInteger32Constant();
3484 return relation.ApplyToValues(value, other_value);
3485 } else {
3486 return false;
3487 }
3488 }
3489
3291 virtual intptr_t Hashcode() { 3490 virtual intptr_t Hashcode() {
3292 if (has_int32_value_) { 3491 if (has_int32_value_) {
3293 return static_cast<intptr_t>(int32_value_); 3492 return static_cast<intptr_t>(int32_value_);
3294 } else if (has_double_value_) { 3493 } else if (has_double_value_) {
3295 return static_cast<intptr_t>(BitCast<int64_t>(double_value_)); 3494 return static_cast<intptr_t>(BitCast<int64_t>(double_value_));
3296 } else { 3495 } else {
3297 ASSERT(!handle_.is_null()); 3496 ASSERT(!handle_.is_null());
3298 return unique_id_.Hashcode(); 3497 return unique_id_.Hashcode();
3299 } 3498 }
3300 } 3499 }
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after
3575 // HGraphBuilder::AddBoundsCheck() helper, which also guards the index with 3774 // HGraphBuilder::AddBoundsCheck() helper, which also guards the index with
3576 // a HCheckSmiOrInt32 check. 3775 // a HCheckSmiOrInt32 check.
3577 // However when building stubs, where we know that the arguments are Int32, 3776 // However when building stubs, where we know that the arguments are Int32,
3578 // it makes sense to invoke this constructor directly. 3777 // it makes sense to invoke this constructor directly.
3579 HBoundsCheck(HValue* index, 3778 HBoundsCheck(HValue* index,
3580 HValue* length, 3779 HValue* length,
3581 BoundsCheckKeyMode key_mode = DONT_ALLOW_SMI_KEY, 3780 BoundsCheckKeyMode key_mode = DONT_ALLOW_SMI_KEY,
3582 Representation r = Representation::None()) 3781 Representation r = Representation::None())
3583 : key_mode_(key_mode), skip_check_(false), 3782 : key_mode_(key_mode), skip_check_(false),
3584 base_(NULL), offset_(0), scale_(0), 3783 base_(NULL), offset_(0), scale_(0),
3585 responsibility_direction_(DIRECTION_NONE) { 3784 responsibility_direction_(DIRECTION_NONE),
3785 allow_equality_(false) {
3586 SetOperandAt(0, index); 3786 SetOperandAt(0, index);
3587 SetOperandAt(1, length); 3787 SetOperandAt(1, length);
3588 if (r.IsNone()) { 3788 if (r.IsNone()) {
3589 // In the normal compilation pipeline the representation is flexible 3789 // In the normal compilation pipeline the representation is flexible
3590 // (see InferRepresentation). 3790 // (see InferRepresentation).
3591 SetFlag(kFlexibleRepresentation); 3791 SetFlag(kFlexibleRepresentation);
3592 } else { 3792 } else {
3593 // When compiling stubs we want to set the representation explicitly 3793 // When compiling stubs we want to set the representation explicitly
3594 // so the compilation pipeline can skip the HInferRepresentation phase. 3794 // so the compilation pipeline can skip the HInferRepresentation phase.
3595 set_representation(r); 3795 set_representation(r);
3596 } 3796 }
3597 SetFlag(kUseGVN); 3797 SetFlag(kUseGVN);
3598 } 3798 }
3599 3799
3600 bool skip_check() { return skip_check_; } 3800 bool skip_check() const { return skip_check_; }
3601 void set_skip_check(bool skip_check) { skip_check_ = skip_check; } 3801 void set_skip_check() {
3802 isolate()->counters()->bounds_checks_removed()->Increment();
3803 skip_check_ = true;
3804 }
3602 HValue* base() { return base_; } 3805 HValue* base() { return base_; }
3603 int offset() { return offset_; } 3806 int offset() { return offset_; }
3604 int scale() { return scale_; } 3807 int scale() { return scale_; }
3605 bool index_can_increase() { 3808 bool index_can_increase() {
3606 return (responsibility_direction_ & DIRECTION_LOWER) == 0; 3809 return (responsibility_direction_ & DIRECTION_LOWER) == 0;
3607 } 3810 }
3608 bool index_can_decrease() { 3811 bool index_can_decrease() {
3609 return (responsibility_direction_ & DIRECTION_UPPER) == 0; 3812 return (responsibility_direction_ & DIRECTION_UPPER) == 0;
3610 } 3813 }
3611 3814
(...skipping 14 matching lines...) Expand all
3626 return false; 3829 return false;
3627 } 3830 }
3628 } 3831 }
3629 3832
3630 virtual Representation RequiredInputRepresentation(int arg_index) { 3833 virtual Representation RequiredInputRepresentation(int arg_index) {
3631 return representation(); 3834 return representation();
3632 } 3835 }
3633 virtual Representation observed_input_representation(int index) { 3836 virtual Representation observed_input_representation(int index) {
3634 return Representation::Integer32(); 3837 return Representation::Integer32();
3635 } 3838 }
3839 virtual bool IsDeletable() const {
3840 return skip_check();
3841 }
3636 3842
3637 virtual bool IsRelationTrueInternal(NumericRelation relation, 3843 virtual bool IsRelationTrueInternal(NumericRelation relation,
3638 HValue* related_value, 3844 HValue* related_value,
3639 int offset = 0, 3845 int offset = 0,
3640 int scale = 0); 3846 int scale = 0);
3641 3847
3642 virtual void PrintDataTo(StringStream* stream); 3848 virtual void PrintDataTo(StringStream* stream);
3643 virtual void InferRepresentation(HInferRepresentation* h_infer); 3849 virtual void InferRepresentation(HInferRepresentation* h_infer);
3644 3850
3645 HValue* index() { return OperandAt(0); } 3851 HValue* index() { return OperandAt(0); }
3646 HValue* length() { return OperandAt(1); } 3852 HValue* length() { return OperandAt(1); }
3853 bool allow_equality() { return allow_equality_; }
3854 void set_allow_equality(bool v) { allow_equality_ = v; }
3647 3855
3648 virtual int RedefinedOperandIndex() { return 0; } 3856 virtual int RedefinedOperandIndex() { return 0; }
3649 virtual bool IsPurelyInformativeDefinition() { return skip_check(); } 3857 virtual bool IsPurelyInformativeDefinition() { return skip_check(); }
3650 virtual void AddInformativeDefinitions(); 3858 virtual void AddInformativeDefinitions();
3651 3859
3652 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck) 3860 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck)
3653 3861
3654 protected: 3862 protected:
3655 friend class HBoundsCheckBaseIndexInformation; 3863 friend class HBoundsCheckBaseIndexInformation;
3656 3864
3657 virtual void SetResponsibilityForRange(RangeGuaranteeDirection direction) { 3865 virtual void SetResponsibilityForRange(RangeGuaranteeDirection direction) {
3658 responsibility_direction_ = static_cast<RangeGuaranteeDirection>( 3866 responsibility_direction_ = static_cast<RangeGuaranteeDirection>(
3659 responsibility_direction_ | direction); 3867 responsibility_direction_ | direction);
3660 } 3868 }
3661 3869
3662 virtual bool DataEquals(HValue* other) { return true; } 3870 virtual bool DataEquals(HValue* other) { return true; }
3663 virtual void TryGuaranteeRangeChanging(RangeEvaluationContext* context); 3871 virtual void TryGuaranteeRangeChanging(RangeEvaluationContext* context);
3664 BoundsCheckKeyMode key_mode_; 3872 BoundsCheckKeyMode key_mode_;
3665 bool skip_check_; 3873 bool skip_check_;
3666 HValue* base_; 3874 HValue* base_;
3667 int offset_; 3875 int offset_;
3668 int scale_; 3876 int scale_;
3669 RangeGuaranteeDirection responsibility_direction_; 3877 RangeGuaranteeDirection responsibility_direction_;
3878 bool allow_equality_;
3670 }; 3879 };
3671 3880
3672 3881
3673 class HBoundsCheckBaseIndexInformation: public HTemplateInstruction<2> { 3882 class HBoundsCheckBaseIndexInformation: public HTemplateInstruction<2> {
3674 public: 3883 public:
3675 explicit HBoundsCheckBaseIndexInformation(HBoundsCheck* check) { 3884 explicit HBoundsCheckBaseIndexInformation(HBoundsCheck* check) {
3676 DecompositionResult decomposition; 3885 DecompositionResult decomposition;
3677 if (check->index()->TryDecompose(&decomposition)) { 3886 if (check->index()->TryDecompose(&decomposition)) {
3678 SetOperandAt(0, decomposition.base()); 3887 SetOperandAt(0, decomposition.base());
3679 SetOperandAt(1, check); 3888 SetOperandAt(1, check);
3680 } else { 3889 } else {
3681 UNREACHABLE(); 3890 UNREACHABLE();
3682 } 3891 }
3683 } 3892 }
3684 3893
3685 HValue* base_index() { return OperandAt(0); } 3894 HValue* base_index() { return OperandAt(0); }
3686 HBoundsCheck* bounds_check() { return HBoundsCheck::cast(OperandAt(1)); } 3895 HBoundsCheck* bounds_check() {
3896 return OperandAt(1)->IsBoundsCheck()
3897 ? HBoundsCheck::cast(OperandAt(1)) : NULL;
3898 }
3687 3899
3688 DECLARE_CONCRETE_INSTRUCTION(BoundsCheckBaseIndexInformation) 3900 DECLARE_CONCRETE_INSTRUCTION(BoundsCheckBaseIndexInformation)
3689 3901
3690 virtual Representation RequiredInputRepresentation(int arg_index) { 3902 virtual Representation RequiredInputRepresentation(int arg_index) {
3691 return representation(); 3903 return representation();
3692 } 3904 }
3693 3905
3694 virtual bool IsRelationTrueInternal(NumericRelation relation, 3906 virtual bool IsRelationTrueInternal(NumericRelation relation,
3695 HValue* related_value, 3907 HValue* related_value,
3696 int offset = 0, 3908 int offset = 0,
(...skipping 588 matching lines...) Expand 10 before | Expand all | Expand 10 after
4285 decomposition->Apply(right(), left()->GetInteger32Constant()); 4497 decomposition->Apply(right(), left()->GetInteger32Constant());
4286 return true; 4498 return true;
4287 } else if (right()->IsInteger32Constant()) { 4499 } else if (right()->IsInteger32Constant()) {
4288 decomposition->Apply(left(), right()->GetInteger32Constant()); 4500 decomposition->Apply(left(), right()->GetInteger32Constant());
4289 return true; 4501 return true;
4290 } else { 4502 } else {
4291 return false; 4503 return false;
4292 } 4504 }
4293 } 4505 }
4294 4506
4507 virtual bool IsRelationTrueInternal(NumericRelation relation,
4508 HValue* other,
4509 int offset = 0,
4510 int scale = 0);
4511
4295 DECLARE_CONCRETE_INSTRUCTION(Add) 4512 DECLARE_CONCRETE_INSTRUCTION(Add)
4296 4513
4297 protected: 4514 protected:
4298 virtual bool DataEquals(HValue* other) { return true; } 4515 virtual bool DataEquals(HValue* other) { return true; }
4299 4516
4300 virtual Range* InferRange(Zone* zone); 4517 virtual Range* InferRange(Zone* zone);
4301 4518
4302 private: 4519 private:
4303 HAdd(HValue* context, HValue* left, HValue* right) 4520 HAdd(HValue* context, HValue* left, HValue* right)
4304 : HArithmeticBinaryOperation(context, left, right) { 4521 : HArithmeticBinaryOperation(context, left, right) {
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after
4547 }; 4764 };
4548 4765
4549 4766
4550 class HShl: public HBitwiseBinaryOperation { 4767 class HShl: public HBitwiseBinaryOperation {
4551 public: 4768 public:
4552 static HInstruction* New(Zone* zone, 4769 static HInstruction* New(Zone* zone,
4553 HValue* context, 4770 HValue* context,
4554 HValue* left, 4771 HValue* left,
4555 HValue* right); 4772 HValue* right);
4556 4773
4774 virtual bool TryDecompose(DecompositionResult* decomposition) {
4775 if (right()->IsInteger32Constant() &&
4776 right()->GetInteger32Constant() <= 1 &&
4777 right()->GetInteger32Constant() >= 0) {
4778 if (decomposition->Apply(left(), 0, - right()->GetInteger32Constant())) {
4779 // This is intended to look for HAdd and HSub, to handle compounds
4780 // like ((base + offset) << scale) with one single decomposition.
4781 left()->TryDecompose(decomposition);
4782 return true;
4783 }
4784 }
4785 return false;
4786 }
4787
4557 virtual Range* InferRange(Zone* zone); 4788 virtual Range* InferRange(Zone* zone);
4558 4789
4559 DECLARE_CONCRETE_INSTRUCTION(Shl) 4790 DECLARE_CONCRETE_INSTRUCTION(Shl)
4560 4791
4561 protected: 4792 protected:
4562 virtual bool DataEquals(HValue* other) { return true; } 4793 virtual bool DataEquals(HValue* other) { return true; }
4563 4794
4564 private: 4795 private:
4565 HShl(HValue* context, HValue* left, HValue* right) 4796 HShl(HValue* context, HValue* left, HValue* right)
4566 : HBitwiseBinaryOperation(context, left, right) { } 4797 : HBitwiseBinaryOperation(context, left, right) { }
4567 }; 4798 };
4568 4799
4569 4800
4570 class HShr: public HBitwiseBinaryOperation { 4801 class HShr: public HBitwiseBinaryOperation {
4571 public: 4802 public:
4572 static HInstruction* New(Zone* zone, 4803 static HInstruction* New(Zone* zone,
4573 HValue* context, 4804 HValue* context,
4574 HValue* left, 4805 HValue* left,
4575 HValue* right); 4806 HValue* right);
4576 4807
4577 virtual bool TryDecompose(DecompositionResult* decomposition) { 4808 virtual bool TryDecompose(DecompositionResult* decomposition) {
4578 if (right()->IsInteger32Constant()) { 4809 if (right()->IsInteger32Constant() &&
4810 right()->GetInteger32Constant() >= 0) {
4579 if (decomposition->Apply(left(), 0, right()->GetInteger32Constant())) { 4811 if (decomposition->Apply(left(), 0, right()->GetInteger32Constant())) {
4580 // This is intended to look for HAdd and HSub, to handle compounds 4812 // This is intended to look for HAdd and HSub, to handle compounds
4581 // like ((base + offset) >> scale) with one single decomposition. 4813 // like ((base + offset) >> scale) with one single decomposition.
4582 left()->TryDecompose(decomposition); 4814 left()->TryDecompose(decomposition);
4583 return true; 4815 return true;
4584 } 4816 }
4585 } 4817 }
4586 return false; 4818 return false;
4587 } 4819 }
4588 4820
(...skipping 11 matching lines...) Expand all
4600 4832
4601 4833
4602 class HSar: public HBitwiseBinaryOperation { 4834 class HSar: public HBitwiseBinaryOperation {
4603 public: 4835 public:
4604 static HInstruction* New(Zone* zone, 4836 static HInstruction* New(Zone* zone,
4605 HValue* context, 4837 HValue* context,
4606 HValue* left, 4838 HValue* left,
4607 HValue* right); 4839 HValue* right);
4608 4840
4609 virtual bool TryDecompose(DecompositionResult* decomposition) { 4841 virtual bool TryDecompose(DecompositionResult* decomposition) {
4610 if (right()->IsInteger32Constant()) { 4842 if (right()->IsInteger32Constant() &&
4843 right()->GetInteger32Constant() >= 0) {
4611 if (decomposition->Apply(left(), 0, right()->GetInteger32Constant())) { 4844 if (decomposition->Apply(left(), 0, right()->GetInteger32Constant())) {
4612 // This is intended to look for HAdd and HSub, to handle compounds 4845 // This is intended to look for HAdd and HSub, to handle compounds
4613 // like ((base + offset) >> scale) with one single decomposition. 4846 // like ((base + offset) >> scale) with one single decomposition.
4614 left()->TryDecompose(decomposition); 4847 left()->TryDecompose(decomposition);
4615 return true; 4848 return true;
4616 } 4849 }
4617 } 4850 }
4618 return false; 4851 return false;
4619 } 4852 }
4620 4853
(...skipping 1840 matching lines...) Expand 10 before | Expand all | Expand 10 after
6461 virtual bool IsDeletable() const { return true; } 6694 virtual bool IsDeletable() const { return true; }
6462 }; 6695 };
6463 6696
6464 6697
6465 #undef DECLARE_INSTRUCTION 6698 #undef DECLARE_INSTRUCTION
6466 #undef DECLARE_CONCRETE_INSTRUCTION 6699 #undef DECLARE_CONCRETE_INSTRUCTION
6467 6700
6468 } } // namespace v8::internal 6701 } } // namespace v8::internal
6469 6702
6470 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ 6703 #endif // V8_HYDROGEN_INSTRUCTIONS_H_
OLDNEW
« no previous file with comments | « src/hydrogen.cc ('k') | src/hydrogen-instructions.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698