Bug 923659 - IonMonkey: Use the Range constructor which takes an MDefinition instead of calling range() directly to determine operand ranges. r=nbp

This commit is contained in:
Dan Gohman 2013-10-15 20:49:43 -07:00
Родитель b56ccce6c7
Коммит 12f63606a4
3 изменённых файлов: 34 добавлений и 16 удалений

Просмотреть файл

@ -359,6 +359,10 @@ class MDefinition : public MNode
return trackedPc_;
}
// Return the range of this value, *before* any bailout checks. Contrast
// this with the type() method, and the Range constructor which takes an
// MDefinition*, which describe the value *after* any bailout checks.
//
// Warning: Range analysis is removing the bit-operations such as '| 0' at
// the end of the transformations. Using this function to analyse any
// operands after the truncate phase of the range analysis will lead to
@ -438,6 +442,12 @@ class MDefinition : public MNode
MIR_FLAG_LIST(FLAG_ACCESSOR)
#undef FLAG_ACCESSOR
// Return the type of this value. This may be speculative, and enforced
// dynamically with the use of bailout checks. If all the bailout checks
// pass, the value will have this type.
//
// Unless this is an MUrsh, which, as a special case, may return a value
// in (INT32_MAX,UINT32_MAX] even when its type() is MIRType_Int32.
MIRType type() const {
return resultType_;
}

Просмотреть файл

@ -838,17 +838,17 @@ MPhi::computeRange()
if (isOSRLikeValue(getOperand(i)))
continue;
Range *input = getOperand(i)->range();
// Peek at the pre-bailout range so we can take a short-cut; if any of
// the operands has an unknown range, this phi has an unknown range.
if (!getOperand(i)->range())
return;
if (!input) {
range = nullptr;
break;
}
Range input(getOperand(i));
if (range)
range->unionWith(input);
range->unionWith(&input);
else
range = new Range(*input);
range = new Range(input);
}
setRange(range);
@ -859,7 +859,8 @@ MBeta::computeRange()
{
bool emptyRange = false;
Range *range = Range::intersect(getOperand(0)->range(), comparison_, &emptyRange);
Range opRange(getOperand(0));
Range *range = Range::intersect(&opRange, comparison_, &emptyRange);
if (emptyRange) {
IonSpew(IonSpew_Range, "Marking block for inst %d unexitable", id());
block()->setEarlyAbort();
@ -2156,7 +2157,7 @@ static void
RemoveTruncatesOnOutput(MInstruction *truncated)
{
JS_ASSERT(truncated->type() == MIRType_Int32);
JS_ASSERT_IF(truncated->range(), truncated->range()->isInt32());
JS_ASSERT(Range(truncated).isInt32());
for (MUseDefIterator use(truncated); use; use++) {
MDefinition *def = use.def();
@ -2226,7 +2227,9 @@ RangeAnalysis::truncate()
}
// Set truncated flag if range analysis ensure that it has no
// rounding errors and no fractional part.
// rounding errors and no fractional part. Note that we can't use
// the MDefinition Range constructor, because we need to know if
// the value will have rounding errors before any bailout checks.
const Range *r = iter->range();
bool canHaveRoundingErrors = !r || r->canHaveRoundingErrors();
@ -2299,25 +2302,27 @@ RangeAnalysis::truncate()
void
MInArray::collectRangeInfo()
{
needsNegativeIntCheck_ = !index()->range() || !index()->range()->isFiniteNonNegative();
Range indexRange(index());
needsNegativeIntCheck_ = !indexRange.isFiniteNonNegative();
}
void
MLoadElementHole::collectRangeInfo()
{
needsNegativeIntCheck_ = !index()->range() || !index()->range()->isFiniteNonNegative();
Range indexRange(index());
needsNegativeIntCheck_ = !indexRange.isFiniteNonNegative();
}
void
MMod::collectRangeInfo()
{
canBeNegativeDividend_ = !lhs()->range() || !lhs()->range()->isFiniteNonNegative();
Range lhsRange(lhs());
canBeNegativeDividend_ = !lhsRange.isFiniteNonNegative();
}
void
MBoundsCheckLower::collectRangeInfo()
{
fallible_ = !index()->range() ||
!index()->range()->hasInt32LowerBound() ||
index()->range()->lower() < minimum_;
Range indexRange(index());
fallible_ = !indexRange.hasInt32LowerBound() || indexRange.lower() < minimum_;
}

Просмотреть файл

@ -307,6 +307,9 @@ class Range : public TempObject {
assertInvariants();
}
// Construct a range from the given MDefinition. This differs from the
// MDefinition's range() method in that it describes the range of values
// *after* any bailout checks.
Range(const MDefinition *def);
static Range *NewInt32Range(int32_t l, int32_t h) {