summaryrefslogtreecommitdiff
path: root/src/lj_record.c
diff options
context:
space:
mode:
authorMike Pall <mike>2010-02-15 01:07:30 +0100
committerMike Pall <mike>2010-02-15 01:07:30 +0100
commitb6e4fde0dca25e911e2f1f614692f44c6923b1dc (patch)
treeb6a25f20a2c7db6e4444f547fd34ff35d2e1db4f /src/lj_record.c
parent2a2f8ed6a144fe763379f9cf0eb6a45750432a47 (diff)
downloadluajit-b6e4fde0dca25e911e2f1f614692f44c6923b1dc.tar.gz
luajit-b6e4fde0dca25e911e2f1f614692f44c6923b1dc.tar.bz2
luajit-b6e4fde0dca25e911e2f1f614692f44c6923b1dc.zip
Improve FOR loop const specialization and integerness checks.
Diffstat (limited to 'src/lj_record.c')
-rw-r--r--src/lj_record.c90
1 files changed, 61 insertions, 29 deletions
diff --git a/src/lj_record.c b/src/lj_record.c
index 2709ea01..deb5b2bb 100644
--- a/src/lj_record.c
+++ b/src/lj_record.c
@@ -249,33 +249,65 @@ nocanon:
249 J->mergesnap = 1; /* In case recording continues. */ 249 J->mergesnap = 1; /* In case recording continues. */
250} 250}
251 251
252/* Peek before FORI to find a const initializer, otherwise load from slot. */ 252/* Search bytecode backwards for a int/num constant slot initializer. */
253static TRef fori_arg(jit_State *J, const BCIns *pc, BCReg slot, IRType t) 253static TRef find_kinit(jit_State *J, const BCIns *endpc, BCReg slot, IRType t)
254{ 254{
255 /* A store to slot-1 means there's no conditional assignment for slot. */ 255 /* This algorithm is rather simplistic and assumes quite a bit about
256 if (bc_a(pc[-1]) == slot-1 && bcmode_a(bc_op(pc[-1])) == BCMdst) { 256 ** how the bytecode is generated. It works fine for FORI initializers,
257 BCIns ins = pc[0]; 257 ** but it won't necessarily work in other cases (e.g. iterator arguments).
258 if (bc_a(ins) == slot) { 258 ** It doesn't do anything fancy, either (like backpropagating MOVs).
259 if (bc_op(ins) == BC_KSHORT) { 259 */
260 int32_t k = (int32_t)(int16_t)bc_d(ins); 260 const BCIns *pc, *startpc = proto_bc(J->pt);
261 if (t == IRT_INT) 261 for (pc = endpc-1; pc > startpc; pc--) {
262 return lj_ir_kint(J, k); 262 BCIns ins = *pc;
263 else 263 BCOp op = bc_op(ins);
264 return lj_ir_knum(J, cast_num(k)); 264 /* First try to find the last instruction that stores to this slot. */
265 } else if (bc_op(ins) == BC_KNUM) { 265 if (bcmode_a(op) == BCMbase && bc_a(ins) <= slot) {
266 lua_Number n = proto_knum(J->pt, bc_d(ins)); 266 return 0; /* Multiple results, e.g. from a CALL or KNIL. */
267 if (t == IRT_INT) 267 } else if (bcmode_a(op) == BCMdst && bc_a(ins) == slot) {
268 return lj_ir_kint(J, lj_num2int(n)); 268 if (op == BC_KSHORT || op == BC_KNUM) { /* Found const. initializer. */
269 else 269 /* Now try to verify there's no forward jump across it. */
270 return lj_ir_knum(J, n); 270 const BCIns *kpc = pc;
271 for ( ; pc > startpc; pc--)
272 if (bc_op(*pc) == BC_JMP) {
273 const BCIns *target = pc+bc_j(*pc)+1;
274 if (target > kpc && target <= endpc)
275 return 0; /* Conditional assignment. */
276 }
277 if (op == BC_KSHORT) {
278 int32_t k = (int32_t)(int16_t)bc_d(ins);
279 return t == IRT_INT ? lj_ir_kint(J, k) : lj_ir_knum(J, cast_num(k));
280 } else {
281 lua_Number n = proto_knum(J->pt, bc_d(ins));
282 if (t == IRT_INT) {
283 int32_t k = lj_num2int(n);
284 if (n == cast_num(k)) /* -0 is ok here. */
285 return lj_ir_kint(J, k);
286 return 0; /* Type mismatch. */
287 } else {
288 return lj_ir_knum(J, n);
289 }
290 }
271 } 291 }
292 return 0; /* Non-constant initializer. */
272 } 293 }
273 } 294 }
274 if (J->base[slot]) 295 return 0; /* No assignment to this slot found? */
275 return J->base[slot]; 296}
276 if (t == IRT_INT) 297
277 t |= IRT_GUARD; 298/* Peek before FORI to find a const initializer. Otherwise load from slot. */
278 return sloadt(J, (int32_t)slot, t, IRSLOAD_READONLY|IRSLOAD_INHERIT); 299static TRef fori_arg(jit_State *J, const BCIns *fori, BCReg slot, IRType t)
300{
301 TRef tr = find_kinit(J, fori, slot, t);
302 if (!tr) {
303 tr = J->base[slot];
304 if (!tr) {
305 if (t == IRT_INT)
306 t |= IRT_GUARD;
307 tr = sloadt(J, (int32_t)slot, t, IRSLOAD_READONLY|IRSLOAD_INHERIT);
308 }
309 }
310 return tr;
279} 311}
280 312
281/* Simulate the runtime behavior of the FOR loop iterator. 313/* Simulate the runtime behavior of the FOR loop iterator.
@@ -311,8 +343,8 @@ static LoopEvent rec_for(jit_State *J, const BCIns *fori, int isforl)
311 idx = tr[FORL_IDX]; 343 idx = tr[FORL_IDX];
312 if (!idx) idx = sloadt(J, (int32_t)(ra+FORL_IDX), IRT_NUM, 0); 344 if (!idx) idx = sloadt(J, (int32_t)(ra+FORL_IDX), IRT_NUM, 0);
313 t = tref_type(idx); 345 t = tref_type(idx);
314 stop = fori_arg(J, fori-2, ra+FORL_STOP, t); 346 stop = fori_arg(J, fori, ra+FORL_STOP, t);
315 step = fori_arg(J, fori-1, ra+FORL_STEP, t); 347 step = fori_arg(J, fori, ra+FORL_STEP, t);
316 tr[FORL_IDX] = idx = emitir(IRT(IR_ADD, t), idx, step); 348 tr[FORL_IDX] = idx = emitir(IRT(IR_ADD, t), idx, step);
317 } else { /* Handle FORI/JFORI opcodes. */ 349 } else { /* Handle FORI/JFORI opcodes. */
318 BCReg i; 350 BCReg i;
@@ -2134,8 +2166,8 @@ static void rec_setup_forl(jit_State *J, const BCIns *fori)
2134 cTValue *forbase = &J->L->base[ra]; 2166 cTValue *forbase = &J->L->base[ra];
2135 IRType t = (J->flags & JIT_F_OPT_NARROW) ? lj_opt_narrow_forl(forbase) 2167 IRType t = (J->flags & JIT_F_OPT_NARROW) ? lj_opt_narrow_forl(forbase)
2136 : IRT_NUM; 2168 : IRT_NUM;
2137 TRef stop = fori_arg(J, fori-2, ra+FORL_STOP, t); 2169 TRef stop = fori_arg(J, fori, ra+FORL_STOP, t);
2138 TRef step = fori_arg(J, fori-1, ra+FORL_STEP, t); 2170 TRef step = fori_arg(J, fori, ra+FORL_STEP, t);
2139 int dir = (0 <= numV(&forbase[FORL_STEP])); 2171 int dir = (0 <= numV(&forbase[FORL_STEP]));
2140 lua_assert(bc_op(*fori) == BC_FORI || bc_op(*fori) == BC_JFORI); 2172 lua_assert(bc_op(*fori) == BC_FORI || bc_op(*fori) == BC_JFORI);
2141 if (!tref_isk(step)) { 2173 if (!tref_isk(step)) {
@@ -2165,7 +2197,7 @@ static void rec_setup_forl(jit_State *J, const BCIns *fori)
2165 k = (int32_t)(dir ? 0x7fffffff : 0x80000000) - k; 2197 k = (int32_t)(dir ? 0x7fffffff : 0x80000000) - k;
2166 emitir(IRTGI(dir ? IR_LE : IR_GE), stop, lj_ir_kint(J, k)); 2198 emitir(IRTGI(dir ? IR_LE : IR_GE), stop, lj_ir_kint(J, k));
2167 } 2199 }
2168 if (t == IRT_INT) 2200 if (t == IRT_INT && !find_kinit(J, fori, ra+FORL_IDX, IRT_INT))
2169 t |= IRT_GUARD; 2201 t |= IRT_GUARD;
2170 J->base[ra+FORL_EXT] = sloadt(J, (int32_t)(ra+FORL_IDX), t, IRSLOAD_INHERIT); 2202 J->base[ra+FORL_EXT] = sloadt(J, (int32_t)(ra+FORL_IDX), t, IRSLOAD_INHERIT);
2171 J->maxslot = ra+FORL_EXT+1; 2203 J->maxslot = ra+FORL_EXT+1;