| 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 |