mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-07 23:24:09 +00:00
Improve alias analysis: disambiguate new allocations.
This commit is contained in:
parent
52b922c1e9
commit
23b5c56d41
@ -37,54 +37,79 @@ typedef enum {
|
|||||||
|
|
||||||
/* -- ALOAD/HLOAD forwarding and ASTORE/HSTORE elimination ---------------- */
|
/* -- ALOAD/HLOAD forwarding and ASTORE/HSTORE elimination ---------------- */
|
||||||
|
|
||||||
|
/* Alias analysis for two different table references. */
|
||||||
|
static AliasRet aa_table(jit_State *J, IRRef ta, IRRef tb)
|
||||||
|
{
|
||||||
|
IRIns *ir, *taba = IR(ta), *tabb = IR(tb);
|
||||||
|
int newa, newb;
|
||||||
|
lua_assert(ta != tb);
|
||||||
|
/* Disambiguate new allocations. */
|
||||||
|
newa = (taba->o == IR_TNEW || taba->o == IR_TDUP);
|
||||||
|
newb = (tabb->o == IR_TNEW || tabb->o == IR_TDUP);
|
||||||
|
if (newa && newb)
|
||||||
|
return ALIAS_NO; /* Two different allocations never alias. */
|
||||||
|
if (newb) { /* At least one allocation? */
|
||||||
|
IRRef tmp = ta; ta = tb; tb = tmp;
|
||||||
|
} else if (!newa) {
|
||||||
|
return ALIAS_MAY; /* Anything else: we just don't know. */
|
||||||
|
}
|
||||||
|
/* Now ta holds the allocation, tb the other table reference.
|
||||||
|
** The allocation might be stored and reloaded as tb. So perform a
|
||||||
|
** simplified escape analysis: check for intervening stores which have
|
||||||
|
** the allocation as the right operand.
|
||||||
|
*/
|
||||||
|
for (ir = IR(ta+1); ir < IR(tb); ir++)
|
||||||
|
if (ir->op2 == ta &&
|
||||||
|
(ir->o == IR_ASTORE || ir->o == IR_HSTORE ||
|
||||||
|
ir->o == IR_USTORE || ir->o == IR_FSTORE))
|
||||||
|
return ALIAS_MAY; /* Allocation was stored and might alias. */
|
||||||
|
return ALIAS_NO; /* Allocation doesn't alias the other reference. */
|
||||||
|
}
|
||||||
|
|
||||||
/* Alias analysis for array and hash access using key-based disambiguation. */
|
/* Alias analysis for array and hash access using key-based disambiguation. */
|
||||||
static AliasRet aa_ahref(jit_State *J, IRIns *refa, IRIns *refb)
|
static AliasRet aa_ahref(jit_State *J, IRIns *refa, IRIns *refb)
|
||||||
{
|
{
|
||||||
IRRef ka = refa->op2;
|
IRRef ka = refa->op2;
|
||||||
IRRef kb = refb->op2;
|
IRRef kb = refb->op2;
|
||||||
IRIns *keya, *keyb;
|
IRIns *keya, *keyb;
|
||||||
|
IRRef ta, tb;
|
||||||
if (refa == refb)
|
if (refa == refb)
|
||||||
return ALIAS_MUST; /* Shortcut for same refs. */
|
return ALIAS_MUST; /* Shortcut for same refs. */
|
||||||
keya = IR(ka);
|
keya = IR(ka);
|
||||||
if (keya->o == IR_KSLOT) { ka = keya->op1; keya = IR(ka); }
|
if (keya->o == IR_KSLOT) { ka = keya->op1; keya = IR(ka); }
|
||||||
keyb = IR(kb);
|
keyb = IR(kb);
|
||||||
if (keyb->o == IR_KSLOT) { kb = keyb->op1; keyb = IR(kb); }
|
if (keyb->o == IR_KSLOT) { kb = keyb->op1; keyb = IR(kb); }
|
||||||
|
ta = (refa->o==IR_HREFK || refa->o==IR_AREF) ? IR(refa->op1)->op1 : refa->op1;
|
||||||
|
tb = (refb->o==IR_HREFK || refb->o==IR_AREF) ? IR(refb->op1)->op1 : refb->op1;
|
||||||
if (ka == kb) {
|
if (ka == kb) {
|
||||||
/* Same key. Check for same table with different ref (NEWREF vs. HREF). */
|
/* Same key. Check for same table with different ref (NEWREF vs. HREF). */
|
||||||
IRIns *ta = refa;
|
if (ta == tb)
|
||||||
IRIns *tb = refb;
|
|
||||||
if (ta->o == IR_HREFK || ta->o == IR_AREF) ta = IR(ta->op1);
|
|
||||||
if (tb->o == IR_HREFK || tb->o == IR_AREF) tb = IR(tb->op1);
|
|
||||||
if (ta->op1 == tb->op1)
|
|
||||||
return ALIAS_MUST; /* Same key, same table. */
|
return ALIAS_MUST; /* Same key, same table. */
|
||||||
else
|
else
|
||||||
return ALIAS_MAY; /* Same key, possibly different table. */
|
return aa_table(J, ta, tb); /* Same key, possibly different table. */
|
||||||
}
|
}
|
||||||
if (irref_isk(ka) && irref_isk(kb))
|
if (irref_isk(ka) && irref_isk(kb))
|
||||||
return ALIAS_NO; /* Different constant keys. */
|
return ALIAS_NO; /* Different constant keys. */
|
||||||
if (refa->o == IR_AREF) {
|
if (refa->o == IR_AREF) {
|
||||||
/* Disambiguate array references based on index arithmetic. */
|
/* Disambiguate array references based on index arithmetic. */
|
||||||
|
int32_t ofsa = 0, ofsb = 0;
|
||||||
|
IRRef basea = ka, baseb = kb;
|
||||||
lua_assert(refb->o == IR_AREF);
|
lua_assert(refb->o == IR_AREF);
|
||||||
if (refa->op1 == refb->op1) {
|
/* Gather base and offset from t[base] or t[base+-ofs]. */
|
||||||
/* Same table, different non-const array keys. */
|
if (keya->o == IR_ADD && irref_isk(keya->op2)) {
|
||||||
int32_t ofsa = 0, ofsb = 0;
|
basea = keya->op1;
|
||||||
IRRef basea = ka, baseb = kb;
|
ofsa = IR(keya->op2)->i;
|
||||||
/* Gather base and offset from t[base] or t[base+-ofs]. */
|
if (basea == kb && ofsa != 0)
|
||||||
if (keya->o == IR_ADD && irref_isk(keya->op2)) {
|
return ALIAS_NO; /* t[base+-ofs] vs. t[base]. */
|
||||||
basea = keya->op1;
|
|
||||||
ofsa = IR(keya->op2)->i;
|
|
||||||
if (basea == kb && ofsa != 0)
|
|
||||||
return ALIAS_NO; /* t[base+-ofs] vs. t[base]. */
|
|
||||||
}
|
|
||||||
if (keyb->o == IR_ADD && irref_isk(keyb->op2)) {
|
|
||||||
baseb = keyb->op1;
|
|
||||||
ofsb = IR(keyb->op2)->i;
|
|
||||||
if (ka == baseb && ofsb != 0)
|
|
||||||
return ALIAS_NO; /* t[base] vs. t[base+-ofs]. */
|
|
||||||
}
|
|
||||||
if (basea == baseb && ofsa != ofsb)
|
|
||||||
return ALIAS_NO; /* t[base+-o1] vs. t[base+-o2] and o1 != o2. */
|
|
||||||
}
|
}
|
||||||
|
if (keyb->o == IR_ADD && irref_isk(keyb->op2)) {
|
||||||
|
baseb = keyb->op1;
|
||||||
|
ofsb = IR(keyb->op2)->i;
|
||||||
|
if (ka == baseb && ofsb != 0)
|
||||||
|
return ALIAS_NO; /* t[base] vs. t[base+-ofs]. */
|
||||||
|
}
|
||||||
|
if (basea == baseb && ofsa != ofsb)
|
||||||
|
return ALIAS_NO; /* t[base+-o1] vs. t[base+-o2] and o1 != o2. */
|
||||||
} else {
|
} else {
|
||||||
/* Disambiguate hash references based on the type of their keys. */
|
/* Disambiguate hash references based on the type of their keys. */
|
||||||
lua_assert((refa->o==IR_HREF || refa->o==IR_HREFK || refa->o==IR_NEWREF) &&
|
lua_assert((refa->o==IR_HREF || refa->o==IR_HREFK || refa->o==IR_NEWREF) &&
|
||||||
@ -92,7 +117,10 @@ static AliasRet aa_ahref(jit_State *J, IRIns *refa, IRIns *refb)
|
|||||||
if (!irt_sametype(keya->t, keyb->t))
|
if (!irt_sametype(keya->t, keyb->t))
|
||||||
return ALIAS_NO; /* Different key types. */
|
return ALIAS_NO; /* Different key types. */
|
||||||
}
|
}
|
||||||
return ALIAS_MAY; /* Anything else: we just don't know. */
|
if (ta == tb)
|
||||||
|
return ALIAS_MAY; /* Same table, cannot disambiguate keys. */
|
||||||
|
else
|
||||||
|
return aa_table(J, ta, tb); /* Try to disambiguate tables. */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Array and hash load forwarding. */
|
/* Array and hash load forwarding. */
|
||||||
|
Loading…
Reference in New Issue
Block a user