зеркало из https://github.com/mozilla/gecko-dev.git
Beta nodes sholud be able to have infinite ranges, fixes very slow testcase (bug 765119, r=dvander)
This commit is contained in:
Родитель
6000461ba8
Коммит
a57a7456d0
|
@ -2755,9 +2755,9 @@ 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)
|
||||
{
|
||||
}
|
||||
|
@ -2765,9 +2765,9 @@ class MBeta : public MUnaryInstruction
|
|||
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 {
|
||||
|
|
|
@ -162,10 +162,10 @@ RangeAnalysis::addBetaNobes()
|
|||
}
|
||||
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);
|
||||
}
|
||||
|
@ -175,35 +175,34 @@ RangeAnalysis::addBetaNobes()
|
|||
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);
|
||||
}
|
||||
|
@ -290,17 +289,20 @@ Range::unionWith(const Range *other)
|
|||
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
|
||||
|
@ -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 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
|
||||
|
|
|
@ -69,8 +69,8 @@ class Range {
|
|||
bool upper_infinite_;
|
||||
|
||||
public:
|
||||
Range() :
|
||||
lower_(JSVAL_INT_MIN),
|
||||
Range()
|
||||
: lower_(JSVAL_INT_MIN),
|
||||
lower_infinite_(true),
|
||||
upper_(JSVAL_INT_MAX),
|
||||
upper_infinite_(true)
|
||||
|
@ -81,6 +81,13 @@ class Range {
|
|||
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);
|
||||
|
|
Загрузка…
Ссылка в новой задаче