OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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/base/flags.h" | 5 #include "src/base/flags.h" |
6 #include "src/bootstrapper.h" | 6 #include "src/bootstrapper.h" |
7 #include "src/compiler/graph-reducer.h" | 7 #include "src/compiler/graph-reducer.h" |
8 #include "src/compiler/js-operator.h" | 8 #include "src/compiler/js-operator.h" |
9 #include "src/compiler/node.h" | 9 #include "src/compiler/node.h" |
10 #include "src/compiler/node-properties.h" | 10 #include "src/compiler/node-properties.h" |
(...skipping 882 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
893 | 893 |
894 Type* Typer::Visitor::JSGreaterThanOrEqualTyper( | 894 Type* Typer::Visitor::JSGreaterThanOrEqualTyper( |
895 Type* lhs, Type* rhs, Typer* t) { | 895 Type* lhs, Type* rhs, Typer* t) { |
896 return FalsifyUndefined(Invert(JSCompareTyper(lhs, rhs, t), t), t); | 896 return FalsifyUndefined(Invert(JSCompareTyper(lhs, rhs, t), t), t); |
897 } | 897 } |
898 | 898 |
899 | 899 |
900 // JS bitwise operators. | 900 // JS bitwise operators. |
901 | 901 |
902 | 902 |
| 903 // Calculate the result minimum. The algorithm considers one bit at a time, from |
| 904 // the most significant to least significant, refining a copy of the input |
| 905 // ranges and terminating when the ranges are equal. |
| 906 static uint32_t BitwiseOrLow(uint32_t lmin, uint32_t lmax, |
| 907 uint32_t rmin, uint32_t rmax) { |
| 908 uint32_t bit = 0x80000000, mask = 0x7fffffff; |
| 909 |
| 910 // Loop, terminating when the ranges are equal, moving down one bit on each |
| 911 // iteration. |
| 912 for (; lmin != lmax || rmin != rmax; bit >>= 1, mask >>= 1) { |
| 913 // Mask off the current bit from each range limit. |
| 914 uint32_t lminb = lmin & bit; |
| 915 uint32_t lmaxb = lmax & bit; |
| 916 uint32_t rminb = rmin & bit; |
| 917 uint32_t rmaxb = rmax & bit; |
| 918 // At this point the higher bits of each range are equal so comparing the |
| 919 // current bit between the upper and lower limit can determine if the bit |
| 920 // changes over the range. If the two input bits are both static across |
| 921 // their ranges then this bit result is known and is the logical OR of each. |
| 922 if (lminb != lmaxb || rminb != rmaxb) { |
| 923 if (lminb == lmaxb) { |
| 924 // The lhs bit is static over its range. The rhs bit changes across it's |
| 925 // range. |
| 926 if (lminb) { |
| 927 // The lhs bit is one forcing the result bit to be one. The rhs bit is |
| 928 // not significant to this bit in the result due to the OR |
| 929 // operation. The rhs minimum of the remaining bits is zero which |
| 930 // occurs when this current bit ticks over to one - which must be |
| 931 // within range because the bit changes. When the lower rhs bits are |
| 932 // zero they do not affect the lower lhs bits and the result is known. |
| 933 rmin &= ~mask; |
| 934 break; |
| 935 } else { |
| 936 // The lhs bit is zero so the result bit equals the rhs bit. The result |
| 937 // minimum occurs when the bit is zero so the rhs range can be culled |
| 938 // to highest input that does not give a one in this bit position. This |
| 939 // is achieved by clearing the bit and setting all the lower bits. |
| 940 rmax = (rmax & ~bit) | mask; |
| 941 } |
| 942 } else if (rminb == rmaxb) { |
| 943 // The rhs bit is static over its range. The lhs bit changes across it's |
| 944 // range. Cull the lhs range as above. |
| 945 if (rminb) { |
| 946 lmin &= ~mask; |
| 947 break; |
| 948 } else { |
| 949 lmax = (lmax & ~bit) | mask; |
| 950 } |
| 951 } else { |
| 952 // Both input bits change across their ranges. The result minimum will |
| 953 // occur then the result bit is zero which demands that both input ranges |
| 954 // be zero in this bit and they are culled as above. |
| 955 lmax = (lmax & ~bit) | mask; |
| 956 rmax = (rmax & ~bit) | mask; |
| 957 } |
| 958 } |
| 959 } |
| 960 return lmin | rmin; |
| 961 } |
| 962 |
| 963 |
| 964 // Calculate the result maximum. The algorithm is parallel to the above, but the |
| 965 // logic is somewhat reversed because it is calculating the maximum rather than |
| 966 // the minimum, and it is possible to exit early if both input bits change |
| 967 // across their range. |
| 968 static uint32_t BitwiseOrHigh(uint32_t lmin, uint32_t lmax, |
| 969 uint32_t rmin, uint32_t rmax) { |
| 970 uint32_t bit = 0x80000000, mask = 0x7fffffff; |
| 971 |
| 972 for (; lmin != lmax || rmin != rmax; bit >>= 1, mask >>= 1) { |
| 973 uint32_t lminb = lmin & bit; |
| 974 uint32_t lmaxb = lmax & bit; |
| 975 uint32_t rminb = rmin & bit; |
| 976 uint32_t rmaxb = rmax & bit; |
| 977 if (lminb != lmaxb || rminb != rmaxb) { |
| 978 if (lminb == lmaxb) { |
| 979 if (lminb) { |
| 980 rmax |= mask; |
| 981 break; |
| 982 } else { |
| 983 rmin = (rmin & ~mask) | bit; |
| 984 } |
| 985 } else if (rminb == rmaxb) { |
| 986 if (rminb) { |
| 987 lmax |= mask; |
| 988 break; |
| 989 } else { |
| 990 lmin = (lmin & ~mask) | bit; |
| 991 } |
| 992 } else { |
| 993 // Both input bits change across their ranges. If this bit changes then |
| 994 // all the lower bits also change across both input ranges, and since |
| 995 // the result is one if either is one then the maximum occurs when all |
| 996 // lower bits are one. The lhsUpperBit is already set at this point, so |
| 997 // this bit does not need setting here too, just the lower bits. |
| 998 lmax |= mask; |
| 999 break; |
| 1000 } |
| 1001 } |
| 1002 } |
| 1003 return lmax | rmax; |
| 1004 } |
| 1005 |
| 1006 |
| 1007 IntType JSBitwiseOrIntType(IntType lhs, IntType rhs) { |
| 1008 // Or-ing with 0 is essentially a conversion to int32, and or-ing |
| 1009 // with -1 returns -1. |
| 1010 if (rhs.min == rhs.max) { |
| 1011 if (rhs.min == 0) { |
| 1012 return IntType(lhs.min, lhs.max); |
| 1013 } |
| 1014 if (rhs.min == -1) { |
| 1015 return IntType(rhs.min, rhs.max); |
| 1016 } |
| 1017 } |
| 1018 if (lhs.min == lhs.max) { |
| 1019 if (lhs.min == 0) { |
| 1020 return IntType(rhs.min, rhs.max); |
| 1021 } |
| 1022 if (lhs.min == -1) { |
| 1023 return IntType(lhs.min, lhs.max); |
| 1024 } |
| 1025 } |
| 1026 |
| 1027 // Divide the calculation into sub-ranges that do not change sign. |
| 1028 uint32_t lminp = uint32_t(std::max(lhs.min, 0)); |
| 1029 uint32_t lmaxn = uint32_t(std::min(lhs.max, -1)); |
| 1030 uint32_t rminp = uint32_t(std::max(rhs.min, 0)); |
| 1031 uint32_t rmaxn = uint32_t(std::min(rhs.max, -1)); |
| 1032 int32_t min = kMaxInt, max = kMinInt; |
| 1033 |
| 1034 if (lhs.max >= 0 && rhs.max >= 0) { |
| 1035 min = std::min(min, int32_t(BitwiseOrLow(lminp, lhs.max, rminp, rhs.max))); |
| 1036 max = std::max(max, int32_t(BitwiseOrHigh(lminp, lhs.max, rminp, rhs.max))); |
| 1037 } |
| 1038 if (lhs.max >= 0 && rhs.min < 0) { |
| 1039 min = std::min(min, int32_t(BitwiseOrLow(lminp, lhs.max, rhs.min, rmaxn))); |
| 1040 max = std::max(max, int32_t(BitwiseOrHigh(lminp, lhs.max, rhs.min, rmaxn))); |
| 1041 } |
| 1042 if (lhs.min < 0 && rhs.max >= 0) { |
| 1043 min = std::min(min, int32_t(BitwiseOrLow(lhs.min, lmaxn, rminp, rhs.max))); |
| 1044 max = std::max(max, int32_t(BitwiseOrHigh(lhs.min, lmaxn, rminp, rhs.max))); |
| 1045 } |
| 1046 if (lhs.min < 0 && rhs.min < 0) { |
| 1047 min = std::min(min, int32_t(BitwiseOrLow(lhs.min, lmaxn, rhs.min, rmaxn))); |
| 1048 max = std::max(max, int32_t(BitwiseOrHigh(lhs.min, lmaxn, rhs.min, rmaxn))); |
| 1049 } |
| 1050 DCHECK(max >= min); |
| 1051 |
| 1052 return IntType(min, max); |
| 1053 } |
| 1054 |
| 1055 |
903 Type* Typer::Visitor::JSBitwiseOrTyper(Type* lhs, Type* rhs, Typer* t) { | 1056 Type* Typer::Visitor::JSBitwiseOrTyper(Type* lhs, Type* rhs, Typer* t) { |
904 lhs = NumberToInt32(ToNumber(lhs, t), t); | 1057 lhs = NumberToInt32(ToNumber(lhs, t), t); |
905 rhs = NumberToInt32(ToNumber(rhs, t), t); | 1058 rhs = NumberToInt32(ToNumber(rhs, t), t); |
906 double lmin = lhs->Min(); | 1059 IntType type = JSBitwiseOrIntType(IntType(lhs->Min(), lhs->Max()), |
907 double rmin = rhs->Min(); | 1060 IntType(rhs->Min(), rhs->Max())); |
908 double lmax = lhs->Max(); | 1061 return Type::Range(type.min, type.max, t->zone()); |
909 double rmax = rhs->Max(); | |
910 // Or-ing any two values results in a value no smaller than their minimum. | |
911 // Even no smaller than their maximum if both values are non-negative. | |
912 double min = | |
913 lmin >= 0 && rmin >= 0 ? std::max(lmin, rmin) : std::min(lmin, rmin); | |
914 double max = Type::Signed32()->Max(); | |
915 | |
916 // Or-ing with 0 is essentially a conversion to int32. | |
917 if (rmin == 0 && rmax == 0) { | |
918 min = lmin; | |
919 max = lmax; | |
920 } | |
921 if (lmin == 0 && lmax == 0) { | |
922 min = rmin; | |
923 max = rmax; | |
924 } | |
925 | |
926 if (lmax < 0 || rmax < 0) { | |
927 // Or-ing two values of which at least one is negative results in a negative | |
928 // value. | |
929 max = std::min(max, -1.0); | |
930 } | |
931 return Type::Range(min, max, t->zone()); | |
932 // TODO(neis): Be precise for singleton inputs, here and elsewhere. | |
933 } | 1062 } |
934 | 1063 |
935 | 1064 |
936 Type* Typer::Visitor::JSBitwiseAndTyper(Type* lhs, Type* rhs, Typer* t) { | 1065 Type* Typer::Visitor::JSBitwiseAndTyper(Type* lhs, Type* rhs, Typer* t) { |
937 lhs = NumberToInt32(ToNumber(lhs, t), t); | 1066 lhs = NumberToInt32(ToNumber(lhs, t), t); |
938 rhs = NumberToInt32(ToNumber(rhs, t), t); | 1067 rhs = NumberToInt32(ToNumber(rhs, t), t); |
939 double lmin = lhs->Min(); | 1068 double lmin = lhs->Min(); |
940 double rmin = rhs->Min(); | 1069 double rmin = rhs->Min(); |
941 double lmax = lhs->Max(); | 1070 double lmax = lhs->Max(); |
942 double rmax = rhs->Max(); | 1071 double rmax = rhs->Max(); |
(...skipping 1423 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2366 TYPED_ARRAYS(TYPED_ARRAY_CASE) | 2495 TYPED_ARRAYS(TYPED_ARRAY_CASE) |
2367 #undef TYPED_ARRAY_CASE | 2496 #undef TYPED_ARRAY_CASE |
2368 } | 2497 } |
2369 } | 2498 } |
2370 return Type::Constant(value, zone()); | 2499 return Type::Constant(value, zone()); |
2371 } | 2500 } |
2372 | 2501 |
2373 } // namespace compiler | 2502 } // namespace compiler |
2374 } // namespace internal | 2503 } // namespace internal |
2375 } // namespace v8 | 2504 } // namespace v8 |
OLD | NEW |