Bug 804636 part 3 - Remove JM+TI loop test analysis. r=bhackett

This commit is contained in:
Jan de Mooij 2012-10-27 20:56:19 +02:00
parent 24824c461c
commit 85146049a7
2 changed files with 0 additions and 180 deletions

View File

@ -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)
{

View File

@ -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);