Bug 542905 - cse chains should be cleared more selectively in case of labels. r=nnethercote.

--HG--
extra : convert_revision : 3cdd8540979dda01630e0676b273250311e26284
This commit is contained in:
William Maddox 2010-09-22 19:04:48 -07:00
parent 633fc2cc7c
commit 9ab7c2a331
2 changed files with 21 additions and 3 deletions

View File

@ -1956,7 +1956,8 @@ namespace nanojit
CSE_ACC_CONST( EMB_NUM_USED_ACCS + 0),
CSE_ACC_MULTIPLE( EMB_NUM_USED_ACCS + 1),
storesSinceLastLoad(ACCSET_NONE),
alloc(alloc)
alloc(alloc),
suspended(false)
{
m_findNL[LInsImmI] = &CseFilter::findImmI;
@ -2137,6 +2138,7 @@ namespace nanojit
void CseFilter::addNL(NLKind nlkind, LIns* ins, uint32_t k)
{
if (suspended) return;
NanoAssert(!m_listNL[nlkind][k]);
m_usedNL[nlkind]++;
m_listNL[nlkind][k] = ins;
@ -2147,6 +2149,7 @@ namespace nanojit
void CseFilter::addL(LIns* ins, uint32_t k)
{
if (suspended) return;
CseAcc cseAcc = miniAccSetToCseAcc(ins->miniAccSet(), ins->loadQual());
NanoAssert(!m_listL[cseAcc][k]);
m_usedL[cseAcc]++;
@ -2427,7 +2430,7 @@ namespace nanojit
LIns* CseFilter::ins0(LOpcode op)
{
if (op == LIR_label)
if (op == LIR_label && !suspended)
clearAll();
return out->ins0(op);
}
@ -2483,7 +2486,8 @@ namespace nanojit
if (storesSinceLastLoad != ACCSET_NONE) {
// Clear all normal (excludes CONST and MULTIPLE) loads
// aliased by stores and calls since the last time we were in
// this function.
// this function. Aliased loads must be cleared even when CSE
// is suspended.
AccSet a = storesSinceLastLoad & ((1 << EMB_NUM_USED_ACCS) - 1);
while (a) {
int acc = msbSet32(a);

View File

@ -1963,6 +1963,12 @@ namespace nanojit
Allocator& alloc;
// If true, we will not add new instructions to the CSE tables, but we
// will continue to CSE instructions that match existing table
// entries. Load instructions will still be removed if aliasing
// stores are encountered.
bool suspended;
CseAcc miniAccSetToCseAcc(MiniAccSet miniAccSet, LoadQual loadQual) {
NanoAssert(miniAccSet.val < NUM_ACCS || miniAccSet.val == MINI_ACCSET_MULTIPLE.val);
return (loadQual == LOAD_CONST) ? CSE_ACC_CONST :
@ -2038,6 +2044,14 @@ namespace nanojit
LIns* insCall(const CallInfo *call, LIns* args[]);
LIns* insGuard(LOpcode op, LIns* cond, GuardRecord *gr);
LIns* insGuardXov(LOpcode op, LIns* a, LIns* b, GuardRecord *gr);
// These functions provide control over CSE in the face of control
// flow. A suspend()/resume() pair may be put around a synthetic
// control flow diamond, preventing the inserted label from resetting
// the CSE state. A suspend() call must be dominated by a resume()
// call, else incorrect code could result.
void suspend() { suspended = true; }
void resume() { suspended = false; }
};
class LirBuffer