aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Pall <mike>2010-09-21 01:31:04 +0200
committerMike Pall <mike>2010-09-21 01:31:04 +0200
commit23b5c56d41d24a29cfd17d943a9a849a7b9ac20c (patch)
tree27096e71daf2e1f3da188969e49b03c90bbd384a /src
parent52b922c1e941cfc56ae76954a80c429782a33ca6 (diff)
downloadluajit-23b5c56d41d24a29cfd17d943a9a849a7b9ac20c.tar.gz
luajit-23b5c56d41d24a29cfd17d943a9a849a7b9ac20c.tar.bz2
luajit-23b5c56d41d24a29cfd17d943a9a849a7b9ac20c.zip
Improve alias analysis: disambiguate new allocations.
Diffstat (limited to 'src')
-rw-r--r--src/lj_opt_mem.c80
1 files changed, 54 insertions, 26 deletions
diff --git a/src/lj_opt_mem.c b/src/lj_opt_mem.c
index 8674ddea..4d2e9664 100644
--- a/src/lj_opt_mem.c
+++ b/src/lj_opt_mem.c
@@ -37,54 +37,79 @@ typedef enum {
37 37
38/* -- ALOAD/HLOAD forwarding and ASTORE/HSTORE elimination ---------------- */ 38/* -- ALOAD/HLOAD forwarding and ASTORE/HSTORE elimination ---------------- */
39 39
40/* Alias analysis for two different table references. */
41static AliasRet aa_table(jit_State *J, IRRef ta, IRRef tb)
42{
43 IRIns *ir, *taba = IR(ta), *tabb = IR(tb);
44 int newa, newb;
45 lua_assert(ta != tb);
46 /* Disambiguate new allocations. */
47 newa = (taba->o == IR_TNEW || taba->o == IR_TDUP);
48 newb = (tabb->o == IR_TNEW || tabb->o == IR_TDUP);
49 if (newa && newb)
50 return ALIAS_NO; /* Two different allocations never alias. */
51 if (newb) { /* At least one allocation? */
52 IRRef tmp = ta; ta = tb; tb = tmp;
53 } else if (!newa) {
54 return ALIAS_MAY; /* Anything else: we just don't know. */
55 }
56 /* Now ta holds the allocation, tb the other table reference.
57 ** The allocation might be stored and reloaded as tb. So perform a
58 ** simplified escape analysis: check for intervening stores which have
59 ** the allocation as the right operand.
60 */
61 for (ir = IR(ta+1); ir < IR(tb); ir++)
62 if (ir->op2 == ta &&
63 (ir->o == IR_ASTORE || ir->o == IR_HSTORE ||
64 ir->o == IR_USTORE || ir->o == IR_FSTORE))
65 return ALIAS_MAY; /* Allocation was stored and might alias. */
66 return ALIAS_NO; /* Allocation doesn't alias the other reference. */
67}
68
40/* Alias analysis for array and hash access using key-based disambiguation. */ 69/* Alias analysis for array and hash access using key-based disambiguation. */
41static AliasRet aa_ahref(jit_State *J, IRIns *refa, IRIns *refb) 70static AliasRet aa_ahref(jit_State *J, IRIns *refa, IRIns *refb)
42{ 71{
43 IRRef ka = refa->op2; 72 IRRef ka = refa->op2;
44 IRRef kb = refb->op2; 73 IRRef kb = refb->op2;
45 IRIns *keya, *keyb; 74 IRIns *keya, *keyb;
75 IRRef ta, tb;
46 if (refa == refb) 76 if (refa == refb)
47 return ALIAS_MUST; /* Shortcut for same refs. */ 77 return ALIAS_MUST; /* Shortcut for same refs. */
48 keya = IR(ka); 78 keya = IR(ka);
49 if (keya->o == IR_KSLOT) { ka = keya->op1; keya = IR(ka); } 79 if (keya->o == IR_KSLOT) { ka = keya->op1; keya = IR(ka); }
50 keyb = IR(kb); 80 keyb = IR(kb);
51 if (keyb->o == IR_KSLOT) { kb = keyb->op1; keyb = IR(kb); } 81 if (keyb->o == IR_KSLOT) { kb = keyb->op1; keyb = IR(kb); }
82 ta = (refa->o==IR_HREFK || refa->o==IR_AREF) ? IR(refa->op1)->op1 : refa->op1;
83 tb = (refb->o==IR_HREFK || refb->o==IR_AREF) ? IR(refb->op1)->op1 : refb->op1;
52 if (ka == kb) { 84 if (ka == kb) {
53 /* Same key. Check for same table with different ref (NEWREF vs. HREF). */ 85 /* Same key. Check for same table with different ref (NEWREF vs. HREF). */
54 IRIns *ta = refa; 86 if (ta == tb)
55 IRIns *tb = refb;
56 if (ta->o == IR_HREFK || ta->o == IR_AREF) ta = IR(ta->op1);
57 if (tb->o == IR_HREFK || tb->o == IR_AREF) tb = IR(tb->op1);
58 if (ta->op1 == tb->op1)
59 return ALIAS_MUST; /* Same key, same table. */ 87 return ALIAS_MUST; /* Same key, same table. */
60 else 88 else
61 return ALIAS_MAY; /* Same key, possibly different table. */ 89 return aa_table(J, ta, tb); /* Same key, possibly different table. */
62 } 90 }
63 if (irref_isk(ka) && irref_isk(kb)) 91 if (irref_isk(ka) && irref_isk(kb))
64 return ALIAS_NO; /* Different constant keys. */ 92 return ALIAS_NO; /* Different constant keys. */
65 if (refa->o == IR_AREF) { 93 if (refa->o == IR_AREF) {
66 /* Disambiguate array references based on index arithmetic. */ 94 /* Disambiguate array references based on index arithmetic. */
95 int32_t ofsa = 0, ofsb = 0;
96 IRRef basea = ka, baseb = kb;
67 lua_assert(refb->o == IR_AREF); 97 lua_assert(refb->o == IR_AREF);
68 if (refa->op1 == refb->op1) { 98 /* Gather base and offset from t[base] or t[base+-ofs]. */
69 /* Same table, different non-const array keys. */ 99 if (keya->o == IR_ADD && irref_isk(keya->op2)) {
70 int32_t ofsa = 0, ofsb = 0; 100 basea = keya->op1;
71 IRRef basea = ka, baseb = kb; 101 ofsa = IR(keya->op2)->i;
72 /* Gather base and offset from t[base] or t[base+-ofs]. */ 102 if (basea == kb && ofsa != 0)
73 if (keya->o == IR_ADD && irref_isk(keya->op2)) { 103 return ALIAS_NO; /* t[base+-ofs] vs. t[base]. */
74 basea = keya->op1;
75 ofsa = IR(keya->op2)->i;
76 if (basea == kb && ofsa != 0)
77 return ALIAS_NO; /* t[base+-ofs] vs. t[base]. */
78 }
79 if (keyb->o == IR_ADD && irref_isk(keyb->op2)) {
80 baseb = keyb->op1;
81 ofsb = IR(keyb->op2)->i;
82 if (ka == baseb && ofsb != 0)
83 return ALIAS_NO; /* t[base] vs. t[base+-ofs]. */
84 }
85 if (basea == baseb && ofsa != ofsb)
86 return ALIAS_NO; /* t[base+-o1] vs. t[base+-o2] and o1 != o2. */
87 } 104 }
105 if (keyb->o == IR_ADD && irref_isk(keyb->op2)) {
106 baseb = keyb->op1;
107 ofsb = IR(keyb->op2)->i;
108 if (ka == baseb && ofsb != 0)
109 return ALIAS_NO; /* t[base] vs. t[base+-ofs]. */
110 }
111 if (basea == baseb && ofsa != ofsb)
112 return ALIAS_NO; /* t[base+-o1] vs. t[base+-o2] and o1 != o2. */
88 } else { 113 } else {
89 /* Disambiguate hash references based on the type of their keys. */ 114 /* Disambiguate hash references based on the type of their keys. */
90 lua_assert((refa->o==IR_HREF || refa->o==IR_HREFK || refa->o==IR_NEWREF) && 115 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)
92 if (!irt_sametype(keya->t, keyb->t)) 117 if (!irt_sametype(keya->t, keyb->t))
93 return ALIAS_NO; /* Different key types. */ 118 return ALIAS_NO; /* Different key types. */
94 } 119 }
95 return ALIAS_MAY; /* Anything else: we just don't know. */ 120 if (ta == tb)
121 return ALIAS_MAY; /* Same table, cannot disambiguate keys. */
122 else
123 return aa_table(J, ta, tb); /* Try to disambiguate tables. */
96} 124}
97 125
98/* Array and hash load forwarding. */ 126/* Array and hash load forwarding. */