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

Unified Diff: src/compiler/typer.cc

Issue 714413004: [turbofan] More useful typing for And, Or and Shr. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fix the range/bitset subtyping mess-up in bitwise or. Created 6 years, 1 month 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/compiler/change-lowering.cc ('k') | test/cctest/compiler/test-changes-lowering.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/compiler/typer.cc
diff --git a/src/compiler/typer.cc b/src/compiler/typer.cc
index 20a39d94493ff1eed1463e1a142d7cd037c90655..996eecd361caacde8ae062304ac1180d68902e75 100644
--- a/src/compiler/typer.cc
+++ b/src/compiler/typer.cc
@@ -717,16 +717,26 @@ Type* Typer::Visitor::JSBitwiseOrTyper(Type* lhs, Type* rhs, Typer* t) {
double rmax = rhs->Max();
// Or-ing any two values results in a value no smaller than their minimum.
// Even no smaller than their maximum if both values are non-negative.
- Handle<Object> min = f->NewNumber(
- lmin >= 0 && rmin >= 0 ? std::max(lmin, rmin) : std::min(lmin, rmin));
+ double min =
+ lmin >= 0 && rmin >= 0 ? std::max(lmin, rmin) : std::min(lmin, rmin);
+ double max = Type::Signed32()->Max();
+
+ // Or-ing with 0 is essentially a conversion to int32.
+ if (rmin == 0 && rmax == 0) {
+ min = lmin;
+ max = lmax;
+ }
+ if (lmin == 0 && lmax == 0) {
+ min = rmin;
+ max = rmax;
+ }
+
if (lmax < 0 || rmax < 0) {
// Or-ing two values of which at least one is negative results in a negative
// value.
- Handle<Object> max = f->NewNumber(-1);
- return Type::Range(min, max, t->zone());
+ max = std::min(max, -1.0);
}
- Handle<Object> max = f->NewNumber(Type::Signed32()->Max());
- return Type::Range(min, max, t->zone());
+ return Type::Range(f->NewNumber(min), f->NewNumber(max), t->zone());
// TODO(neis): Be precise for singleton inputs, here and elsewhere.
}
@@ -739,18 +749,22 @@ Type* Typer::Visitor::JSBitwiseAndTyper(Type* lhs, Type* rhs, Typer* t) {
double rmin = rhs->Min();
double lmax = lhs->Max();
double rmax = rhs->Max();
+ double min = Type::Signed32()->Min();
// And-ing any two values results in a value no larger than their maximum.
// Even no larger than their minimum if both values are non-negative.
- Handle<Object> max = f->NewNumber(
- lmin >= 0 && rmin >= 0 ? std::min(lmax, rmax) : std::max(lmax, rmax));
- if (lmin >= 0 || rmin >= 0) {
- // And-ing two values of which at least one is non-negative results in a
- // non-negative value.
- Handle<Object> min = f->NewNumber(0);
- return Type::Range(min, max, t->zone());
+ double max =
+ lmin >= 0 && rmin >= 0 ? std::min(lmax, rmax) : std::max(lmax, rmax);
+ // And-ing with a non-negative value x causes the result to be between
+ // zero and x.
+ if (lmin >= 0) {
+ min = 0;
+ max = std::min(max, lmax);
}
- Handle<Object> min = f->NewNumber(Type::Signed32()->Min());
- return Type::Range(min, max, t->zone());
+ if (rmin >= 0) {
+ min = 0;
+ max = std::min(max, rmax);
+ }
+ return Type::Range(f->NewNumber(min), f->NewNumber(max), t->zone());
}
@@ -780,18 +794,31 @@ Type* Typer::Visitor::JSShiftLeftTyper(Type* lhs, Type* rhs, Typer* t) {
Type* Typer::Visitor::JSShiftRightTyper(Type* lhs, Type* rhs, Typer* t) {
lhs = NumberToInt32(ToNumber(lhs, t), t);
- Factory* f = t->isolate()->factory();
+ rhs = NumberToUint32(ToNumber(rhs, t), t);
+ double min = kMinInt;
+ double max = kMaxInt;
if (lhs->Min() >= 0) {
// Right-shifting a non-negative value cannot make it negative, nor larger.
- Handle<Object> min = f->NewNumber(0);
- Handle<Object> max = f->NewNumber(lhs->Max());
- return Type::Range(min, max, t->zone());
+ min = std::max(min, 0.0);
+ max = std::min(max, lhs->Max());
}
if (lhs->Max() < 0) {
// Right-shifting a negative value cannot make it non-negative, nor smaller.
- Handle<Object> min = f->NewNumber(lhs->Min());
- Handle<Object> max = f->NewNumber(-1);
- return Type::Range(min, max, t->zone());
+ min = std::max(min, lhs->Min());
+ max = std::min(max, -1.0);
+ }
+ if (rhs->Min() > 0 && rhs->Max() <= 31) {
+ // Right-shifting by a positive value yields a small integer value.
+ double shift_min = kMinInt >> static_cast<int>(rhs->Min());
+ double shift_max = kMaxInt >> static_cast<int>(rhs->Min());
+ min = std::max(min, shift_min);
+ max = std::min(max, shift_max);
+ }
+ // TODO(jarin) Ideally, the following micro-optimization should be performed
+ // by the type constructor.
+ if (max != Type::Signed32()->Max() || min != Type::Signed32()->Min()) {
+ Factory* f = t->isolate()->factory();
+ return Type::Range(f->NewNumber(min), f->NewNumber(max), t->zone());
}
return Type::Signed32();
}
« no previous file with comments | « src/compiler/change-lowering.cc ('k') | test/cctest/compiler/test-changes-lowering.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698