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

Unified Diff: src/compiler/operation-typer.cc

Issue 2074903002: [turbofan] Numeric type feedback for mul, div and mod. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebase Created 4 years, 6 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/compiler/operation-typer.h ('k') | src/compiler/representation-change.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/compiler/operation-typer.cc
diff --git a/src/compiler/operation-typer.cc b/src/compiler/operation-typer.cc
index 16004a047a1c4f8bf0fa2b434ede334ac31895a6..0ab24732c75c7d04817893a39edcd32d71785080 100644
--- a/src/compiler/operation-typer.cc
+++ b/src/compiler/operation-typer.cc
@@ -233,6 +233,36 @@ Type* OperationTyper::ModulusRanger(RangeType* lhs, RangeType* rhs) {
return result;
}
+Type* OperationTyper::MultiplyRanger(Type* lhs, Type* rhs) {
+ double results[4];
+ double lmin = lhs->AsRange()->Min();
+ double lmax = lhs->AsRange()->Max();
+ double rmin = rhs->AsRange()->Min();
+ double rmax = rhs->AsRange()->Max();
+ results[0] = lmin * rmin;
+ results[1] = lmin * rmax;
+ results[2] = lmax * rmin;
+ results[3] = lmax * rmax;
+ // If the result may be nan, we give up on calculating a precise type,
+ // because
+ // the discontinuity makes it too complicated. Note that even if none of
+ // the
+ // "results" above is nan, the actual result may still be, so we have to do
+ // a
+ // different check:
+ bool maybe_nan = (lhs->Maybe(cache_.kSingletonZero) &&
+ (rmin == -V8_INFINITY || rmax == +V8_INFINITY)) ||
+ (rhs->Maybe(cache_.kSingletonZero) &&
+ (lmin == -V8_INFINITY || lmax == +V8_INFINITY));
+ if (maybe_nan) return cache_.kIntegerOrMinusZeroOrNaN; // Giving up.
+ bool maybe_minuszero = (lhs->Maybe(cache_.kSingletonZero) && rmin < 0) ||
+ (rhs->Maybe(cache_.kSingletonZero) && lmin < 0);
+ Type* range =
+ Type::Range(array_min(results, 4), array_max(results, 4), zone());
+ return maybe_minuszero ? Type::Union(range, Type::MinusZero(), zone())
+ : range;
+}
+
Type* OperationTyper::ToNumber(Type* type) {
if (type->Is(Type::Number())) return type;
if (type->Is(Type::NullOrUndefined())) {
@@ -282,6 +312,50 @@ Type* OperationTyper::NumericSubtract(Type* lhs, Type* rhs) {
return Type::Number();
}
+Type* OperationTyper::NumericMultiply(Type* lhs, Type* rhs) {
+ DCHECK(lhs->Is(Type::Number()));
+ DCHECK(rhs->Is(Type::Number()));
+ lhs = Rangify(lhs);
+ rhs = Rangify(rhs);
+ if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN();
+ if (lhs->IsRange() && rhs->IsRange()) {
+ return MultiplyRanger(lhs, rhs);
+ }
+ return Type::Number();
+}
+
+Type* OperationTyper::NumericDivide(Type* lhs, Type* rhs) {
+ DCHECK(lhs->Is(Type::Number()));
+ DCHECK(rhs->Is(Type::Number()));
+
+ if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN();
+ // Division is tricky, so all we do is try ruling out nan.
+ bool maybe_nan =
+ lhs->Maybe(Type::NaN()) || rhs->Maybe(cache_.kZeroish) ||
+ ((lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY) &&
+ (rhs->Min() == -V8_INFINITY || rhs->Max() == +V8_INFINITY));
+ return maybe_nan ? Type::Number() : Type::OrderedNumber();
+}
+
+Type* OperationTyper::NumericModulus(Type* lhs, Type* rhs) {
+ DCHECK(lhs->Is(Type::Number()));
+ DCHECK(rhs->Is(Type::Number()));
+ if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN();
+
+ if (lhs->Maybe(Type::NaN()) || rhs->Maybe(cache_.kZeroish) ||
+ lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY) {
+ // Result maybe NaN.
+ return Type::Number();
+ }
+
+ lhs = Rangify(lhs);
+ rhs = Rangify(rhs);
+ if (lhs->IsRange() && rhs->IsRange()) {
+ return ModulusRanger(lhs->AsRange(), rhs->AsRange());
+ }
+ return Type::OrderedNumber();
+}
+
Type* OperationTyper::ToPrimitive(Type* type) {
if (type->Is(Type::Primitive()) && !type->Maybe(Type::Receiver())) {
return type;
« no previous file with comments | « src/compiler/operation-typer.h ('k') | src/compiler/representation-change.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698