| OLD | NEW |
| 1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/compiler/operation-typer.h" | 5 #include "src/compiler/operation-typer.h" |
| 6 | 6 |
| 7 #include "src/compiler/common-operator.h" | 7 #include "src/compiler/common-operator.h" |
| 8 #include "src/compiler/type-cache.h" | 8 #include "src/compiler/type-cache.h" |
| 9 #include "src/compiler/types.h" | 9 #include "src/compiler/types.h" |
| 10 #include "src/factory.h" | 10 #include "src/factory.h" |
| (...skipping 778 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 789 // TODO(jarin) Use a range here. | 789 // TODO(jarin) Use a range here. |
| 790 return Type::Negative32(); | 790 return Type::Negative32(); |
| 791 } | 791 } |
| 792 return Type::Signed32(); | 792 return Type::Signed32(); |
| 793 } | 793 } |
| 794 | 794 |
| 795 Type* OperationTyper::NumberShiftLeft(Type* lhs, Type* rhs) { | 795 Type* OperationTyper::NumberShiftLeft(Type* lhs, Type* rhs) { |
| 796 DCHECK(lhs->Is(Type::Number())); | 796 DCHECK(lhs->Is(Type::Number())); |
| 797 DCHECK(rhs->Is(Type::Number())); | 797 DCHECK(rhs->Is(Type::Number())); |
| 798 | 798 |
| 799 // TODO(turbofan): Infer a better type here. | 799 if (!lhs->IsInhabited() || !rhs->IsInhabited()) return Type::None(); |
| 800 return Type::Signed32(); | 800 |
| 801 lhs = NumberToInt32(lhs); |
| 802 rhs = NumberToUint32(rhs); |
| 803 |
| 804 int32_t min_lhs = lhs->Min(); |
| 805 int32_t max_lhs = lhs->Max(); |
| 806 uint32_t min_rhs = rhs->Min(); |
| 807 uint32_t max_rhs = rhs->Max(); |
| 808 if (max_rhs > 31) { |
| 809 // rhs can be larger than the bitmask |
| 810 max_rhs = 31; |
| 811 min_rhs = 0; |
| 812 } |
| 813 |
| 814 if (max_lhs > (kMaxInt >> max_rhs) || min_lhs < (kMinInt >> max_rhs)) { |
| 815 // overflow possible |
| 816 return Type::Signed32(); |
| 817 } |
| 818 |
| 819 double min = |
| 820 std::min(static_cast<int32_t>(static_cast<uint32_t>(min_lhs) << min_rhs), |
| 821 static_cast<int32_t>(static_cast<uint32_t>(min_lhs) << max_rhs)); |
| 822 double max = |
| 823 std::max(static_cast<int32_t>(static_cast<uint32_t>(max_lhs) << min_rhs), |
| 824 static_cast<int32_t>(static_cast<uint32_t>(max_lhs) << max_rhs)); |
| 825 |
| 826 if (max == kMaxInt && min == kMinInt) return Type::Signed32(); |
| 827 return Type::Range(min, max, zone()); |
| 801 } | 828 } |
| 802 | 829 |
| 803 Type* OperationTyper::NumberShiftRight(Type* lhs, Type* rhs) { | 830 Type* OperationTyper::NumberShiftRight(Type* lhs, Type* rhs) { |
| 804 DCHECK(lhs->Is(Type::Number())); | 831 DCHECK(lhs->Is(Type::Number())); |
| 805 DCHECK(rhs->Is(Type::Number())); | 832 DCHECK(rhs->Is(Type::Number())); |
| 806 | 833 |
| 807 if (!lhs->IsInhabited() || !rhs->IsInhabited()) return Type::None(); | 834 if (!lhs->IsInhabited() || !rhs->IsInhabited()) return Type::None(); |
| 808 | 835 |
| 809 lhs = NumberToInt32(lhs); | 836 lhs = NumberToInt32(lhs); |
| 810 rhs = NumberToUint32(rhs); | 837 rhs = NumberToUint32(rhs); |
| 811 | 838 |
| 812 double min = kMinInt; | 839 int32_t min_lhs = lhs->Min(); |
| 813 double max = kMaxInt; | 840 int32_t max_lhs = lhs->Max(); |
| 814 if (lhs->Min() >= 0) { | 841 uint32_t min_rhs = rhs->Min(); |
| 815 // Right-shifting a non-negative value cannot make it negative, nor larger. | 842 uint32_t max_rhs = rhs->Max(); |
| 816 min = std::max(min, 0.0); | 843 if (max_rhs > 31) { |
| 817 max = std::min(max, lhs->Max()); | 844 // rhs can be larger than the bitmask |
| 818 if (rhs->Min() > 0 && rhs->Max() <= 31) { | 845 max_rhs = 31; |
| 819 max = static_cast<int>(max) >> static_cast<int>(rhs->Min()); | 846 min_rhs = 0; |
| 820 } | |
| 821 } | 847 } |
| 822 if (lhs->Max() < 0) { | 848 double min = std::min(min_lhs >> min_rhs, min_lhs >> max_rhs); |
| 823 // Right-shifting a negative value cannot make it non-negative, nor smaller. | 849 double max = std::max(max_lhs >> min_rhs, max_lhs >> max_rhs); |
| 824 min = std::max(min, lhs->Min()); | 850 |
| 825 max = std::min(max, -1.0); | |
| 826 if (rhs->Min() > 0 && rhs->Max() <= 31) { | |
| 827 min = static_cast<int>(min) >> static_cast<int>(rhs->Min()); | |
| 828 } | |
| 829 } | |
| 830 if (rhs->Min() > 0 && rhs->Max() <= 31) { | |
| 831 // Right-shifting by a positive value yields a small integer value. | |
| 832 double shift_min = kMinInt >> static_cast<int>(rhs->Min()); | |
| 833 double shift_max = kMaxInt >> static_cast<int>(rhs->Min()); | |
| 834 min = std::max(min, shift_min); | |
| 835 max = std::min(max, shift_max); | |
| 836 } | |
| 837 // TODO(jarin) Ideally, the following micro-optimization should be performed | |
| 838 // by the type constructor. | |
| 839 if (max == kMaxInt && min == kMinInt) return Type::Signed32(); | 851 if (max == kMaxInt && min == kMinInt) return Type::Signed32(); |
| 840 return Type::Range(min, max, zone()); | 852 return Type::Range(min, max, zone()); |
| 841 } | 853 } |
| 842 | 854 |
| 843 Type* OperationTyper::NumberShiftRightLogical(Type* lhs, Type* rhs) { | 855 Type* OperationTyper::NumberShiftRightLogical(Type* lhs, Type* rhs) { |
| 844 DCHECK(lhs->Is(Type::Number())); | 856 DCHECK(lhs->Is(Type::Number())); |
| 845 DCHECK(rhs->Is(Type::Number())); | 857 DCHECK(rhs->Is(Type::Number())); |
| 846 | 858 |
| 847 if (!lhs->IsInhabited()) return Type::None(); | 859 if (!lhs->IsInhabited()) return Type::None(); |
| 848 | 860 |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 972 return singleton_true(); | 984 return singleton_true(); |
| 973 } | 985 } |
| 974 | 986 |
| 975 Type* OperationTyper::TypeTypeGuard(const Operator* sigma_op, Type* input) { | 987 Type* OperationTyper::TypeTypeGuard(const Operator* sigma_op, Type* input) { |
| 976 return Type::Intersect(input, TypeGuardTypeOf(sigma_op), zone()); | 988 return Type::Intersect(input, TypeGuardTypeOf(sigma_op), zone()); |
| 977 } | 989 } |
| 978 | 990 |
| 979 } // namespace compiler | 991 } // namespace compiler |
| 980 } // namespace internal | 992 } // namespace internal |
| 981 } // namespace v8 | 993 } // namespace v8 |
| OLD | NEW |