зеркало из https://github.com/mozilla/gecko-dev.git
Bug 915846 - IonMonkey: Introduce several new Range predicate helper functions. r=nbp
This commit is contained in:
Родитель
9d8d65f46f
Коммит
7b632205a2
|
@ -39,7 +39,10 @@ using namespace js;
|
|||
using namespace js::jit;
|
||||
|
||||
using mozilla::DebugOnly;
|
||||
using mozilla::DoubleExponentBias;
|
||||
using mozilla::Maybe;
|
||||
using mozilla::NegativeInfinity;
|
||||
using mozilla::PositiveInfinity;
|
||||
using JS::GenericNaN;
|
||||
|
||||
namespace js {
|
||||
|
@ -7517,7 +7520,7 @@ bool
|
|||
CodeGenerator::emitAssertRangeI(const Range *r, Register input)
|
||||
{
|
||||
// Check the lower bound.
|
||||
if (r->lower() != INT32_MIN) {
|
||||
if (r->hasInt32LowerBound() && r->lower() > INT32_MIN) {
|
||||
Label success;
|
||||
masm.branch32(Assembler::GreaterThanOrEqual, input, Imm32(r->lower()), &success);
|
||||
masm.breakpoint();
|
||||
|
@ -7525,7 +7528,7 @@ CodeGenerator::emitAssertRangeI(const Range *r, Register input)
|
|||
}
|
||||
|
||||
// Check the upper bound.
|
||||
if (r->upper() != INT32_MAX) {
|
||||
if (r->hasInt32UpperBound() && r->upper() < INT32_MAX) {
|
||||
Label success;
|
||||
masm.branch32(Assembler::LessThanOrEqual, input, Imm32(r->upper()), &success);
|
||||
masm.breakpoint();
|
||||
|
@ -7566,7 +7569,7 @@ CodeGenerator::emitAssertRangeD(const Range *r, FloatRegister input, FloatRegist
|
|||
// This code does not yet check r->canHaveFractionalPart(). This would require new
|
||||
// assembler interfaces to make rounding instructions available.
|
||||
|
||||
if (!r->canBeInfiniteOrNaN()) {
|
||||
if (!r->hasInt32Bounds() && !r->canBeInfiniteOrNaN() && r->exponent() < DoubleExponentBias) {
|
||||
// Check the bounds implied by the maximum exponent.
|
||||
Label exponentLoOk;
|
||||
masm.loadConstantDouble(pow(2.0, r->exponent() + 1), temp);
|
||||
|
@ -7581,6 +7584,27 @@ CodeGenerator::emitAssertRangeD(const Range *r, FloatRegister input, FloatRegist
|
|||
masm.branchDouble(Assembler::DoubleGreaterThanOrEqual, input, temp, &exponentHiOk);
|
||||
masm.breakpoint();
|
||||
masm.bind(&exponentHiOk);
|
||||
} else if (!r->hasInt32Bounds() && !r->canBeNaN()) {
|
||||
// If we think the value can't be NaN, check that it isn't.
|
||||
Label notnan;
|
||||
masm.branchDouble(Assembler::DoubleOrdered, input, input, ¬nan);
|
||||
masm.breakpoint();
|
||||
masm.bind(¬nan);
|
||||
|
||||
// If we think the value also can't be an infinity, check that it isn't.
|
||||
if (!r->canBeInfiniteOrNaN()) {
|
||||
Label notposinf;
|
||||
masm.loadConstantDouble(PositiveInfinity(), temp);
|
||||
masm.branchDouble(Assembler::DoubleLessThan, input, temp, ¬posinf);
|
||||
masm.breakpoint();
|
||||
masm.bind(¬posinf);
|
||||
|
||||
Label notneginf;
|
||||
masm.loadConstantDouble(NegativeInfinity(), temp);
|
||||
masm.branchDouble(Assembler::DoubleGreaterThan, input, temp, ¬neginf);
|
||||
masm.breakpoint();
|
||||
masm.bind(¬neginf);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
@ -674,9 +674,7 @@ Range::ursh(const Range *lhs, int32_t c)
|
|||
|
||||
// If the value is always non-negative or always negative, we can simply
|
||||
// compute the correct range by shifting.
|
||||
if ((lhs->lower_ >= 0 && lhs->hasInt32UpperBound()) ||
|
||||
(lhs->upper_ < 0 && lhs->hasInt32LowerBound()))
|
||||
{
|
||||
if (lhs->isFiniteNonNegative() || lhs->isFiniteNegative()) {
|
||||
return Range::NewUInt32Range(
|
||||
uint32_t(lhs->lower_) >> shift,
|
||||
uint32_t(lhs->upper_) >> shift);
|
||||
|
@ -705,7 +703,7 @@ Range::rsh(const Range *lhs, const Range *rhs)
|
|||
Range *
|
||||
Range::ursh(const Range *lhs, const Range *rhs)
|
||||
{
|
||||
return Range::NewUInt32Range(0, (lhs->lower() >= 0 && lhs->hasInt32UpperBound()) ? lhs->upper() : UINT32_MAX);
|
||||
return Range::NewUInt32Range(0, lhs->isFiniteNonNegative() ? lhs->upper() : UINT32_MAX);
|
||||
}
|
||||
|
||||
Range *
|
||||
|
@ -752,19 +750,10 @@ Range::max(const Range *lhs, const Range *rhs)
|
|||
bool
|
||||
Range::negativeZeroMul(const Range *lhs, const Range *rhs)
|
||||
{
|
||||
// Both values are positive
|
||||
if (lhs->lower_ >= 0 && rhs->lower_ >= 0)
|
||||
return false;
|
||||
|
||||
// Both values are negative (non zero)
|
||||
if (lhs->upper_ < 0 && rhs->upper_ < 0)
|
||||
return false;
|
||||
|
||||
// One operand is positive (non zero)
|
||||
if (lhs->lower_ > 0 || rhs->lower_ > 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
// The result can only be negative zero if both sides are finite and they
|
||||
// have differing signs.
|
||||
return (lhs->canBeFiniteNegative() && rhs->canBeFiniteNonNegative()) ||
|
||||
(rhs->canBeFiniteNegative() && lhs->canBeFiniteNonNegative());
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -2202,23 +2191,25 @@ RangeAnalysis::truncate()
|
|||
void
|
||||
MInArray::collectRangeInfo()
|
||||
{
|
||||
needsNegativeIntCheck_ = !index()->range() || index()->range()->lower() < 0;
|
||||
needsNegativeIntCheck_ = !index()->range() || !index()->range()->isFiniteNonNegative();
|
||||
}
|
||||
|
||||
void
|
||||
MLoadElementHole::collectRangeInfo()
|
||||
{
|
||||
needsNegativeIntCheck_ = !index()->range() || index()->range()->lower() < 0;
|
||||
needsNegativeIntCheck_ = !index()->range() || !index()->range()->isFiniteNonNegative();
|
||||
}
|
||||
|
||||
void
|
||||
MMod::collectRangeInfo()
|
||||
{
|
||||
canBeNegativeDividend_ = !lhs()->range() || lhs()->range()->lower() < 0;
|
||||
canBeNegativeDividend_ = !lhs()->range() || !lhs()->range()->isFiniteNonNegative();
|
||||
}
|
||||
|
||||
void
|
||||
MBoundsCheckLower::collectRangeInfo()
|
||||
{
|
||||
fallible_ = !index()->range() || index()->range()->lower() < minimum_;
|
||||
fallible_ = !index()->range() ||
|
||||
!index()->range()->hasInt32LowerBound() ||
|
||||
index()->range()->lower() < minimum_;
|
||||
}
|
||||
|
|
|
@ -367,6 +367,28 @@ class Range : public TempObject {
|
|||
return upper_;
|
||||
}
|
||||
|
||||
// Test whether all values in this range can are finite and negative.
|
||||
bool isFiniteNegative() const {
|
||||
return upper_ < 0 && !canBeInfiniteOrNaN();
|
||||
}
|
||||
|
||||
// Test whether all values in this range can are finite and non-negative.
|
||||
bool isFiniteNonNegative() const {
|
||||
return lower_ >= 0 && !canBeInfiniteOrNaN();
|
||||
}
|
||||
|
||||
// Test whether a value in this range can possibly be a finite
|
||||
// negative value.
|
||||
bool canBeFiniteNegative() const {
|
||||
return lower_ < 0;
|
||||
}
|
||||
|
||||
// Test whether a value in this range can possibly be a finite
|
||||
// non-negative value.
|
||||
bool canBeFiniteNonNegative() const {
|
||||
return upper_ >= 0;
|
||||
}
|
||||
|
||||
void setLower(int64_t x) {
|
||||
setLowerInit(x);
|
||||
rectifyExponent();
|
||||
|
|
Загрузка…
Ссылка в новой задаче