diff options
author | Mike Pall <mike> | 2010-06-30 23:30:08 +0200 |
---|---|---|
committer | Mike Pall <mike> | 2010-06-30 23:30:08 +0200 |
commit | bbd1584d5f26e7eb674fb1721de9915e4dda489c (patch) | |
tree | f4c36d47afcf9b2a7c03f3ec181d9cd00cfc0924 /src | |
parent | 9f6707ddbb25287948d58555818e68ab742083be (diff) | |
download | luajit-bbd1584d5f26e7eb674fb1721de9915e4dda489c.tar.gz luajit-bbd1584d5f26e7eb674fb1721de9915e4dda489c.tar.bz2 luajit-bbd1584d5f26e7eb674fb1721de9915e4dda489c.zip |
Do not eliminate PHIs for values only referenced from side exits.
Diffstat (limited to 'src')
-rw-r--r-- | src/lj_opt_loop.c | 51 |
1 files changed, 28 insertions, 23 deletions
diff --git a/src/lj_opt_loop.c b/src/lj_opt_loop.c index 48207dd5..f370d59f 100644 --- a/src/lj_opt_loop.c +++ b/src/lj_opt_loop.c | |||
@@ -101,7 +101,8 @@ | |||
101 | /* -- PHI elimination ----------------------------------------------------- */ | 101 | /* -- PHI elimination ----------------------------------------------------- */ |
102 | 102 | ||
103 | /* Emit or eliminate collected PHIs. */ | 103 | /* Emit or eliminate collected PHIs. */ |
104 | static void loop_emit_phi(jit_State *J, IRRef1 *subst, IRRef1 *phi, IRRef nphi) | 104 | static void loop_emit_phi(jit_State *J, IRRef1 *subst, IRRef1 *phi, IRRef nphi, |
105 | SnapNo onsnap) | ||
105 | { | 106 | { |
106 | int pass2 = 0; | 107 | int pass2 = 0; |
107 | IRRef i, nslots; | 108 | IRRef i, nslots; |
@@ -120,11 +121,21 @@ static void loop_emit_phi(jit_State *J, IRRef1 *subst, IRRef1 *phi, IRRef nphi) | |||
120 | } | 121 | } |
121 | /* Pass #2: traverse variant part and clear marks of non-redundant PHIs. */ | 122 | /* Pass #2: traverse variant part and clear marks of non-redundant PHIs. */ |
122 | if (pass2) { | 123 | if (pass2) { |
124 | SnapNo s; | ||
123 | for (i = J->cur.nins-1; i > invar; i--) { | 125 | for (i = J->cur.nins-1; i > invar; i--) { |
124 | IRIns *ir = IR(i); | 126 | IRIns *ir = IR(i); |
125 | if (!irref_isk(ir->op1)) irt_clearmark(IR(ir->op1)->t); | 127 | if (!irref_isk(ir->op1)) irt_clearmark(IR(ir->op1)->t); |
126 | if (!irref_isk(ir->op2)) irt_clearmark(IR(ir->op2)->t); | 128 | if (!irref_isk(ir->op2)) irt_clearmark(IR(ir->op2)->t); |
127 | } | 129 | } |
130 | for (s = J->cur.nsnap-1; s >= onsnap; s--) { | ||
131 | SnapShot *snap = &J->cur.snap[s]; | ||
132 | SnapEntry *map = &J->cur.snapmap[snap->mapofs]; | ||
133 | MSize n, nent = snap->nent; | ||
134 | for (n = 0; n < nent; n++) { | ||
135 | IRRef ref = snap_ref(map[n]); | ||
136 | if (!irref_isk(ref)) irt_clearmark(IR(ref)->t); | ||
137 | } | ||
138 | } | ||
128 | } | 139 | } |
129 | /* Pass #3: add PHIs for variant slots without a corresponding SLOAD. */ | 140 | /* Pass #3: add PHIs for variant slots without a corresponding SLOAD. */ |
130 | nslots = J->baseslot+J->maxslot; | 141 | nslots = J->baseslot+J->maxslot; |
@@ -133,11 +144,7 @@ static void loop_emit_phi(jit_State *J, IRRef1 *subst, IRRef1 *phi, IRRef nphi) | |||
133 | while (!irref_isk(ref) && ref != subst[ref]) { | 144 | while (!irref_isk(ref) && ref != subst[ref]) { |
134 | IRIns *ir = IR(ref); | 145 | IRIns *ir = IR(ref); |
135 | irt_clearmark(ir->t); /* Unmark potential uses, too. */ | 146 | irt_clearmark(ir->t); /* Unmark potential uses, too. */ |
136 | if (irt_isphi(ir->t)) { | 147 | if (irt_isphi(ir->t) || irt_ispri(ir->t)) |
137 | irt_clearmark(IR(subst[ref])->t); | ||
138 | break; | ||
139 | } | ||
140 | if (irt_ispri(ir->t)) | ||
141 | break; | 148 | break; |
142 | irt_setphi(ir->t); | 149 | irt_setphi(ir->t); |
143 | if (nphi >= LJ_MAX_PHI) | 150 | if (nphi >= LJ_MAX_PHI) |
@@ -222,7 +229,8 @@ static void loop_unroll(jit_State *J) | |||
222 | IRRef1 phi[LJ_MAX_PHI]; | 229 | IRRef1 phi[LJ_MAX_PHI]; |
223 | uint32_t nphi = 0; | 230 | uint32_t nphi = 0; |
224 | IRRef1 *subst; | 231 | IRRef1 *subst; |
225 | SnapShot *osnap; | 232 | SnapNo onsnap; |
233 | SnapShot *osnap, *loopsnap; | ||
226 | SnapEntry *loopmap, *psentinel; | 234 | SnapEntry *loopmap, *psentinel; |
227 | IRRef ins, invar; | 235 | IRRef ins, invar; |
228 | 236 | ||
@@ -244,20 +252,17 @@ static void loop_unroll(jit_State *J) | |||
244 | ** from the loop snapshot entries for each new snapshot. | 252 | ** from the loop snapshot entries for each new snapshot. |
245 | ** Caveat: both calls may reallocate J->cur.snap and J->cur.snapmap! | 253 | ** Caveat: both calls may reallocate J->cur.snap and J->cur.snapmap! |
246 | */ | 254 | */ |
247 | { | 255 | onsnap = J->cur.nsnap; |
248 | MSize nsnap = J->cur.nsnap; | 256 | lj_snap_grow_buf(J, 2*onsnap-2); |
249 | SnapShot *loopsnap; | 257 | lj_snap_grow_map(J, J->cur.nsnapmap*2+(onsnap-2)*J->cur.snap[onsnap-1].nent); |
250 | lj_snap_grow_buf(J, 2*nsnap-2); | ||
251 | lj_snap_grow_map(J, J->cur.nsnapmap*2+(nsnap-2)*J->cur.snap[nsnap-1].nent); | ||
252 | 258 | ||
253 | /* The loop snapshot is used for fallback substitutions. */ | 259 | /* The loop snapshot is used for fallback substitutions. */ |
254 | loopsnap = &J->cur.snap[nsnap-1]; | 260 | loopsnap = &J->cur.snap[onsnap-1]; |
255 | loopmap = &J->cur.snapmap[loopsnap->mapofs]; | 261 | loopmap = &J->cur.snapmap[loopsnap->mapofs]; |
256 | /* The PC of snapshot #0 and the loop snapshot must match. */ | 262 | /* The PC of snapshot #0 and the loop snapshot must match. */ |
257 | psentinel = &loopmap[loopsnap->nent]; | 263 | psentinel = &loopmap[loopsnap->nent]; |
258 | lua_assert(*psentinel == J->cur.snapmap[J->cur.snap[0].nent]); | 264 | lua_assert(*psentinel == J->cur.snapmap[J->cur.snap[0].nent]); |
259 | *psentinel = SNAP(255, 0, 0); /* Replace PC with temporary sentinel. */ | 265 | *psentinel = SNAP(255, 0, 0); /* Replace PC with temporary sentinel. */ |
260 | } | ||
261 | 266 | ||
262 | /* Start substitution with snapshot #1 (#0 is empty for root traces). */ | 267 | /* Start substitution with snapshot #1 (#0 is empty for root traces). */ |
263 | osnap = &J->cur.snap[1]; | 268 | osnap = &J->cur.snap[1]; |
@@ -308,11 +313,11 @@ static void loop_unroll(jit_State *J) | |||
308 | lua_assert(J->cur.nsnapmap <= J->sizesnapmap); | 313 | lua_assert(J->cur.nsnapmap <= J->sizesnapmap); |
309 | *psentinel = J->cur.snapmap[J->cur.snap[0].nent]; /* Restore PC. */ | 314 | *psentinel = J->cur.snapmap[J->cur.snap[0].nent]; /* Restore PC. */ |
310 | 315 | ||
311 | loop_emit_phi(J, subst, phi, nphi); | 316 | loop_emit_phi(J, subst, phi, nphi, onsnap); |
312 | } | 317 | } |
313 | 318 | ||
314 | /* Undo any partial changes made by the loop optimization. */ | 319 | /* Undo any partial changes made by the loop optimization. */ |
315 | static void loop_undo(jit_State *J, IRRef ins, MSize nsnap) | 320 | static void loop_undo(jit_State *J, IRRef ins, SnapNo nsnap) |
316 | { | 321 | { |
317 | ptrdiff_t i; | 322 | ptrdiff_t i; |
318 | SnapShot *snap = &J->cur.snap[nsnap-1]; | 323 | SnapShot *snap = &J->cur.snap[nsnap-1]; |
@@ -346,7 +351,7 @@ static TValue *cploop_opt(lua_State *L, lua_CFunction dummy, void *ud) | |||
346 | int lj_opt_loop(jit_State *J) | 351 | int lj_opt_loop(jit_State *J) |
347 | { | 352 | { |
348 | IRRef nins = J->cur.nins; | 353 | IRRef nins = J->cur.nins; |
349 | MSize nsnap = J->cur.nsnap; | 354 | SnapNo nsnap = J->cur.nsnap; |
350 | int errcode = lj_vm_cpcall(J->L, NULL, J, cploop_opt); | 355 | int errcode = lj_vm_cpcall(J->L, NULL, J, cploop_opt); |
351 | if (LJ_UNLIKELY(errcode)) { | 356 | if (LJ_UNLIKELY(errcode)) { |
352 | lua_State *L = J->L; | 357 | lua_State *L = J->L; |