Beta nodes sholud be able to have infinite ranges, fixes very slow testcase (bug 765119, r=dvander)

This commit is contained in:
Marty Rosenberg 2012-10-02 04:34:27 -04:00
parent 97d90653ab
commit ccf9962550
3 changed files with 34 additions and 22 deletions

View File

@ -2774,9 +2774,9 @@ class MBeta : public MUnaryInstruction
private: private:
Range comparison_; Range comparison_;
MDefinition *val_; MDefinition *val_;
MBeta(MDefinition *val, int32 low, int32 high) MBeta(MDefinition *val, const Range &comp)
: MUnaryInstruction(val), : MUnaryInstruction(val),
comparison_(low, high), comparison_(comp),
val_(val) val_(val)
{ {
} }
@ -2784,9 +2784,9 @@ class MBeta : public MUnaryInstruction
public: public:
INSTRUCTION_HEADER(Beta); INSTRUCTION_HEADER(Beta);
void printOpcode(FILE *fp); 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 { AliasSet getAliasSet() const {

View File

@ -162,10 +162,10 @@ RangeAnalysis::addBetaNobes()
} }
if (smaller && greater) { if (smaller && greater) {
MBeta *beta; 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); block->insertBefore(*block->begin(), beta);
replaceDominatedUsesWith(smaller, beta, block); 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); block->insertBefore(*block->begin(), beta);
replaceDominatedUsesWith(greater, beta, block); replaceDominatedUsesWith(greater, beta, block);
} }
@ -175,35 +175,34 @@ RangeAnalysis::addBetaNobes()
JS_ASSERT(val); JS_ASSERT(val);
int32 low = JSVAL_INT_MIN; Range comp;
int32 high = JSVAL_INT_MAX;
switch (jsop) { switch (jsop) {
case JSOP_LE: case JSOP_LE:
high = bound; comp.setUpper(bound);
break; break;
case JSOP_LT: case JSOP_LT:
if (!SafeSub(bound, 1, &bound)) if (!SafeSub(bound, 1, &bound))
break; break;
high = bound; comp.setUpper(bound);
break; break;
case JSOP_GE: case JSOP_GE:
low = bound; comp.setLower(bound);
break; break;
case JSOP_GT: case JSOP_GT:
if (!SafeAdd(bound, 1, &bound)) if (!SafeAdd(bound, 1, &bound))
break; break;
low = bound; comp.setLower(bound);
break; break;
case JSOP_EQ: case JSOP_EQ:
low = bound; comp.setLower(bound);
high = bound; comp.setUpper(bound);
default: default:
break; // well, for neq we could have break; // well, for neq we could have
// [-\inf, bound-1] U [bound+1, \inf] but we only use contiguous ranges. // [-\inf, bound-1] U [bound+1, \inf] but we only use contiguous ranges.
} }
IonSpew(IonSpew_Range, "Adding beta node for %d", val->id()); 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); block->insertBefore(*block->begin(), beta);
replaceDominatedUsesWith(val, beta, block); replaceDominatedUsesWith(val, beta, block);
} }
@ -290,17 +289,20 @@ Range::unionWith(const Range *other)
Range Range
Range::add(const Range *lhs, const Range *rhs) Range::add(const Range *lhs, const Range *rhs)
{ {
return Range( Range ret(
(int64_t)lhs->lower_ + (int64_t)rhs->lower_, (int64_t)lhs->lower_ + (int64_t)rhs->lower_,
(int64_t)lhs->upper_ + (int64_t)rhs->upper_); (int64_t)lhs->upper_ + (int64_t)rhs->upper_);
return ret;
} }
Range Range
Range::sub(const Range *lhs, const Range *rhs) Range::sub(const Range *lhs, const Range *rhs)
{ {
return Range( Range ret(
(int64_t)lhs->lower_ - (int64_t)rhs->upper_, (int64_t)lhs->lower_ - (int64_t)rhs->upper_,
(int64_t)lhs->upper_ - (int64_t)rhs->lower_); (int64_t)lhs->upper_ - (int64_t)rhs->lower_);
return ret;
} }
Range Range
@ -310,27 +312,30 @@ Range::mul(const Range *lhs, const Range *rhs)
int64_t b = (int64_t)lhs->lower_ * (int64_t)rhs->upper_; int64_t b = (int64_t)lhs->lower_ * (int64_t)rhs->upper_;
int64_t c = (int64_t)lhs->upper_ * (int64_t)rhs->lower_; int64_t c = (int64_t)lhs->upper_ * (int64_t)rhs->lower_;
int64_t d = (int64_t)lhs->upper_ * (int64_t)rhs->upper_; int64_t d = (int64_t)lhs->upper_ * (int64_t)rhs->upper_;
return Range( Range ret(
Min( Min(a, b), Min(c, d) ), Min( Min(a, b), Min(c, d) ),
Max( Max(a, b), Max(c, d) )); Max( Max(a, b), Max(c, d) ));
return ret;
} }
Range Range
Range::shl(const Range *lhs, int32 c) Range::shl(const Range *lhs, int32 c)
{ {
int32 shift = c & 0x1f; int32 shift = c & 0x1f;
return Range( Range ret(
(int64_t)lhs->lower_ << shift, (int64_t)lhs->lower_ << shift,
(int64_t)lhs->upper_ << shift); (int64_t)lhs->upper_ << shift);
return ret;
} }
Range Range
Range::shr(const Range *lhs, int32 c) Range::shr(const Range *lhs, int32 c)
{ {
int32 shift = c & 0x1f; int32 shift = c & 0x1f;
return Range( Range ret(
(int64_t)lhs->lower_ >> shift, (int64_t)lhs->lower_ >> shift,
(int64_t)lhs->upper_ >> shift); (int64_t)lhs->upper_ >> shift);
return ret;
} }
bool bool

View File

@ -69,8 +69,8 @@ class Range {
bool upper_infinite_; bool upper_infinite_;
public: public:
Range() : Range()
lower_(JSVAL_INT_MIN), : lower_(JSVAL_INT_MIN),
lower_infinite_(true), lower_infinite_(true),
upper_(JSVAL_INT_MAX), upper_(JSVAL_INT_MAX),
upper_infinite_(true) upper_infinite_(true)
@ -81,6 +81,13 @@ class Range {
setUpper(h); 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) { static int64_t abs64(int64_t x) {
#ifdef WTF_OS_WINDOWS #ifdef WTF_OS_WINDOWS
return _abs64(x); return _abs64(x);