mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 804636 part 3 - Remove JM+TI loop test analysis. r=bhackett
This commit is contained in:
parent
24824c461c
commit
85146049a7
@ -48,8 +48,6 @@ LoopState::init(jsbytecode *head, Jump entry, jsbytecode *entryTarget)
|
||||
|
||||
this->entry = entry;
|
||||
|
||||
analyzeLoopTest();
|
||||
analyzeLoopIncrements();
|
||||
for (unsigned i = 0; i < ssa->numFrames(); i++) {
|
||||
/* Only analyze this frame if it is nested within the loop itself. */
|
||||
uint32_t index = ssa->iterFrame(i).index;
|
||||
@ -1410,181 +1408,6 @@ LoopState::restoreInvariants(jsbytecode *pc, Assembler &masm,
|
||||
|
||||
/* Loop analysis methods. */
|
||||
|
||||
/*
|
||||
* Get any slot/constant accessed by a loop test operand, in terms of its value
|
||||
* at the start of the next loop iteration.
|
||||
*/
|
||||
bool
|
||||
LoopState::getLoopTestAccess(const SSAValue &v, uint32_t *pslot, int32_t *pconstant)
|
||||
{
|
||||
*pslot = UNASSIGNED;
|
||||
*pconstant = 0;
|
||||
|
||||
if (v.kind() == SSAValue::PHI || v.kind() == SSAValue::VAR) {
|
||||
/*
|
||||
* Getting the value of a variable at a previous offset. Check that it
|
||||
* is not updated before the start of the next loop iteration.
|
||||
*/
|
||||
uint32_t slot;
|
||||
uint32_t offset;
|
||||
if (v.kind() == SSAValue::PHI) {
|
||||
slot = v.phiSlot();
|
||||
offset = v.phiOffset();
|
||||
} else {
|
||||
slot = v.varSlot();
|
||||
offset = v.varInitial() ? 0 : v.varOffset();
|
||||
}
|
||||
if (outerAnalysis->slotEscapes(slot))
|
||||
return false;
|
||||
if (outerAnalysis->liveness(slot).firstWrite(offset + 1, lifetime->backedge) != UINT32_MAX)
|
||||
return false;
|
||||
*pslot = slot;
|
||||
*pconstant = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
jsbytecode *pc = outerScript->code + v.pushedOffset();
|
||||
JSOp op = JSOp(*pc);
|
||||
|
||||
switch (op) {
|
||||
case JSOP_ZERO:
|
||||
case JSOP_ONE:
|
||||
case JSOP_UINT16:
|
||||
case JSOP_UINT24:
|
||||
case JSOP_INT8:
|
||||
case JSOP_INT32:
|
||||
*pconstant = GetBytecodeInteger(pc);
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LoopState::analyzeLoopTest()
|
||||
{
|
||||
if (cc.debugMode())
|
||||
return;
|
||||
|
||||
/* Don't handle do-while loops. */
|
||||
if (lifetime->entry == lifetime->head)
|
||||
return;
|
||||
|
||||
/* Don't handle loops with branching inside their condition. */
|
||||
if (lifetime->entry < lifetime->lastBlock)
|
||||
return;
|
||||
|
||||
/* Get the test performed before branching. */
|
||||
jsbytecode *backedge = outerScript->code + lifetime->backedge;
|
||||
if (JSOp(*backedge) != JSOP_IFNE)
|
||||
return;
|
||||
const SSAValue &test = outerAnalysis->poppedValue(backedge, 0);
|
||||
if (test.kind() != SSAValue::PUSHED)
|
||||
return;
|
||||
JSOp cmpop = JSOp(outerScript->code[test.pushedOffset()]);
|
||||
switch (cmpop) {
|
||||
case JSOP_GT:
|
||||
case JSOP_GE:
|
||||
case JSOP_LT:
|
||||
case JSOP_LE:
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
SSAValue one = outerAnalysis->poppedValue(test.pushedOffset(), 1);
|
||||
SSAValue two = outerAnalysis->poppedValue(test.pushedOffset(), 0);
|
||||
|
||||
/* The test must be comparing known integers. */
|
||||
if (outerAnalysis->getValueTypes(one)->getKnownTypeTag() != JSVAL_TYPE_INT32 ||
|
||||
outerAnalysis->getValueTypes(two)->getKnownTypeTag() != JSVAL_TYPE_INT32) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Reverse the condition if the RHS is modified by the loop. */
|
||||
uint32_t swapRHS;
|
||||
int32_t swapConstant;
|
||||
if (getLoopTestAccess(two, &swapRHS, &swapConstant)) {
|
||||
if (swapRHS != UNASSIGNED && outerAnalysis->liveness(swapRHS).firstWrite(lifetime) != UINT32_MAX) {
|
||||
SSAValue tmp = one;
|
||||
one = two;
|
||||
two = tmp;
|
||||
cmpop = ReverseCompareOp(cmpop);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t lhs;
|
||||
int32_t lhsConstant;
|
||||
if (!getLoopTestAccess(one, &lhs, &lhsConstant))
|
||||
return;
|
||||
|
||||
uint32_t rhs = UNASSIGNED;
|
||||
int32_t rhsConstant = 0;
|
||||
CrossSSAValue rhsv(CrossScriptSSA::OUTER_FRAME, two);
|
||||
if (!getEntryValue(rhsv, &rhs, &rhsConstant))
|
||||
return;
|
||||
if (!loopInvariantEntry(rhs))
|
||||
return;
|
||||
|
||||
if (lhs == UNASSIGNED)
|
||||
return;
|
||||
|
||||
int32_t constant;
|
||||
if (!SafeSub(rhsConstant, lhsConstant, &constant))
|
||||
return;
|
||||
|
||||
/* x > y ==> x >= y + 1 */
|
||||
if (cmpop == JSOP_GT && !SafeAdd(constant, 1, &constant))
|
||||
return;
|
||||
|
||||
/* x < y ==> x <= y - 1 */
|
||||
if (cmpop == JSOP_LT && !SafeSub(constant, 1, &constant))
|
||||
return;
|
||||
|
||||
/* Passed all filters, this is a loop test we can capture. */
|
||||
|
||||
this->testLHS = lhs;
|
||||
this->testRHS = rhs;
|
||||
this->testConstant = constant;
|
||||
this->testLessEqual = (cmpop == JSOP_LT || cmpop == JSOP_LE);
|
||||
}
|
||||
|
||||
void
|
||||
LoopState::analyzeLoopIncrements()
|
||||
{
|
||||
if (cc.debugMode())
|
||||
return;
|
||||
|
||||
/*
|
||||
* Find locals and arguments which are used in exactly one inc/dec operation in every
|
||||
* iteration of the loop (we only match against the last basic block, but could
|
||||
* also handle the first basic block).
|
||||
*/
|
||||
|
||||
for (uint32_t slot = ArgSlot(0); slot < LocalSlot(outerScript, outerScript->nfixed); slot++) {
|
||||
if (outerAnalysis->slotEscapes(slot))
|
||||
continue;
|
||||
|
||||
uint32_t offset = outerAnalysis->liveness(slot).onlyWrite(lifetime);
|
||||
if (offset == UINT32_MAX || offset < lifetime->lastBlock)
|
||||
continue;
|
||||
|
||||
jsbytecode *pc = outerScript->code + offset;
|
||||
JSOp op = JSOp(*pc);
|
||||
const JSCodeSpec *cs = &js_CodeSpec[op];
|
||||
if (cs->format & (JOF_INC | JOF_DEC)) {
|
||||
if (!outerAnalysis->integerOperation(pc))
|
||||
continue;
|
||||
|
||||
Increment inc;
|
||||
inc.slot = slot;
|
||||
inc.offset = offset;
|
||||
increments.append(inc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
LoopState::definiteArrayAccess(const SSAValue &obj, const SSAValue &index)
|
||||
{
|
||||
|
@ -330,12 +330,9 @@ class LoopState : public MacroAssemblerTypedefs
|
||||
*/
|
||||
bool constrainedLoop;
|
||||
|
||||
void analyzeLoopTest();
|
||||
void analyzeLoopIncrements();
|
||||
void analyzeLoopBody(unsigned frame);
|
||||
|
||||
bool definiteArrayAccess(const analyze::SSAValue &obj, const analyze::SSAValue &index);
|
||||
bool getLoopTestAccess(const analyze::SSAValue &v, uint32_t *pslot, int32_t *pconstant);
|
||||
|
||||
bool addGrowArray(types::TypeObject *object);
|
||||
bool addModifiedProperty(types::TypeObject *object, jsid id);
|
||||
|
Loading…
Reference in New Issue
Block a user