Beta nodes sholud be able to have infinite ranges, fixes very slow testcase (bug 765119, r=dvander)
authorMarty Rosenberg <mrosenberg@mozilla.com>
Tue, 02 Oct 2012 04:34:27 -0400
changeset 109618 ddcda23710f428704d5e455abe86947154458829
parent 109617 bcb1272c7b94c70e31333ee2053ec10f9c1c28d6
child 109619 af9e58e861024e230bc10cdd109ac2af159bfa9f
push id23636
push usergsharp@mozilla.com
push dateMon, 08 Oct 2012 08:08:19 +0000
treeherdermozilla-central@24cf40690042 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdvander
bugs765119
milestone18.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Beta nodes sholud be able to have infinite ranges, fixes very slow testcase (bug 765119, r=dvander)
js/src/ion/MIR.h
js/src/ion/RangeAnalysis.cpp
js/src/ion/RangeAnalysis.h
--- a/js/src/ion/MIR.h
+++ b/js/src/ion/MIR.h
@@ -2769,29 +2769,29 @@ class MPhi : public MDefinition, public 
 
 // The goal of a Beta node is to split a def at a conditionally taken
 // branch, so that uses dominated by it have a different name.
 class MBeta : public MUnaryInstruction
 {
   private:
     Range comparison_;
     MDefinition *val_;
-    MBeta(MDefinition *val, int32 low, int32 high)
+    MBeta(MDefinition *val, const Range &comp)
         : MUnaryInstruction(val),
-          comparison_(low, high),
+          comparison_(comp),
           val_(val)
     {
     }
 
   public:
     INSTRUCTION_HEADER(Beta);
     void printOpcode(FILE *fp);
-    static MBeta *New(MDefinition *val, int32 low, int32 high)
+    static MBeta *New(MDefinition *val, const Range &comp)
     {
-        return new MBeta(val, low, high);
+        return new MBeta(val, comp);
     }
 
     AliasSet getAliasSet() const {
         return AliasSet::None();
     }
 
     bool recomputeRange() {
         return range()->update(
--- a/js/src/ion/RangeAnalysis.cpp
+++ b/js/src/ion/RangeAnalysis.cpp
@@ -157,58 +157,57 @@ RangeAnalysis::addBetaNobes()
                 smaller = left;
                 greater = right;
             } else if (JSOP_GT) {
                 smaller = right;
                 greater = left;
             }
             if (smaller && greater) {
                 MBeta *beta;
-                beta = MBeta::New(smaller, JSVAL_INT_MIN, JSVAL_INT_MAX-1);
+                beta = MBeta::New(smaller, Range(JSVAL_INT_MIN, JSVAL_INT_MAX-1));
                 block->insertBefore(*block->begin(), beta);
                 replaceDominatedUsesWith(smaller, beta, block);
-                beta = MBeta::New(greater, JSVAL_INT_MIN+1, JSVAL_INT_MAX);
+                beta = MBeta::New(greater, Range(JSVAL_INT_MIN+1, JSVAL_INT_MAX));
                 block->insertBefore(*block->begin(), beta);
                 replaceDominatedUsesWith(greater, beta, block);
             }
             continue;
         }
 
         JS_ASSERT(val);
 
 
-        int32 low = JSVAL_INT_MIN;
-        int32 high = JSVAL_INT_MAX;
+        Range comp;
         switch (jsop) {
           case JSOP_LE:
-            high = bound;
+            comp.setUpper(bound);
             break;
           case JSOP_LT:
             if (!SafeSub(bound, 1, &bound))
                 break;
-            high = bound;
+            comp.setUpper(bound);
             break;
           case JSOP_GE:
-            low = bound;
+            comp.setLower(bound);
             break;
           case JSOP_GT:
             if (!SafeAdd(bound, 1, &bound))
                 break;
-            low = bound;
+            comp.setLower(bound);
             break;
           case JSOP_EQ:
-            low = bound;
-            high = bound;
+            comp.setLower(bound);
+            comp.setUpper(bound);
           default:
             break; // well, for neq we could have
                    // [-\inf, bound-1] U [bound+1, \inf] but we only use contiguous ranges.
         }
 
         IonSpew(IonSpew_Range, "Adding beta node for %d", val->id());
-        MBeta *beta = MBeta::New(val, low, high);
+        MBeta *beta = MBeta::New(val, comp);
         block->insertBefore(*block->begin(), beta);
         replaceDominatedUsesWith(val, beta, block);
     }
 
     return true;
 }
 
 bool
@@ -285,57 +284,63 @@ Range::unionWith(const Range *other)
     setUpper(Max(upper_, other->upper_));
     lower_infinite_ |= other->lower_infinite_;
     upper_infinite_ |= other->upper_infinite_;
 }
 
 Range
 Range::add(const Range *lhs, const Range *rhs)
 {
-    return Range(
+    Range ret(
         (int64_t)lhs->lower_ + (int64_t)rhs->lower_,
         (int64_t)lhs->upper_ + (int64_t)rhs->upper_);
+    return ret;
 }
 
 Range
 Range::sub(const Range *lhs, const Range *rhs)
 {
-    return Range(
+    Range ret(
         (int64_t)lhs->lower_ - (int64_t)rhs->upper_,
         (int64_t)lhs->upper_ - (int64_t)rhs->lower_);
+    return ret;
+
 }
 
 Range
 Range::mul(const Range *lhs, const Range *rhs)
 {
     int64_t a = (int64_t)lhs->lower_ * (int64_t)rhs->lower_;
     int64_t b = (int64_t)lhs->lower_ * (int64_t)rhs->upper_;
     int64_t c = (int64_t)lhs->upper_ * (int64_t)rhs->lower_;
     int64_t d = (int64_t)lhs->upper_ * (int64_t)rhs->upper_;
-    return Range(
+    Range ret(
         Min( Min(a, b), Min(c, d) ),
         Max( Max(a, b), Max(c, d) ));
+    return ret;
 }
 
 Range
 Range::shl(const Range *lhs, int32 c)
 {
     int32 shift = c & 0x1f;
-    return Range(
+    Range ret(
         (int64_t)lhs->lower_ << shift,
         (int64_t)lhs->upper_ << shift);
+    return ret;
 }
 
 Range
 Range::shr(const Range *lhs, int32 c)
 {
     int32 shift = c & 0x1f;
-    return Range(
+    Range ret(
         (int64_t)lhs->lower_ >> shift,
         (int64_t)lhs->upper_ >> shift);
+    return ret;
 }
 
 bool
 Range::update(const Range *other)
 {
     bool changed =
         lower_ != other->lower_ ||
         lower_infinite_ != other->lower_infinite_ ||
--- a/js/src/ion/RangeAnalysis.h
+++ b/js/src/ion/RangeAnalysis.h
@@ -64,28 +64,35 @@ class Range {
         // 1) lower_infinite == true implies lower_ == JSVAL_INT_MIN
         // 2) upper_infinite == true implies upper_ == JSVAL_INT_MAX
         int32 lower_;
         bool lower_infinite_;
         int32 upper_;
         bool upper_infinite_;
 
     public:
-        Range() :
-            lower_(JSVAL_INT_MIN),
+        Range()
+          : lower_(JSVAL_INT_MIN),
             lower_infinite_(true),
             upper_(JSVAL_INT_MAX),
             upper_infinite_(true)
         {}
 
         Range(int64_t l, int64_t h) {
             setLower(l);
             setUpper(h);
         }
 
+        Range(const Range &other)
+          : lower_(other.lower_),
+            lower_infinite_(other.lower_infinite_),
+            upper_(other.upper_),
+            upper_infinite_(other.upper_infinite_)
+        {}
+
         static int64_t abs64(int64_t x) {
 #ifdef WTF_OS_WINDOWS
             return _abs64(x);
 #else
             return llabs(x);
 #endif
         }