Add a bunch of features to range analysis to make it optimize more. (bug 765119, r=jandem)

This commit is contained in:
Marty Rosenberg 2012-10-02 04:34:28 -04:00
parent 0ae2ada192
commit df22f16de7
5 changed files with 46 additions and 24 deletions

View File

@ -255,7 +255,8 @@ JSONSpewer::spewMDef(MDefinition *def)
integerValue(use.def()->id());
endList();
stringProperty("type", StringFromMIRType(def->type()));
stringProperty("type", "%s : [%d, %d]", StringFromMIRType(def->type()),
def->range()->lower(), def->range()->upper());
if (def->isInstruction()) {
if (MResumePoint *rp = def->toInstruction()->resumePoint())

View File

@ -61,6 +61,8 @@ class MUse;
class MIRGraph;
class MResumePoint;
static inline bool isOSRLikeValue (MDefinition *def);
// Represents a use of a node.
class MUse : public TempObject, public InlineForwardListNode<MUse>
{
@ -1919,6 +1921,12 @@ class MBitAnd : public MBinaryBitwiseInstruction
MDefinition *foldIfEqual() {
return getOperand(0); // x & x => x;
}
bool recomputeRange() {
Range *left = getOperand(0)->range();
Range *right = getOperand(1)->range();
return range()->update(Range::and_(left, right));
}
};
class MBitOr : public MBinaryBitwiseInstruction
@ -2733,16 +2741,17 @@ class MPhi : public MDefinition, public InlineForwardListNode<MPhi>
AliasSet getAliasSet() const {
return AliasSet::None();
}
bool recomputeRange() {
if (type() != MIRType_Int32)
return false;
Range r;
r.update(getOperand(0)->range());
for (size_t i = 0; i < numOperands(); i++)
r.unionWith(getOperand(i)->range());
JS_ASSERT(getOperand(0)->op() != MDefinition::Op_OsrValue);
for (size_t i = 0; i < numOperands(); i++) {
if (!isOSRLikeValue(getOperand(i)))
r.unionWith(getOperand(i)->range(), true);
}
return range()->update(&r);
}
@ -5573,6 +5582,16 @@ void MNode::initOperand(size_t index, MDefinition *ins)
setOperand(index, ins);
ins->addUse(this, index);
}
static inline bool isOSRLikeValue (MDefinition *def) {
if (def->isOsrValue())
return true;
if (def->isUnbox())
if (def->getOperand(0)->isOsrValue())
return true;
return false;
}
typedef Vector<MDefinition *, 8, IonAllocPolicy> MDefinitionVector;

View File

@ -278,11 +278,11 @@ Range::intersect(const Range *lhs, const Range *rhs)
}
void
Range::unionWith(const Range *other)
Range::unionWith(const Range *other, bool useNarrowing)
{
setLower(Min(lower_, other->lower_));
setUpper(Max(upper_, other->upper_));
lower_infinite_ |= other->lower_infinite_;
setUpper(Max(upper_, other->upper_));
upper_infinite_ |= other->upper_infinite_;
}
@ -304,7 +304,20 @@ Range::sub(const Range *lhs, const Range *rhs)
return ret;
}
Range
Range::and_(const Range *lhs, const Range *rhs)
{
uint64_t lower = 0;
// If both numbers can be negative, issues can be had.
if (lhs->lower_ < 0 && rhs->lower_ < 0)
lower = INT_MIN;
uint64_t upper = lhs->upper_;
if (rhs->upper_ < lhs->upper_)
upper = rhs->upper_;
Range ret(lower, upper);
return ret;
}
Range
Range::mul(const Range *lhs, const Range *rhs)
{
@ -346,7 +359,6 @@ Range::update(const Range *other)
lower_infinite_ != other->lower_infinite_ ||
upper_ != other->upper_ ||
upper_infinite_ != other->upper_infinite_;
if (changed) {
lower_ = other->lower_;
lower_infinite_ = other->lower_infinite_;
@ -386,20 +398,13 @@ RangeAnalysis::analyze()
for (MDefinitionIterator iter(*block); iter; iter++) {
MDefinition *def = *iter;
if (!def->isPhi() && !def->isBeta())
continue;
AddToWorklist(worklist, def);
}
}
size_t iters = 0;
#define MAX_ITERS 4096
// XXX: hack: range analysis iloops on jit-test/tests/basic/fannkuch.js
// To circumvent this and land the pass, we just run for a fixed number of
// iterations.
//
// (Bug 765119)
while (!worklist.empty() /* && iters < MAX_ITERS*/) {
while (!worklist.empty()) {
MDefinition *def = PopFromWorklist(worklist);
IonSpew(IonSpew_Range, "recomputing range on %d", def->id());
SpewRange(def);
@ -417,7 +422,6 @@ RangeAnalysis::analyze()
for(size_t i = 0; i < worklist.length(); i++)
worklist[i]->setNotInWorklist();
#undef MAX_ITERS
#ifdef DEBUG
for (ReversePostorderIterator block(graph_.rpoBegin()); block != graph_.rpoEnd(); block++) {

View File

@ -106,13 +106,13 @@ class Range {
// modification. This is to avoid a bunch of useless extra
// copying when chaining together unions when handling Phi
// nodes.
void unionWith(const Range *other);
void unionWith(const Range *other, bool useNarrowing = false);
static Range intersect(const Range *lhs, const Range *rhs);
static Range add(const Range *lhs, const Range *rhs);
static Range sub(const Range *lhs, const Range *rhs);
static Range mul(const Range *lhs, const Range *rhs);
static Range and_(const Range *lhs, const Range *rhs);
static Range shl(const Range *lhs, int32 c);
static Range shr(const Range *lhs, int32 c);

View File

@ -467,12 +467,10 @@ CodeGeneratorARM::visitMulI(LMulI *ins)
Assembler::Condition c = Assembler::Overflow;
//masm.imull(ToOperand(rhs), ToRegister(lhs));
if (mul->canOverflow()) {
if (mul->canOverflow())
c = masm.ma_check_mul(ToRegister(lhs), ToRegister(rhs), ToRegister(dest), c);
} else {
else
masm.ma_mul(ToRegister(lhs), ToRegister(rhs), ToRegister(dest));
}
// Bailout on overflow
if (mul->canOverflow() && !bailoutIf(c, ins->snapshot()))