Reviewers: jarin,
Description:
[turbofan] Compute tighter ranges for modulus in Typer.
[email protected]
BUG=
Please review this at https://codereview.chromium.org/689133003/
Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Affected files (+55, -7 lines):
M src/compiler/typer.cc
M test/cctest/compiler/test-typer.cc
Index: src/compiler/typer.cc
diff --git a/src/compiler/typer.cc b/src/compiler/typer.cc
index
d7faa5a855b9b7134d651f599f904402b9532a47..c18de34ee95fa4dcbc555de85d8b8030aefd684f
100644
--- a/src/compiler/typer.cc
+++ b/src/compiler/typer.cc
@@ -232,6 +232,7 @@ class Typer::Visitor : public NullNodeVisitor {
static Type* JSSubtractRanger(Type::RangeType*, Type::RangeType*,
Typer*);
static Type* JSMultiplyRanger(Type::RangeType*, Type::RangeType*,
Typer*);
static Type* JSDivideRanger(Type::RangeType*, Type::RangeType*, Typer*);
+ static Type* JSModulusRanger(Type::RangeType*, Type::RangeType*, Typer*);
static Type* JSCompareTyper(Type*, Type*, Typer*);
@@ -984,17 +985,57 @@ Type* Typer::Visitor::JSDivideTyper(Type* lhs, Type*
rhs, Typer* t) {
}
+Type* Typer::Visitor::JSModulusRanger(Type::RangeType* lhs,
+ Type::RangeType* rhs, Typer* t) {
+ double lmin = lhs->Min()->Number();
+ double lmax = lhs->Max()->Number();
+ double rmin = rhs->Min()->Number();
+ double rmax = rhs->Max()->Number();
+
+ double labs = std::max(std::abs(lmin), std::abs(lmax));
+ double rabs = std::max(std::abs(rmin), std::abs(rmax)) - 1;
+ double abs = std::min(labs, rabs);
+ bool maybe_minus_zero = false;
+ double omin = 0;
+ double omax = 0;
+ if (lmin >= 0) { // {lhs} positive.
+ omin = 0;
+ omax = abs;
+ } else if (lmax <= 0) { // {lhs} negative.
+ omin = 0 - abs;
+ omax = 0;
+ maybe_minus_zero = lmin <= omin;
+ } else {
+ omin = 0 - abs;
+ omax = abs;
+ maybe_minus_zero = lmin <= omin;
+ }
+
+ Factory* f = t->isolate()->factory();
+ Type* result = Type::Range(f->NewNumber(omin), f->NewNumber(omax),
t->zone());
+ if (maybe_minus_zero)
+ result = Type::Union(result, Type::MinusZero(), t->zone());
+ return result;
+}
+
+
Type* Typer::Visitor::JSModulusTyper(Type* lhs, Type* rhs, Typer* t) {
lhs = ToNumber(lhs, t);
rhs = ToNumber(rhs, t);
if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN();
- // Division is tricky, so all we do is try ruling out nan.
- // TODO(neis): try ruling out -0 as well?
- bool maybe_nan =
- lhs->Maybe(Type::NaN()) || rhs->Maybe(t->zeroish) ||
- ((lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY) &&
- (rhs->Min() == -V8_INFINITY || rhs->Max() == +V8_INFINITY));
- return maybe_nan ? Type::Number() : Type::OrderedNumber();
+
+ if (lhs->Maybe(Type::NaN()) || rhs->Maybe(t->zeroish) ||
+ lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY) {
+ // Result maybe NaN.
+ return Type::Number();
+ }
+
+ lhs = Rangify(lhs, t);
+ rhs = Rangify(rhs, t);
+ if (lhs->IsRange() && rhs->IsRange()) {
+ return JSModulusRanger(lhs->AsRange(), rhs->AsRange(), t);
+ }
+ return Type::OrderedNumber();
}
Index: test/cctest/compiler/test-typer.cc
diff --git a/test/cctest/compiler/test-typer.cc
b/test/cctest/compiler/test-typer.cc
index
ae65840c702d8b05c51f4c91a140982ec4cbc5b3..618f5c1307db854f3e0e6ae69ce790000b9ebbb5
100644
--- a/test/cctest/compiler/test-typer.cc
+++ b/test/cctest/compiler/test-typer.cc
@@ -4,6 +4,7 @@
#include <functional>
+#include "src/codegen.h"
#include "src/compiler/node-properties-inl.h"
#include "src/compiler/typer.h"
#include "test/cctest/cctest.h"
@@ -216,6 +217,12 @@ TEST(TypeJSDivide) {
}
+TEST(TypeJSModulus) {
+ TyperTester t;
+ t.TestBinaryArithOp(t.javascript_.Modulus(), modulo);
+}
+
+
TEST(TypeJSBitwiseOr) {
TyperTester t;
t.TestBinaryBitOp(t.javascript_.BitwiseOr(), bit_or);
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.