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 856 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
867 // JS bitwise operators. | 867 // JS bitwise operators. |
868 | 868 |
869 | 869 |
870 Type* Typer::Visitor::JSBitwiseOrTyper(Type* lhs, Type* rhs, Typer* t) { | 870 Type* Typer::Visitor::JSBitwiseOrTyper(Type* lhs, Type* rhs, Typer* t) { |
871 lhs = NumberToInt32(ToNumber(lhs, t), t); | 871 lhs = NumberToInt32(ToNumber(lhs, t), t); |
872 rhs = NumberToInt32(ToNumber(rhs, t), t); | 872 rhs = NumberToInt32(ToNumber(rhs, t), t); |
873 double lmin = lhs->Min(); | 873 double lmin = lhs->Min(); |
874 double rmin = rhs->Min(); | 874 double rmin = rhs->Min(); |
875 double lmax = lhs->Max(); | 875 double lmax = lhs->Max(); |
876 double rmax = rhs->Max(); | 876 double rmax = rhs->Max(); |
877 | |
titzer
2015/03/10 07:47:13
Please add unit tests for the typer and mjsunit te
| |
878 // Or-ing with 0 is essentially a conversion to int32, and or-ing | |
879 // with -1 returns -1. | |
880 if (rmin == rmax) { | |
881 if (rmin == 0) { | |
882 return Type::Range(lmin, lmax, t->zone()); | |
883 } | |
884 if (rmin == -1) { | |
885 return Type::Range(rmin, rmax, t->zone()); | |
886 } | |
887 } | |
888 if (lmin == lmax) { | |
889 if (lmin == 0) { | |
890 return Type::Range(rmin, rmax, t->zone()); | |
891 } | |
892 if (lmin == -1) { | |
893 return Type::Range(lmin, lmax, t->zone()); | |
894 } | |
895 } | |
896 | |
897 if (lmin >= 0 && rmin >= 0) { | |
898 // Precise calculation of the result range for positive ranges. | |
899 double min, max; | |
900 int32_t lmin2, lmax2, rmin2, rmax2, bit, mask; | |
901 | |
902 // Calculate the result minimum. | |
903 lmin2 = lmin, lmax2 = lmax, rmin2 = rmin, rmax2 = rmax; | |
904 bit = 0x40000000, mask = 0x3fffffff; | |
905 for (; lmin2 != lmax2 || rmin2 != rmax2; bit >>= 1, mask >>= 1) { | |
906 int32_t lminb = lmin2 & bit; | |
907 int32_t lmaxb = lmax2 & bit; | |
908 int32_t rminb = rmin2 & bit; | |
909 int32_t rmaxb = rmax2 & bit; | |
910 if (lminb != lmaxb || rminb != rmaxb) { | |
911 if (lminb == lmaxb) { | |
912 if (lminb) { | |
913 rmin2 = (rmin2 & ~mask) | bit; | |
914 } else { | |
915 rmax2 = (rmax2 & ~bit) | mask; | |
916 } | |
917 } else if (rminb == rmaxb) { | |
918 if (rminb) { | |
919 lmin2 = (lmin2 & ~mask) | bit; | |
920 } else { | |
921 lmax2 = (lmax2 & ~bit) | mask; | |
922 } | |
923 } else { | |
924 lmax2 = (lmax2 & ~bit) | mask; | |
925 rmax2 = (rmax2 & ~bit) | mask; | |
926 } | |
927 } | |
928 } | |
929 min = lmin2 | rmin2; | |
930 | |
931 // Calculate the result maximum. | |
932 lmin2 = lmin, lmax2 = lmax, rmin2 = rmin, rmax2 = rmax; | |
933 bit = 0x40000000, mask = 0x3fffffff; | |
934 for (; lmin2 != lmax2 || rmin2 != rmax2; bit >>= 1, mask >>= 1) { | |
935 int32_t lminb = lmin2 & bit; | |
936 int32_t lmaxb = lmax2 & bit; | |
937 int32_t rminb = rmin2 & bit; | |
938 int32_t rmaxb = rmax2 & bit; | |
939 if (lminb != lmaxb || rminb != rmaxb) { | |
940 if (lminb == lmaxb) { | |
941 if (lminb) { | |
942 rmax2 = (rmax2 & ~bit) | mask; | |
943 } else { | |
944 rmin2 = (rmin2 & ~mask) | bit; | |
945 } | |
946 } else if (rminb == rmaxb) { | |
947 if (rminb) { | |
948 lmax2 = (lmax2 & ~bit) | mask; | |
949 } else { | |
950 lmin2 = (lmin2 & ~mask) | bit; | |
951 } | |
952 } else { | |
953 lmax2 = lmax2 | mask; | |
954 break; | |
955 } | |
956 } | |
957 } | |
958 max = lmax2 | rmax2; | |
959 | |
960 return Type::Range(min, max, t->zone()); | |
961 } | |
962 | |
877 // Or-ing any two values results in a value no smaller than their minimum. | 963 // Or-ing any two values results in a value no smaller than their minimum. |
878 // Even no smaller than their maximum if both values are non-negative. | 964 double min = std::min(lmin, rmin); |
879 double min = | |
880 lmin >= 0 && rmin >= 0 ? std::max(lmin, rmin) : std::min(lmin, rmin); | |
881 double max = Type::Signed32()->Max(); | 965 double max = Type::Signed32()->Max(); |
882 | 966 |
883 // Or-ing with 0 is essentially a conversion to int32. | |
884 if (rmin == 0 && rmax == 0) { | |
885 min = lmin; | |
886 max = lmax; | |
887 } | |
888 if (lmin == 0 && lmax == 0) { | |
889 min = rmin; | |
890 max = rmax; | |
891 } | |
892 | |
893 if (lmax < 0 || rmax < 0) { | 967 if (lmax < 0 || rmax < 0) { |
894 // Or-ing two values of which at least one is negative results in a negative | 968 // Or-ing two values of which at least one is negative results in a negative |
895 // value. | 969 // value. |
896 max = std::min(max, -1.0); | 970 max = std::min(max, -1.0); |
897 } | 971 } |
898 return Type::Range(min, max, t->zone()); | 972 return Type::Range(min, max, t->zone()); |
899 // TODO(neis): Be precise for singleton inputs, here and elsewhere. | 973 // TODO(neis): Be precise for singleton inputs, here and elsewhere. |
900 } | 974 } |
901 | 975 |
902 | 976 |
(...skipping 1308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2211 TYPED_ARRAYS(TYPED_ARRAY_CASE) | 2285 TYPED_ARRAYS(TYPED_ARRAY_CASE) |
2212 #undef TYPED_ARRAY_CASE | 2286 #undef TYPED_ARRAY_CASE |
2213 } | 2287 } |
2214 } | 2288 } |
2215 return Type::Constant(value, zone()); | 2289 return Type::Constant(value, zone()); |
2216 } | 2290 } |
2217 | 2291 |
2218 } // namespace compiler | 2292 } // namespace compiler |
2219 } // namespace internal | 2293 } // namespace internal |
2220 } // namespace v8 | 2294 } // namespace v8 |
OLD | NEW |