mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
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:
parent
633fc2cc7c
commit
9ab7c2a331
@ -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);
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user