Chromium Code Reviews| 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 941 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 952 max = std::min(max, lmax); | 952 max = std::min(max, lmax); |
| 953 } | 953 } |
| 954 if (rmin >= 0) { | 954 if (rmin >= 0) { |
| 955 min = 0; | 955 min = 0; |
| 956 max = std::min(max, rmax); | 956 max = std::min(max, rmax); |
| 957 } | 957 } |
| 958 return Type::Range(min, max, t->zone()); | 958 return Type::Range(min, max, t->zone()); |
| 959 } | 959 } |
| 960 | 960 |
| 961 | 961 |
| 962 static uint32_t BitwiseXorLow(uint32_t lmin, uint32_t lmax, | |
| 963 uint32_t rmin, uint32_t rmax) { | |
|
titzer
2015/05/13 14:44:37
Maybe pull these methods into a separate file with
| |
| 964 uint32_t bit = 0x80000000, mask = 0x7fffffff; | |
| 965 | |
| 966 for (; lmin != lmax || rmin != rmax; bit >>= 1, mask >>= 1) { | |
| 967 uint32_t lminb = lmin & bit; | |
| 968 uint32_t lmaxb = lmax & bit; | |
| 969 uint32_t rminb = rmin & bit; | |
| 970 uint32_t rmaxb = rmax & bit; | |
| 971 if (lminb != lmaxb || rminb != rmaxb) { | |
| 972 if (lminb == lmaxb) { | |
| 973 if (lminb) { | |
| 974 rmin = (rmin & ~mask) | bit; | |
| 975 } else { | |
| 976 rmax = (rmax & ~bit) | mask; | |
| 977 } | |
| 978 } else if (rminb == rmaxb) { | |
| 979 if (rminb) { | |
| 980 lmin = (lmin & ~mask) | bit; | |
| 981 } else { | |
| 982 lmax = (lmax & ~bit) | mask; | |
| 983 } | |
| 984 } else { | |
| 985 lmax = (lmax & ~bit) | mask; | |
| 986 rmax = (rmax & ~bit) | mask; | |
| 987 } | |
| 988 } | |
| 989 } | |
| 990 return lmin ^ rmin; | |
| 991 } | |
| 992 | |
| 993 | |
| 994 static uint32_t BitwiseXorHigh(uint32_t lmin, uint32_t lmax, | |
| 995 uint32_t rmin, uint32_t rmax) { | |
| 996 uint32_t bit = 0x80000000, mask = 0x7fffffff; | |
| 997 | |
| 998 for (; lmin != lmax || rmin != rmax; bit >>= 1, mask >>= 1) { | |
| 999 uint32_t lminb = lmin & bit; | |
| 1000 uint32_t lmaxb = lmax & bit; | |
| 1001 uint32_t rminb = rmin & bit; | |
| 1002 uint32_t rmaxb = rmax & bit; | |
| 1003 if (lminb != lmaxb || rminb != rmaxb) { | |
| 1004 if (lminb == lmaxb) { | |
| 1005 if (lminb) { | |
| 1006 rmax = (rmax & ~bit) | mask; | |
| 1007 } else { | |
| 1008 rmin = (rmin & ~mask) | bit; | |
| 1009 } | |
| 1010 } else if (rminb == rmaxb) { | |
| 1011 if (rminb) { | |
| 1012 lmax = (lmax & ~bit) | mask; | |
| 1013 } else { | |
| 1014 lmin = (lmin & ~mask) | bit; | |
| 1015 } | |
| 1016 } else { | |
| 1017 lmax = (lmax & ~bit) | mask; | |
| 1018 rmin = (rmin & ~mask) | bit; | |
| 1019 } | |
| 1020 } | |
| 1021 } | |
| 1022 return lmax ^ rmax; | |
| 1023 } | |
| 1024 | |
| 1025 | |
| 1026 IntType JSBitwiseXorIntType(IntType lhs, IntType rhs) { | |
| 1027 uint32_t lminp = uint32_t(std::max(lhs.min, 0)); | |
| 1028 uint32_t lmaxn = uint32_t(std::min(lhs.max, -1)); | |
| 1029 uint32_t rminp = uint32_t(std::max(rhs.min, 0)); | |
| 1030 uint32_t rmaxn = uint32_t(std::min(rhs.max, -1)); | |
| 1031 int32_t min = kMaxInt, max = kMinInt; | |
| 1032 | |
| 1033 if (lhs.max >= 0 && rhs.max >= 0) { | |
| 1034 min = std::min(min, int32_t(BitwiseXorLow(lminp, lhs.max, | |
| 1035 rminp, rhs.max))); | |
| 1036 max = std::max(max, int32_t(BitwiseXorHigh(lminp, lhs.max, | |
| 1037 rminp, rhs.max))); | |
| 1038 } | |
| 1039 if (lhs.max >= 0 && rhs.min < 0) { | |
| 1040 min = std::min(min, int32_t(BitwiseXorLow(lminp, lhs.max, | |
| 1041 rhs.min, rmaxn))); | |
| 1042 max = std::max(max, int32_t(BitwiseXorHigh(lminp, lhs.max, | |
| 1043 rhs.min, rmaxn))); | |
| 1044 } | |
| 1045 if (lhs.min < 0 && rhs.max >= 0) { | |
| 1046 min = std::min(min, int32_t(BitwiseXorLow(lhs.min, lmaxn, | |
| 1047 rminp, rhs.max))); | |
| 1048 max = std::max(max, int32_t(BitwiseXorHigh(lhs.min, lmaxn, | |
| 1049 rminp, rhs.max))); | |
| 1050 } | |
| 1051 if (lhs.min < 0 && rhs.min < 0) { | |
| 1052 min = std::min(min, int32_t(BitwiseXorLow(lhs.min, lmaxn, | |
| 1053 rhs.min, rmaxn))); | |
| 1054 max = std::max(max, int32_t(BitwiseXorHigh(lhs.min, lmaxn, | |
| 1055 rhs.min, rmaxn))); | |
| 1056 } | |
| 1057 DCHECK(max >= min); | |
| 1058 | |
| 1059 return IntType(min, max); | |
| 1060 } | |
| 1061 | |
| 1062 | |
| 962 Type* Typer::Visitor::JSBitwiseXorTyper(Type* lhs, Type* rhs, Typer* t) { | 1063 Type* Typer::Visitor::JSBitwiseXorTyper(Type* lhs, Type* rhs, Typer* t) { |
| 963 lhs = NumberToInt32(ToNumber(lhs, t), t); | 1064 lhs = NumberToInt32(ToNumber(lhs, t), t); |
| 964 rhs = NumberToInt32(ToNumber(rhs, t), t); | 1065 rhs = NumberToInt32(ToNumber(rhs, t), t); |
| 965 double lmin = lhs->Min(); | 1066 IntType type = JSBitwiseXorIntType(IntType(lhs->Min(), lhs->Max()), |
| 966 double rmin = rhs->Min(); | 1067 IntType(rhs->Min(), rhs->Max())); |
| 967 double lmax = lhs->Max(); | 1068 return Type::Range(type.min, type.max, t->zone()); |
| 968 double rmax = rhs->Max(); | |
| 969 if ((lmin >= 0 && rmin >= 0) || (lmax < 0 && rmax < 0)) { | |
| 970 // Xor-ing negative or non-negative values results in a non-negative value. | |
| 971 return Type::Unsigned31(); | |
| 972 } | |
| 973 if ((lmax < 0 && rmin >= 0) || (lmin >= 0 && rmax < 0)) { | |
| 974 // Xor-ing a negative and a non-negative value results in a negative value. | |
| 975 // TODO(jarin) Use a range here. | |
| 976 return Type::Negative32(); | |
| 977 } | |
| 978 return Type::Signed32(); | |
| 979 } | 1069 } |
| 980 | 1070 |
| 981 | 1071 |
| 982 Type* Typer::Visitor::JSShiftLeftTyper(Type* lhs, Type* rhs, Typer* t) { | 1072 Type* Typer::Visitor::JSShiftLeftTyper(Type* lhs, Type* rhs, Typer* t) { |
| 983 return Type::Signed32(); | 1073 return Type::Signed32(); |
| 984 } | 1074 } |
| 985 | 1075 |
| 986 | 1076 |
| 987 Type* Typer::Visitor::JSShiftRightTyper(Type* lhs, Type* rhs, Typer* t) { | 1077 Type* Typer::Visitor::JSShiftRightTyper(Type* lhs, Type* rhs, Typer* t) { |
| 988 lhs = NumberToInt32(ToNumber(lhs, t), t); | 1078 lhs = NumberToInt32(ToNumber(lhs, t), t); |
| (...skipping 1377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2366 TYPED_ARRAYS(TYPED_ARRAY_CASE) | 2456 TYPED_ARRAYS(TYPED_ARRAY_CASE) |
| 2367 #undef TYPED_ARRAY_CASE | 2457 #undef TYPED_ARRAY_CASE |
| 2368 } | 2458 } |
| 2369 } | 2459 } |
| 2370 return Type::Constant(value, zone()); | 2460 return Type::Constant(value, zone()); |
| 2371 } | 2461 } |
| 2372 | 2462 |
| 2373 } // namespace compiler | 2463 } // namespace compiler |
| 2374 } // namespace internal | 2464 } // namespace internal |
| 2375 } // namespace v8 | 2465 } // namespace v8 |
| OLD | NEW |