Chromium Code Reviews| 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 775 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 786 // TODO(jarin) Use a range here. | 786 // TODO(jarin) Use a range here. |
| 787 return Type::Negative32(); | 787 return Type::Negative32(); |
| 788 } | 788 } |
| 789 return Type::Signed32(); | 789 return Type::Signed32(); |
| 790 } | 790 } |
| 791 | 791 |
| 792 Type* OperationTyper::NumberShiftLeft(Type* lhs, Type* rhs) { | 792 Type* OperationTyper::NumberShiftLeft(Type* lhs, Type* rhs) { |
| 793 DCHECK(lhs->Is(Type::Number())); | 793 DCHECK(lhs->Is(Type::Number())); |
| 794 DCHECK(rhs->Is(Type::Number())); | 794 DCHECK(rhs->Is(Type::Number())); |
| 795 | 795 |
| 796 // TODO(turbofan): Infer a better type here. | 796 if (!lhs->IsInhabited() || !rhs->IsInhabited()) return Type::None(); |
| 797 return Type::Signed32(); | 797 |
| 798 lhs = NumberToInt32(lhs); | |
| 799 rhs = NumberToUint32(rhs); | |
| 800 | |
| 801 int32_t minLhs = lhs->Min(); | |
|
Jarin
2016/11/21 10:34:59
Style nit: minLhs -> min_lhs.
| |
| 802 int32_t maxLhs = lhs->Max(); | |
| 803 uint32_t maxRhs = rhs->Max(); | |
| 804 uint32_t minRhs = rhs->Min(); | |
| 805 if (maxRhs > 31) { | |
| 806 // rhs can be larger than the bitmask | |
| 807 maxRhs = 31; | |
| 808 minRhs = 0; | |
| 809 } | |
| 810 | |
| 811 if (maxLhs > (kMaxInt >> maxRhs) || minLhs < (kMinInt >> maxRhs)) { | |
| 812 // overflow possible | |
| 813 return Type::Signed32(); | |
| 814 } | |
| 815 | |
| 816 double min = | |
| 817 std::min(static_cast<int32_t>(static_cast<uint32_t>(minLhs) << minRhs), | |
| 818 static_cast<int32_t>(static_cast<uint32_t>(minLhs) << maxRhs)); | |
| 819 double max = | |
| 820 std::max(static_cast<int32_t>(static_cast<uint32_t>(maxLhs) << minRhs), | |
| 821 static_cast<int32_t>(static_cast<uint32_t>(maxLhs) << maxRhs)); | |
| 822 | |
| 823 if (max == kMaxInt && min == kMinInt) return Type::Signed32(); | |
| 824 return Type::Range(min, max, zone()); | |
| 798 } | 825 } |
| 799 | 826 |
| 800 Type* OperationTyper::NumberShiftRight(Type* lhs, Type* rhs) { | 827 Type* OperationTyper::NumberShiftRight(Type* lhs, Type* rhs) { |
| 801 DCHECK(lhs->Is(Type::Number())); | 828 DCHECK(lhs->Is(Type::Number())); |
| 802 DCHECK(rhs->Is(Type::Number())); | 829 DCHECK(rhs->Is(Type::Number())); |
| 803 | 830 |
| 804 if (!lhs->IsInhabited() || !rhs->IsInhabited()) return Type::None(); | 831 if (!lhs->IsInhabited() || !rhs->IsInhabited()) return Type::None(); |
| 805 | 832 |
| 806 lhs = NumberToInt32(lhs); | 833 lhs = NumberToInt32(lhs); |
| 807 rhs = NumberToUint32(rhs); | 834 rhs = NumberToUint32(rhs); |
| 808 | 835 |
| 809 double min = kMinInt; | 836 int32_t minLhs = lhs->Min(); |
| 810 double max = kMaxInt; | 837 int32_t maxLhs = lhs->Max(); |
| 811 if (lhs->Min() >= 0) { | 838 uint32_t maxRhs = rhs->Max(); |
| 812 // Right-shifting a non-negative value cannot make it negative, nor larger. | 839 uint32_t minRhs = rhs->Min(); |
| 813 min = std::max(min, 0.0); | 840 if (maxRhs > 31) { |
| 814 max = std::min(max, lhs->Max()); | 841 // rhs can be larger than the bitmask |
| 815 if (rhs->Min() > 0 && rhs->Max() <= 31) { | 842 maxRhs = 31; |
| 816 max = static_cast<int>(max) >> static_cast<int>(rhs->Min()); | 843 minRhs = 0; |
| 817 } | |
| 818 } | 844 } |
| 819 if (lhs->Max() < 0) { | 845 double min = std::min(minLhs >> minRhs, minLhs >> maxRhs); |
| 820 // Right-shifting a negative value cannot make it non-negative, nor smaller. | 846 double max = std::max(maxLhs >> minRhs, maxLhs >> maxRhs); |
| 821 min = std::max(min, lhs->Min()); | 847 |
| 822 max = std::min(max, -1.0); | |
| 823 if (rhs->Min() > 0 && rhs->Max() <= 31) { | |
| 824 min = static_cast<int>(min) >> static_cast<int>(rhs->Min()); | |
| 825 } | |
| 826 } | |
| 827 if (rhs->Min() > 0 && rhs->Max() <= 31) { | |
| 828 // Right-shifting by a positive value yields a small integer value. | |
| 829 double shift_min = kMinInt >> static_cast<int>(rhs->Min()); | |
| 830 double shift_max = kMaxInt >> static_cast<int>(rhs->Min()); | |
| 831 min = std::max(min, shift_min); | |
| 832 max = std::min(max, shift_max); | |
| 833 } | |
| 834 // TODO(jarin) Ideally, the following micro-optimization should be performed | |
| 835 // by the type constructor. | |
| 836 if (max == kMaxInt && min == kMinInt) return Type::Signed32(); | 848 if (max == kMaxInt && min == kMinInt) return Type::Signed32(); |
| 837 return Type::Range(min, max, zone()); | 849 return Type::Range(min, max, zone()); |
| 838 } | 850 } |
| 839 | 851 |
| 840 Type* OperationTyper::NumberShiftRightLogical(Type* lhs, Type* rhs) { | 852 Type* OperationTyper::NumberShiftRightLogical(Type* lhs, Type* rhs) { |
| 841 DCHECK(lhs->Is(Type::Number())); | 853 DCHECK(lhs->Is(Type::Number())); |
| 842 DCHECK(rhs->Is(Type::Number())); | 854 DCHECK(rhs->Is(Type::Number())); |
| 843 | 855 |
| 844 if (!lhs->IsInhabited()) return Type::None(); | 856 if (!lhs->IsInhabited()) return Type::None(); |
| 845 | 857 |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 969 return singleton_true(); | 981 return singleton_true(); |
| 970 } | 982 } |
| 971 | 983 |
| 972 Type* OperationTyper::TypeTypeGuard(const Operator* sigma_op, Type* input) { | 984 Type* OperationTyper::TypeTypeGuard(const Operator* sigma_op, Type* input) { |
| 973 return Type::Intersect(input, TypeGuardTypeOf(sigma_op), zone()); | 985 return Type::Intersect(input, TypeGuardTypeOf(sigma_op), zone()); |
| 974 } | 986 } |
| 975 | 987 |
| 976 } // namespace compiler | 988 } // namespace compiler |
| 977 } // namespace internal | 989 } // namespace internal |
| 978 } // namespace v8 | 990 } // namespace v8 |
| OLD | NEW |