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 |