mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Add a bunch of features to range analysis to make it optimize more. (bug 765119, r=jandem)
This commit is contained in:
parent
7bf3a3daf6
commit
92fcef15b4
@ -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())
|
||||
|
@ -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);
|
||||
}
|
||||
@ -5534,6 +5543,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;
|
||||
|
||||
|
@ -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++) {
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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()))
|
||||
|
Loading…
Reference in New Issue
Block a user