OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
113 | 113 |
114 void Range::AddConstant(int32_t value) { | 114 void Range::AddConstant(int32_t value) { |
115 if (value == 0) return; | 115 if (value == 0) return; |
116 bool may_overflow = false; // Overflow is ignored here. | 116 bool may_overflow = false; // Overflow is ignored here. |
117 lower_ = AddWithoutOverflow(lower_, value, &may_overflow); | 117 lower_ = AddWithoutOverflow(lower_, value, &may_overflow); |
118 upper_ = AddWithoutOverflow(upper_, value, &may_overflow); | 118 upper_ = AddWithoutOverflow(upper_, value, &may_overflow); |
119 Verify(); | 119 Verify(); |
120 } | 120 } |
121 | 121 |
122 | 122 |
| 123 void Range::Intersect(Range* other) { |
| 124 upper_ = Min(upper_, other->upper_); |
| 125 lower_ = Max(lower_, other->lower_); |
| 126 bool b = CanBeMinusZero() && other->CanBeMinusZero(); |
| 127 set_can_be_minus_zero(b); |
| 128 } |
| 129 |
| 130 |
| 131 void Range::Union(Range* other) { |
| 132 upper_ = Max(upper_, other->upper_); |
| 133 lower_ = Min(lower_, other->lower_); |
| 134 bool b = CanBeMinusZero() || other->CanBeMinusZero(); |
| 135 set_can_be_minus_zero(b); |
| 136 } |
| 137 |
| 138 |
| 139 void Range::Sar(int32_t value) { |
| 140 int32_t bits = value & 0x1F; |
| 141 lower_ = lower_ >> bits; |
| 142 upper_ = upper_ >> bits; |
| 143 set_can_be_minus_zero(false); |
| 144 } |
| 145 |
| 146 |
| 147 void Range::Shl(int32_t value) { |
| 148 int32_t bits = value & 0x1F; |
| 149 int old_lower = lower_; |
| 150 int old_upper = upper_; |
| 151 lower_ = lower_ << bits; |
| 152 upper_ = upper_ << bits; |
| 153 if (old_lower != lower_ >> bits || old_upper != upper_ >> bits) { |
| 154 upper_ = kMaxInt; |
| 155 lower_ = kMinInt; |
| 156 } |
| 157 set_can_be_minus_zero(false); |
| 158 } |
| 159 |
| 160 |
123 bool Range::AddAndCheckOverflow(Range* other) { | 161 bool Range::AddAndCheckOverflow(Range* other) { |
124 bool may_overflow = false; | 162 bool may_overflow = false; |
125 lower_ = AddWithoutOverflow(lower_, other->lower(), &may_overflow); | 163 lower_ = AddWithoutOverflow(lower_, other->lower(), &may_overflow); |
126 upper_ = AddWithoutOverflow(upper_, other->upper(), &may_overflow); | 164 upper_ = AddWithoutOverflow(upper_, other->upper(), &may_overflow); |
127 KeepOrder(); | 165 KeepOrder(); |
128 Verify(); | 166 Verify(); |
129 return may_overflow; | 167 return may_overflow; |
130 } | 168 } |
131 | 169 |
132 | 170 |
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
408 ASSERT(HasRange()); | 446 ASSERT(HasRange()); |
409 } | 447 } |
410 | 448 |
411 | 449 |
412 void HInstruction::PrintTo(StringStream* stream) { | 450 void HInstruction::PrintTo(StringStream* stream) { |
413 stream->Add("%s", Mnemonic()); | 451 stream->Add("%s", Mnemonic()); |
414 if (HasSideEffects()) stream->Add("*"); | 452 if (HasSideEffects()) stream->Add("*"); |
415 stream->Add(" "); | 453 stream->Add(" "); |
416 PrintDataTo(stream); | 454 PrintDataTo(stream); |
417 | 455 |
418 if (range() != NULL) { | 456 if (range() != NULL && |
| 457 !range()->IsMostGeneric() && |
| 458 !range()->CanBeMinusZero()) { |
419 stream->Add(" range[%d,%d,m0=%d]", | 459 stream->Add(" range[%d,%d,m0=%d]", |
420 range()->lower(), | 460 range()->lower(), |
421 range()->upper(), | 461 range()->upper(), |
422 static_cast<int>(range()->CanBeMinusZero())); | 462 static_cast<int>(range()->CanBeMinusZero())); |
423 } | 463 } |
424 | 464 |
425 int changes_flags = (flags() & HValue::ChangesFlagsMask()); | 465 int changes_flags = (flags() & HValue::ChangesFlagsMask()); |
426 if (changes_flags != 0) { | 466 if (changes_flags != 0) { |
427 stream->Add(" changes[0x%x]", changes_flags); | 467 stream->Add(" changes[0x%x]", changes_flags); |
428 } | 468 } |
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
732 Range* HValue::InferRange() { | 772 Range* HValue::InferRange() { |
733 if (representation().IsTagged()) { | 773 if (representation().IsTagged()) { |
734 // Tagged values are always in int32 range when converted to integer, | 774 // Tagged values are always in int32 range when converted to integer, |
735 // but they can contain -0. | 775 // but they can contain -0. |
736 Range* result = new Range(); | 776 Range* result = new Range(); |
737 result->set_can_be_minus_zero(true); | 777 result->set_can_be_minus_zero(true); |
738 return result; | 778 return result; |
739 } else if (representation().IsNone()) { | 779 } else if (representation().IsNone()) { |
740 return NULL; | 780 return NULL; |
741 } else { | 781 } else { |
| 782 // Untagged integer32 cannot be -0 and we don't compute ranges for |
| 783 // untagged doubles. |
742 return new Range(); | 784 return new Range(); |
743 } | 785 } |
744 } | 786 } |
745 | 787 |
746 | 788 |
747 Range* HConstant::InferRange() { | 789 Range* HConstant::InferRange() { |
748 if (has_int32_value_) { | 790 if (has_int32_value_) { |
749 Range* result = new Range(int32_value_, int32_value_); | 791 Range* result = new Range(int32_value_, int32_value_); |
750 result->set_can_be_minus_zero(false); | 792 result->set_can_be_minus_zero(false); |
751 return result; | 793 return result; |
752 } | 794 } |
753 return HInstruction::InferRange(); | 795 return HValue::InferRange(); |
754 } | 796 } |
755 | 797 |
756 | 798 |
757 Range* HPhi::InferRange() { | 799 Range* HPhi::InferRange() { |
758 if (representation().IsInteger32()) { | 800 if (representation().IsInteger32()) { |
759 if (block()->IsLoopHeader()) { | 801 if (block()->IsLoopHeader()) { |
760 Range* range = new Range(kMinInt, kMaxInt); | 802 Range* range = new Range(kMinInt, kMaxInt); |
761 return range; | 803 return range; |
762 } else { | 804 } else { |
763 Range* range = OperandAt(0)->range()->Copy(); | 805 Range* range = OperandAt(0)->range()->Copy(); |
(...skipping 13 matching lines...) Expand all Loading... |
777 Range* a = left()->range(); | 819 Range* a = left()->range(); |
778 Range* b = right()->range(); | 820 Range* b = right()->range(); |
779 Range* res = a->Copy(); | 821 Range* res = a->Copy(); |
780 if (!res->AddAndCheckOverflow(b)) { | 822 if (!res->AddAndCheckOverflow(b)) { |
781 ClearFlag(kCanOverflow); | 823 ClearFlag(kCanOverflow); |
782 } | 824 } |
783 bool m0 = a->CanBeMinusZero() && b->CanBeMinusZero(); | 825 bool m0 = a->CanBeMinusZero() && b->CanBeMinusZero(); |
784 res->set_can_be_minus_zero(m0); | 826 res->set_can_be_minus_zero(m0); |
785 return res; | 827 return res; |
786 } else { | 828 } else { |
787 return HArithmeticBinaryOperation::InferRange(); | 829 return HValue::InferRange(); |
788 } | 830 } |
789 } | 831 } |
790 | 832 |
791 | 833 |
792 Range* HSub::InferRange() { | 834 Range* HSub::InferRange() { |
793 if (representation().IsInteger32()) { | 835 if (representation().IsInteger32()) { |
794 Range* a = left()->range(); | 836 Range* a = left()->range(); |
795 Range* b = right()->range(); | 837 Range* b = right()->range(); |
796 Range* res = a->Copy(); | 838 Range* res = a->Copy(); |
797 if (!res->SubAndCheckOverflow(b)) { | 839 if (!res->SubAndCheckOverflow(b)) { |
798 ClearFlag(kCanOverflow); | 840 ClearFlag(kCanOverflow); |
799 } | 841 } |
800 res->set_can_be_minus_zero(a->CanBeMinusZero() && b->CanBeZero()); | 842 res->set_can_be_minus_zero(a->CanBeMinusZero() && b->CanBeZero()); |
801 return res; | 843 return res; |
802 } else { | 844 } else { |
803 return HArithmeticBinaryOperation::InferRange(); | 845 return HValue::InferRange(); |
804 } | 846 } |
805 } | 847 } |
806 | 848 |
807 | 849 |
808 Range* HMul::InferRange() { | 850 Range* HMul::InferRange() { |
809 if (representation().IsInteger32()) { | 851 if (representation().IsInteger32()) { |
810 Range* a = left()->range(); | 852 Range* a = left()->range(); |
811 Range* b = right()->range(); | 853 Range* b = right()->range(); |
812 Range* res = a->Copy(); | 854 Range* res = a->Copy(); |
813 if (!res->MulAndCheckOverflow(b)) { | 855 if (!res->MulAndCheckOverflow(b)) { |
814 ClearFlag(kCanOverflow); | 856 ClearFlag(kCanOverflow); |
815 } | 857 } |
816 bool m0 = (a->CanBeZero() && b->CanBeNegative()) || | 858 bool m0 = (a->CanBeZero() && b->CanBeNegative()) || |
817 (a->CanBeNegative() && b->CanBeZero()); | 859 (a->CanBeNegative() && b->CanBeZero()); |
818 res->set_can_be_minus_zero(m0); | 860 res->set_can_be_minus_zero(m0); |
819 return res; | 861 return res; |
820 } else { | 862 } else { |
821 return HArithmeticBinaryOperation::InferRange(); | 863 return HValue::InferRange(); |
822 } | 864 } |
823 } | 865 } |
824 | 866 |
825 | 867 |
826 Range* HDiv::InferRange() { | 868 Range* HDiv::InferRange() { |
827 if (representation().IsInteger32()) { | 869 if (representation().IsInteger32()) { |
828 Range* result = new Range(); | 870 Range* result = new Range(); |
829 if (left()->range()->CanBeMinusZero()) { | 871 if (left()->range()->CanBeMinusZero()) { |
830 result->set_can_be_minus_zero(true); | 872 result->set_can_be_minus_zero(true); |
831 } | 873 } |
832 | 874 |
833 if (left()->range()->CanBeZero() && right()->range()->CanBeNegative()) { | 875 if (left()->range()->CanBeZero() && right()->range()->CanBeNegative()) { |
834 result->set_can_be_minus_zero(true); | 876 result->set_can_be_minus_zero(true); |
835 } | 877 } |
836 | 878 |
837 if (right()->range()->Includes(-1) && left()->range()->Includes(kMinInt)) { | 879 if (right()->range()->Includes(-1) && left()->range()->Includes(kMinInt)) { |
838 SetFlag(HValue::kCanOverflow); | 880 SetFlag(HValue::kCanOverflow); |
839 } | 881 } |
840 | 882 |
841 if (!right()->range()->CanBeZero()) { | 883 if (!right()->range()->CanBeZero()) { |
842 ClearFlag(HValue::kCanBeDivByZero); | 884 ClearFlag(HValue::kCanBeDivByZero); |
843 } | 885 } |
844 return result; | 886 return result; |
845 } else { | 887 } else { |
846 return HArithmeticBinaryOperation::InferRange(); | 888 return HValue::InferRange(); |
847 } | 889 } |
848 } | 890 } |
849 | 891 |
850 | 892 |
851 Range* HMod::InferRange() { | 893 Range* HMod::InferRange() { |
852 if (representation().IsInteger32()) { | 894 if (representation().IsInteger32()) { |
853 Range* a = left()->range(); | 895 Range* a = left()->range(); |
854 Range* result = new Range(); | 896 Range* result = new Range(); |
855 if (a->CanBeMinusZero() || a->CanBeNegative()) { | 897 if (a->CanBeMinusZero() || a->CanBeNegative()) { |
856 result->set_can_be_minus_zero(true); | 898 result->set_can_be_minus_zero(true); |
857 } | 899 } |
858 if (!right()->range()->CanBeZero()) { | 900 if (!right()->range()->CanBeZero()) { |
859 ClearFlag(HValue::kCanBeDivByZero); | 901 ClearFlag(HValue::kCanBeDivByZero); |
860 } | 902 } |
861 return result; | 903 return result; |
862 } else { | 904 } else { |
863 return HArithmeticBinaryOperation::InferRange(); | 905 return HValue::InferRange(); |
864 } | 906 } |
865 } | 907 } |
866 | 908 |
867 | 909 |
868 void HPhi::PrintTo(StringStream* stream) { | 910 void HPhi::PrintTo(StringStream* stream) { |
869 stream->Add("["); | 911 stream->Add("["); |
870 for (int i = 0; i < OperandCount(); ++i) { | 912 for (int i = 0; i < OperandCount(); ++i) { |
871 HValue* value = OperandAt(i); | 913 HValue* value = OperandAt(i); |
872 stream->Add(" "); | 914 stream->Add(" "); |
873 value->PrintNameTo(stream); | 915 value->PrintNameTo(stream); |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1014 void HBinaryOperation::PrintDataTo(StringStream* stream) { | 1056 void HBinaryOperation::PrintDataTo(StringStream* stream) { |
1015 left()->PrintNameTo(stream); | 1057 left()->PrintNameTo(stream); |
1016 stream->Add(" "); | 1058 stream->Add(" "); |
1017 right()->PrintNameTo(stream); | 1059 right()->PrintNameTo(stream); |
1018 if (CheckFlag(kCanOverflow)) stream->Add(" !"); | 1060 if (CheckFlag(kCanOverflow)) stream->Add(" !"); |
1019 if (CheckFlag(kBailoutOnMinusZero)) stream->Add(" -0?"); | 1061 if (CheckFlag(kBailoutOnMinusZero)) stream->Add(" -0?"); |
1020 } | 1062 } |
1021 | 1063 |
1022 | 1064 |
1023 Range* HBitAnd::InferRange() { | 1065 Range* HBitAnd::InferRange() { |
1024 Range* a = left()->range(); | 1066 int32_t left_mask = (left()->range() != NULL) |
1025 Range* b = right()->range(); | 1067 ? left()->range()->Mask() |
1026 int32_t a_mask = 0xffffffff; | 1068 : 0xffffffff; |
1027 int32_t b_mask = 0xffffffff; | 1069 int32_t right_mask = (right()->range() != NULL) |
1028 if (a != NULL) a_mask = a->Mask(); | 1070 ? right()->range()->Mask() |
1029 if (b != NULL) b_mask = b->Mask(); | 1071 : 0xffffffff; |
1030 int32_t result_mask = a_mask & b_mask; | 1072 int32_t result_mask = left_mask & right_mask; |
1031 if (result_mask >= 0) { | 1073 return (result_mask >= 0) |
1032 return new Range(0, result_mask); | 1074 ? new Range(0, result_mask) |
1033 } else { | 1075 : HValue::InferRange(); |
1034 return HBinaryOperation::InferRange(); | |
1035 } | |
1036 } | 1076 } |
1037 | 1077 |
1038 | 1078 |
1039 Range* HBitOr::InferRange() { | 1079 Range* HBitOr::InferRange() { |
1040 Range* a = left()->range(); | 1080 int32_t left_mask = (left()->range() != NULL) |
1041 Range* b = right()->range(); | 1081 ? left()->range()->Mask() |
1042 int32_t a_mask = 0xffffffff; | 1082 : 0xffffffff; |
1043 int32_t b_mask = 0xffffffff; | 1083 int32_t right_mask = (right()->range() != NULL) |
1044 if (a != NULL) a_mask = a->Mask(); | 1084 ? right()->range()->Mask() |
1045 if (b != NULL) b_mask = b->Mask(); | 1085 : 0xffffffff; |
1046 int32_t result_mask = a_mask | b_mask; | 1086 int32_t result_mask = left_mask | right_mask; |
1047 if (result_mask >= 0) { | 1087 return (result_mask >= 0) |
1048 return new Range(0, result_mask); | 1088 ? new Range(0, result_mask) |
1049 } else { | 1089 : HValue::InferRange(); |
1050 return HBinaryOperation::InferRange(); | |
1051 } | |
1052 } | 1090 } |
1053 | 1091 |
1054 | 1092 |
1055 Range* HSar::InferRange() { | 1093 Range* HSar::InferRange() { |
1056 if (right()->IsConstant()) { | 1094 if (right()->IsConstant()) { |
1057 HConstant* c = HConstant::cast(right()); | 1095 HConstant* c = HConstant::cast(right()); |
1058 if (c->HasInteger32Value()) { | 1096 if (c->HasInteger32Value()) { |
1059 int32_t val = c->Integer32Value(); | 1097 Range* result = (left()->range() != NULL) |
1060 Range* result = NULL; | 1098 ? left()->range()->Copy() |
1061 Range* left_range = left()->range(); | 1099 : new Range(); |
1062 if (left_range == NULL) { | 1100 result->Sar(c->Integer32Value()); |
1063 result = new Range(); | |
1064 } else { | |
1065 result = left_range->Copy(); | |
1066 } | |
1067 result->Sar(val); | |
1068 return result; | 1101 return result; |
1069 } | 1102 } |
1070 } | 1103 } |
1071 | 1104 return HValue::InferRange(); |
1072 return HBinaryOperation::InferRange(); | |
1073 } | 1105 } |
1074 | 1106 |
1075 | 1107 |
1076 Range* HShl::InferRange() { | 1108 Range* HShl::InferRange() { |
1077 if (right()->IsConstant()) { | 1109 if (right()->IsConstant()) { |
1078 HConstant* c = HConstant::cast(right()); | 1110 HConstant* c = HConstant::cast(right()); |
1079 if (c->HasInteger32Value()) { | 1111 if (c->HasInteger32Value()) { |
1080 int32_t val = c->Integer32Value(); | 1112 Range* result = (left()->range() != NULL) |
1081 Range* result = NULL; | 1113 ? left()->range()->Copy() |
1082 Range* left_range = left()->range(); | 1114 : new Range(); |
1083 if (left_range == NULL) { | 1115 result->Shl(c->Integer32Value()); |
1084 result = new Range(); | |
1085 } else { | |
1086 result = left_range->Copy(); | |
1087 } | |
1088 result->Shl(val); | |
1089 return result; | 1116 return result; |
1090 } | 1117 } |
1091 } | 1118 } |
1092 | 1119 return HValue::InferRange(); |
1093 return HBinaryOperation::InferRange(); | |
1094 } | 1120 } |
1095 | 1121 |
1096 | 1122 |
1097 | 1123 |
1098 void HCompare::PrintDataTo(StringStream* stream) { | 1124 void HCompare::PrintDataTo(StringStream* stream) { |
1099 stream->Add(Token::Name(token())); | 1125 stream->Add(Token::Name(token())); |
1100 stream->Add(" "); | 1126 stream->Add(" "); |
1101 HBinaryOperation::PrintDataTo(stream); | 1127 HBinaryOperation::PrintDataTo(stream); |
1102 } | 1128 } |
1103 | 1129 |
(...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1476 | 1502 |
1477 | 1503 |
1478 void HCheckPrototypeMaps::Verify() { | 1504 void HCheckPrototypeMaps::Verify() { |
1479 HInstruction::Verify(); | 1505 HInstruction::Verify(); |
1480 ASSERT(HasNoUses()); | 1506 ASSERT(HasNoUses()); |
1481 } | 1507 } |
1482 | 1508 |
1483 #endif | 1509 #endif |
1484 | 1510 |
1485 } } // namespace v8::internal | 1511 } } // namespace v8::internal |
OLD | NEW |