Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(153)

Side by Side Diff: src/compiler/typer.cc

Issue 1112123002: Precise bitwise-xor derived result type for all int32 input types. Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Split the bitwise-xor result type derivation into a separate function. Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698