summaryrefslogtreecommitdiff
path: root/src/lj_record.c
diff options
context:
space:
mode:
authorMike Pall <mike>2011-03-10 01:57:24 +0100
committerMike Pall <mike>2011-03-10 01:57:24 +0100
commitbfce3c1127fd57fe0c935c92bcf45b4737041edd (patch)
tree2bd2d9e08c70608de63c7a69df7f00cfab07f6be /src/lj_record.c
parent3f26e3a89d54dfb761ca02fc89aaf15326f5f514 (diff)
downloadluajit-bfce3c1127fd57fe0c935c92bcf45b4737041edd.tar.gz
luajit-bfce3c1127fd57fe0c935c92bcf45b4737041edd.tar.bz2
luajit-bfce3c1127fd57fe0c935c92bcf45b4737041edd.zip
DUALNUM: Handle integer type in JIT compiler.
Diffstat (limited to 'src/lj_record.c')
-rw-r--r--src/lj_record.c280
1 files changed, 156 insertions, 124 deletions
diff --git a/src/lj_record.c b/src/lj_record.c
index 2bfd2608..613e458e 100644
--- a/src/lj_record.c
+++ b/src/lj_record.c
@@ -13,6 +13,7 @@
13#include "lj_err.h" 13#include "lj_err.h"
14#include "lj_str.h" 14#include "lj_str.h"
15#include "lj_tab.h" 15#include "lj_tab.h"
16#include "lj_meta.h"
16#include "lj_frame.h" 17#include "lj_frame.h"
17#include "lj_bc.h" 18#include "lj_bc.h"
18#include "lj_ff.h" 19#include "lj_ff.h"
@@ -102,7 +103,7 @@ static void rec_check_slots(jit_State *J)
102 lua_assert((J->slot[s+1] & TREF_FRAME)); 103 lua_assert((J->slot[s+1] & TREF_FRAME));
103 depth++; 104 depth++;
104 } else { 105 } else {
105 if (tvisnum(tv)) 106 if (tvisnumber(tv))
106 lua_assert(tref_isnumber(tr)); /* Could be IRT_INT etc., too. */ 107 lua_assert(tref_isnumber(tr)); /* Could be IRT_INT etc., too. */
107 else 108 else
108 lua_assert(itype2irt(tv) == tref_type(tr)); 109 lua_assert(itype2irt(tv) == tref_type(tr));
@@ -197,6 +198,7 @@ typedef enum {
197static void canonicalize_slots(jit_State *J) 198static void canonicalize_slots(jit_State *J)
198{ 199{
199 BCReg s; 200 BCReg s;
201 if (LJ_DUALNUM) return;
200 for (s = J->baseslot+J->maxslot-1; s >= 1; s--) { 202 for (s = J->baseslot+J->maxslot-1; s >= 1; s--) {
201 TRef tr = J->slot[s]; 203 TRef tr = J->slot[s];
202 if (tref_isinteger(tr)) { 204 if (tref_isinteger(tr)) {
@@ -254,16 +256,16 @@ static TRef find_kinit(jit_State *J, const BCIns *endpc, BCReg slot, IRType t)
254 } 256 }
255 if (op == BC_KSHORT) { 257 if (op == BC_KSHORT) {
256 int32_t k = (int32_t)(int16_t)bc_d(ins); 258 int32_t k = (int32_t)(int16_t)bc_d(ins);
257 return t == IRT_INT ? lj_ir_kint(J, k) : lj_ir_knum(J, cast_num(k)); 259 return t == IRT_INT ? lj_ir_kint(J, k) : lj_ir_knum(J, (lua_Number)k);
258 } else { 260 } else {
259 lua_Number n = proto_knum(J->pt, bc_d(ins)); 261 cTValue *tv = proto_knumtv(J->pt, bc_d(ins));
260 if (t == IRT_INT) { 262 if (t == IRT_INT) {
261 int32_t k = lj_num2int(n); 263 int32_t k = numberVint(tv);
262 if (n == cast_num(k)) /* -0 is ok here. */ 264 if (tvisint(tv) || numV(tv) == (lua_Number)k) /* -0 is ok here. */
263 return lj_ir_kint(J, k); 265 return lj_ir_kint(J, k);
264 return 0; /* Type mismatch. */ 266 return 0; /* Type mismatch. */
265 } else { 267 } else {
266 return lj_ir_knum(J, n); 268 return lj_ir_knum(J, numberVnum(tv));
267 } 269 }
268 } 270 }
269 } 271 }
@@ -273,41 +275,47 @@ static TRef find_kinit(jit_State *J, const BCIns *endpc, BCReg slot, IRType t)
273 return 0; /* No assignment to this slot found? */ 275 return 0; /* No assignment to this slot found? */
274} 276}
275 277
278/* Load and optionally convert a FORI argument from a slot. */
279static TRef fori_load(jit_State *J, BCReg slot, IRType t, int mode)
280{
281 int conv = (tvisint(&J->L->base[slot]) != (t==IRT_INT)) ? IRSLOAD_CONVERT : 0;
282 return sloadt(J, (int32_t)slot,
283 t + (((mode & IRSLOAD_TYPECHECK) ||
284 (conv && t == IRT_INT && !(mode >> 16))) ?
285 IRT_GUARD : 0),
286 mode + conv);
287}
288
276/* Peek before FORI to find a const initializer. Otherwise load from slot. */ 289/* Peek before FORI to find a const initializer. Otherwise load from slot. */
277static TRef fori_arg(jit_State *J, const BCIns *fori, BCReg slot, IRType t) 290static TRef fori_arg(jit_State *J, const BCIns *fori, BCReg slot,
291 IRType t, int mode)
278{ 292{
279 TRef tr = J->base[slot]; 293 TRef tr = J->base[slot];
280 if (!tr) { 294 if (!tr) {
281 tr = find_kinit(J, fori, slot, t); 295 tr = find_kinit(J, fori, slot, t);
282 if (!tr) 296 if (!tr)
283 tr = sloadt(J, (int32_t)slot, 297 tr = fori_load(J, slot, t, mode);
284 t == IRT_INT ? (IRT_INT|IRT_GUARD) : t,
285 t == IRT_INT ? (IRSLOAD_CONVERT|IRSLOAD_READONLY|IRSLOAD_INHERIT) :
286 (IRSLOAD_READONLY|IRSLOAD_INHERIT));
287 } 298 }
288 return tr; 299 return tr;
289} 300}
290 301
291/* In-place coercion of FORI arguments. */ 302/* Return the direction of the FOR loop iterator.
292static lua_Number for_coerce(jit_State *J, TValue *o) 303** It's important to exactly reproduce the semantics of the interpreter.
304*/
305static int rec_for_direction(cTValue *o)
293{ 306{
294 if (!tvisnum(o) && !(tvisstr(o) && lj_str_tonum(strV(o), o))) 307 return (tvisint(o) ? intV(o) : (int32_t)o->u32.hi) >= 0;
295 lj_trace_err(J, LJ_TRERR_BADTYPE);
296 return numV(o);
297} 308}
298 309
299/* Simulate the runtime behavior of the FOR loop iterator. 310/* Simulate the runtime behavior of the FOR loop iterator. */
300** It's important to exactly reproduce the semantics of the interpreter. 311static LoopEvent rec_for_iter(IROp *op, cTValue *o, int isforl)
301*/
302static LoopEvent for_iter(jit_State *J, IROp *op, BCReg ra, int isforl)
303{ 312{
304 TValue *forbase = &J->L->base[ra]; 313 lua_Number stopv = numberVnum(&o[FORL_STOP]);
305 lua_Number stopv = for_coerce(J, &forbase[FORL_STOP]); 314 lua_Number idxv = numberVnum(&o[FORL_IDX]);
306 lua_Number idxv = for_coerce(J, &forbase[FORL_IDX]); 315 lua_Number stepv = numberVnum(&o[FORL_STEP]);
307 lua_Number stepv = for_coerce(J, &forbase[FORL_STEP]);
308 if (isforl) 316 if (isforl)
309 idxv += stepv; 317 idxv += stepv;
310 if ((int32_t)forbase[FORL_STEP].u32.hi >= 0) { 318 if (rec_for_direction(&o[FORL_STEP])) {
311 if (idxv <= stopv) { *op = IR_LE; return LOOPEV_ENTER; } 319 if (idxv <= stopv) { *op = IR_LE; return LOOPEV_ENTER; }
312 *op = IR_GT; return LOOPEV_LEAVE; 320 *op = IR_GT; return LOOPEV_LEAVE;
313 } else { 321 } else {
@@ -316,44 +324,123 @@ static LoopEvent for_iter(jit_State *J, IROp *op, BCReg ra, int isforl)
316 } 324 }
317} 325}
318 326
327/* Record checks for FOR loop overflow and step direction. */
328static void rec_for_check(jit_State *J, IRType t, int dir, TRef stop, TRef step)
329{
330 if (!tref_isk(step)) {
331 /* Non-constant step: need a guard for the direction. */
332 TRef zero = (t == IRT_INT) ? lj_ir_kint(J, 0) : lj_ir_knum_zero(J);
333 emitir(IRTG(dir ? IR_GE : IR_LT, t), step, zero);
334 /* Add hoistable overflow checks for a narrowed FORL index. */
335 if (t == IRT_INT) {
336 if (tref_isk(stop)) {
337 /* Constant stop: optimize check away or to a range check for step. */
338 int32_t k = IR(tref_ref(stop))->i;
339 if (dir) {
340 if (k > 0)
341 emitir(IRTGI(IR_LE), step, lj_ir_kint(J, (int32_t)0x7fffffff-k));
342 } else {
343 if (k < 0)
344 emitir(IRTGI(IR_GE), step, lj_ir_kint(J, (int32_t)0x80000000-k));
345 }
346 } else {
347 /* Stop+step variable: need full overflow check. */
348 TRef tr = emitir(IRTGI(IR_ADDOV), step, stop);
349 emitir(IRTI(IR_USE), tr, 0); /* ADDOV is weak. Avoid dead result. */
350 }
351 }
352 } else if (t == IRT_INT && !tref_isk(stop)) {
353 /* Constant step: optimize overflow check to a range check for stop. */
354 int32_t k = IR(tref_ref(step))->i;
355 k = (int32_t)(dir ? 0x7fffffff : 0x80000000) - k;
356 emitir(IRTGI(dir ? IR_LE : IR_GE), stop, lj_ir_kint(J, k));
357 }
358}
359
360/* Record a FORL instruction. */
361static void rec_for_loop(jit_State *J, const BCIns *fori, ScEvEntry *scev,
362 int init)
363{
364 BCReg ra = bc_a(*fori);
365 cTValue *tv = &J->L->base[ra];
366 TRef idx = J->base[ra+FORL_IDX];
367 IRType t = idx ? tref_type(idx) :
368 (init || LJ_DUALNUM) ? lj_opt_narrow_forl(J, tv) : IRT_NUM;
369 int mode = IRSLOAD_INHERIT +
370 ((!LJ_DUALNUM || tvisint(tv) == (t == IRT_INT)) ? IRSLOAD_READONLY : 0);
371 TRef stop = fori_arg(J, fori, ra+FORL_STOP, t, mode);
372 TRef step = fori_arg(J, fori, ra+FORL_STEP, t, mode);
373 int tc, dir = rec_for_direction(&tv[FORL_STEP]);
374 lua_assert(bc_op(*fori) == BC_FORI || bc_op(*fori) == BC_JFORI);
375 scev->t.irt = t;
376 scev->dir = dir;
377 scev->stop = tref_ref(stop);
378 scev->step = tref_ref(step);
379 if (init)
380 rec_for_check(J, t, dir, stop, step);
381 scev->start = tref_ref(find_kinit(J, fori, ra+FORL_IDX, IRT_INT));
382 tc = (LJ_DUALNUM &&
383 !(scev->start && irref_isk(scev->stop) && irref_isk(scev->step))) ?
384 IRSLOAD_TYPECHECK : 0;
385 if (tc) {
386 J->base[ra+FORL_STOP] = stop;
387 J->base[ra+FORL_STEP] = step;
388 }
389 if (!idx)
390 idx = fori_load(J, ra+FORL_IDX, t,
391 IRSLOAD_INHERIT + tc + (J->scev.start << 16));
392 if (!init)
393 J->base[ra+FORL_IDX] = idx = emitir(IRT(IR_ADD, t), idx, step);
394 J->base[ra+FORL_EXT] = idx;
395 scev->idx = tref_ref(idx);
396 J->maxslot = ra+FORL_EXT+1;
397}
398
319/* Record FORL/JFORL or FORI/JFORI. */ 399/* Record FORL/JFORL or FORI/JFORI. */
320static LoopEvent rec_for(jit_State *J, const BCIns *fori, int isforl) 400static LoopEvent rec_for(jit_State *J, const BCIns *fori, int isforl)
321{ 401{
322 BCReg ra = bc_a(*fori); 402 BCReg ra = bc_a(*fori);
323 IROp op; 403 TValue *tv = &J->L->base[ra];
324 LoopEvent ev = for_iter(J, &op, ra, isforl);
325 TRef *tr = &J->base[ra]; 404 TRef *tr = &J->base[ra];
326 TRef idx, stop; 405 IROp op;
406 LoopEvent ev;
407 TRef stop;
327 IRType t; 408 IRType t;
328 if (isforl) { /* Handle FORL/JFORL opcodes. */ 409 if (isforl) { /* Handle FORL/JFORL opcodes. */
329 TRef step; 410 TRef idx = tr[FORL_IDX];
330 idx = tr[FORL_IDX];
331 if (tref_ref(idx) == J->scev.idx) { 411 if (tref_ref(idx) == J->scev.idx) {
332 t = J->scev.t.irt; 412 t = J->scev.t.irt;
333 stop = J->scev.stop; 413 stop = J->scev.stop;
334 step = J->scev.step; 414 idx = emitir(IRT(IR_ADD, t), idx, J->scev.step);
415 tr[FORL_EXT] = tr[FORL_IDX] = idx;
335 } else { 416 } else {
336 if (!idx) idx = sloadt(J, (int32_t)(ra+FORL_IDX), IRT_NUM, 0); 417 ScEvEntry scev;
337 t = tref_type(idx); 418 rec_for_loop(J, fori, &scev, 0);
338 stop = fori_arg(J, fori, ra+FORL_STOP, t); 419 t = scev.t.irt;
339 step = fori_arg(J, fori, ra+FORL_STEP, t); 420 stop = scev.stop;
340 } 421 }
341 tr[FORL_IDX] = idx = emitir(IRT(IR_ADD, t), idx, step);
342 } else { /* Handle FORI/JFORI opcodes. */ 422 } else { /* Handle FORI/JFORI opcodes. */
343 BCReg i; 423 BCReg i;
344 t = IRT_NUM; 424 lj_meta_for(J->L, tv);
425 t = lj_opt_narrow_forl(J, tv);
345 for (i = FORL_IDX; i <= FORL_STEP; i++) { 426 for (i = FORL_IDX; i <= FORL_STEP; i++) {
346 lua_assert(J->base[ra+i] != 0); /* Assumes the slots are already set. */ 427 lua_assert(tref_isnumber_str(tr[i]));
347 tr[i] = lj_ir_tonum(J, J->base[ra+i]); 428 if (tref_isstr(tr[i]))
429 tr[i] = emitir(IRTG(IR_STRTO, IRT_NUM), tr[i], 0);
430 if (t == IRT_INT) {
431 if (!tref_isinteger(tr[i]))
432 tr[i] = emitir(IRTI(IR_CONV), tr[i], IRCONV_INT_NUM|IRCONV_CHECK);
433 } else {
434 if (!tref_isnum(tr[i]))
435 tr[i] = emitir(IRTN(IR_CONV), tr[i], IRCONV_NUM_INT);
436 }
348 } 437 }
349 idx = tr[FORL_IDX]; 438 tr[FORL_EXT] = tr[FORL_IDX];
350 stop = tr[FORL_STOP]; 439 stop = tr[FORL_STOP];
351 if (!tref_isk(tr[FORL_STEP])) /* Non-const step: need direction guard. */ 440 rec_for_check(J, t, rec_for_direction(&tv[FORL_STEP]), stop, tr[FORL_STEP]);
352 emitir(IRTG(((op-IR_LT)>>1)+IR_LT, IRT_NUM),
353 tr[FORL_STEP], lj_ir_knum_zero(J));
354 } 441 }
355 442
356 tr[FORL_EXT] = idx; 443 ev = rec_for_iter(&op, tv, isforl);
357 if (ev == LOOPEV_LEAVE) { 444 if (ev == LOOPEV_LEAVE) {
358 J->maxslot = ra+FORL_EXT+1; 445 J->maxslot = ra+FORL_EXT+1;
359 J->pc = fori+1; 446 J->pc = fori+1;
@@ -363,7 +450,7 @@ static LoopEvent rec_for(jit_State *J, const BCIns *fori, int isforl)
363 } 450 }
364 lj_snap_add(J); 451 lj_snap_add(J);
365 452
366 emitir(IRTG(op, t), idx, stop); 453 emitir(IRTG(op, t), tr[FORL_IDX], stop);
367 454
368 if (ev == LOOPEV_LEAVE) { 455 if (ev == LOOPEV_LEAVE) {
369 J->maxslot = ra; 456 J->maxslot = ra;
@@ -870,7 +957,7 @@ static void rec_idx_abc(jit_State *J, TRef asizeref, TRef ikey, uint32_t asize)
870 if (ref == J->scev.idx) { 957 if (ref == J->scev.idx) {
871 int32_t stop; 958 int32_t stop;
872 lua_assert(irt_isint(J->scev.t) && ir->o == IR_SLOAD); 959 lua_assert(irt_isint(J->scev.t) && ir->o == IR_SLOAD);
873 stop = lj_num2int(numV(&(J->L->base - J->baseslot)[ir->op1 + FORL_STOP])); 960 stop = numberVint(&(J->L->base - J->baseslot)[ir->op1 + FORL_STOP]);
874 /* Runtime value for stop of loop is within bounds? */ 961 /* Runtime value for stop of loop is within bounds? */
875 if ((int64_t)stop + ofs < (int64_t)asize) { 962 if ((int64_t)stop + ofs < (int64_t)asize) {
876 /* Emit invariant bounds check for stop. */ 963 /* Emit invariant bounds check for stop. */
@@ -897,15 +984,12 @@ static TRef rec_idx_key(jit_State *J, RecordIndex *ix)
897 /* Integer keys are looked up in the array part first. */ 984 /* Integer keys are looked up in the array part first. */
898 key = ix->key; 985 key = ix->key;
899 if (tref_isnumber(key)) { 986 if (tref_isnumber(key)) {
900 lua_Number n = numV(&ix->keyv); 987 int32_t k = numberVint(&ix->keyv);
901 int32_t k = lj_num2int(n); 988 if (!tvisint(&ix->keyv) && numV(&ix->keyv) != (lua_Number)k)
902 lua_assert(tvisnum(&ix->keyv)); 989 k = LJ_MAX_ASIZE;
903 /* Potential array key? */ 990 if ((MSize)k < LJ_MAX_ASIZE) { /* Potential array key? */
904 if ((MSize)k < LJ_MAX_ASIZE && n == cast_num(k)) { 991 TRef ikey = lj_opt_narrow_index(J, key);
905 TRef asizeref, ikey = key; 992 TRef asizeref = emitir(IRTI(IR_FLOAD), ix->tab, IRFL_TAB_ASIZE);
906 if (!tref_isinteger(ikey))
907 ikey = emitir(IRTGI(IR_CONV), ikey, IRCONV_INT_NUM|IRCONV_INDEX);
908 asizeref = emitir(IRTI(IR_FLOAD), ix->tab, IRFL_TAB_ASIZE);
909 if ((MSize)k < t->asize) { /* Currently an array key? */ 993 if ((MSize)k < t->asize) { /* Currently an array key? */
910 TRef arrayref; 994 TRef arrayref;
911 rec_idx_abc(J, asizeref, ikey, t->asize); 995 rec_idx_abc(J, asizeref, ikey, t->asize);
@@ -1081,7 +1165,8 @@ TRef lj_record_idx(jit_State *J, RecordIndex *ix)
1081 } else { 1165 } else {
1082 keybarrier = 0; /* Previous non-nil value kept the key alive. */ 1166 keybarrier = 0; /* Previous non-nil value kept the key alive. */
1083 } 1167 }
1084 if (tref_isinteger(ix->val)) /* Convert int to number before storing. */ 1168 /* Convert int to number before storing. */
1169 if (!LJ_DUALNUM && tref_isinteger(ix->val))
1085 ix->val = emitir(IRTN(IR_CONV), ix->val, IRCONV_NUM_INT); 1170 ix->val = emitir(IRTN(IR_CONV), ix->val, IRCONV_NUM_INT);
1086 emitir(IRT(loadop+IRDELTA_L2S, tref_type(ix->val)), xref, ix->val); 1171 emitir(IRT(loadop+IRDELTA_L2S, tref_type(ix->val)), xref, ix->val);
1087 if (keybarrier || tref_isgcv(ix->val)) 1172 if (keybarrier || tref_isgcv(ix->val))
@@ -1135,7 +1220,8 @@ static TRef rec_upvalue(jit_State *J, uint32_t uv, TRef val)
1135 if (irtype_ispri(t)) res = TREF_PRI(t); /* Canonicalize primitive refs. */ 1220 if (irtype_ispri(t)) res = TREF_PRI(t); /* Canonicalize primitive refs. */
1136 return res; 1221 return res;
1137 } else { /* Upvalue store. */ 1222 } else { /* Upvalue store. */
1138 if (tref_isinteger(val)) /* Convert int to number before storing. */ 1223 /* Convert int to number before storing. */
1224 if (!LJ_DUALNUM && tref_isinteger(val))
1139 val = emitir(IRTN(IR_CONV), val, IRCONV_NUM_INT); 1225 val = emitir(IRTN(IR_CONV), val, IRCONV_NUM_INT);
1140 emitir(IRT(IR_USTORE, tref_type(val)), uref, val); 1226 emitir(IRT(IR_USTORE, tref_type(val)), uref, val);
1141 if (needbarrier && tref_isgcv(val)) 1227 if (needbarrier && tref_isgcv(val))
@@ -1455,16 +1541,15 @@ void lj_record_ins(jit_State *J)
1455 case BCMnone: rb = 0; rc = bc_d(ins); break; /* Upgrade rc to 'rd'. */ 1541 case BCMnone: rb = 0; rc = bc_d(ins); break; /* Upgrade rc to 'rd'. */
1456 case BCMvar: 1542 case BCMvar:
1457 copyTV(J->L, rbv, &lbase[rb]); ix.tab = rb = getslot(J, rb); break; 1543 copyTV(J->L, rbv, &lbase[rb]); ix.tab = rb = getslot(J, rb); break;
1458 case BCMnum: { lua_Number n = proto_knum(J->pt, rb);
1459 setnumV(rbv, n); ix.tab = rb = lj_ir_knumint(J, n); } break;
1460 default: break; /* Handled later. */ 1544 default: break; /* Handled later. */
1461 } 1545 }
1462 switch (bcmode_c(op)) { 1546 switch (bcmode_c(op)) {
1463 case BCMvar: 1547 case BCMvar:
1464 copyTV(J->L, rcv, &lbase[rc]); ix.key = rc = getslot(J, rc); break; 1548 copyTV(J->L, rcv, &lbase[rc]); ix.key = rc = getslot(J, rc); break;
1465 case BCMpri: setitype(rcv, ~rc); ix.key = rc = TREF_PRI(IRT_NIL+rc); break; 1549 case BCMpri: setitype(rcv, ~rc); ix.key = rc = TREF_PRI(IRT_NIL+rc); break;
1466 case BCMnum: { lua_Number n = proto_knum(J->pt, rc); 1550 case BCMnum: { cTValue *tv = proto_knumtv(J->pt, rc);
1467 setnumV(rcv, n); ix.key = rc = lj_ir_knumint(J, n); } break; 1551 copyTV(J->L, rcv, tv); ix.key = rc = tvisint(tv) ? lj_ir_kint(J, intV(tv)) :
1552 lj_ir_knumint(J, numV(tv)); } break;
1468 case BCMstr: { GCstr *s = gco2str(proto_kgc(J->pt, ~(ptrdiff_t)rc)); 1553 case BCMstr: { GCstr *s = gco2str(proto_kgc(J->pt, ~(ptrdiff_t)rc));
1469 setstrV(J->L, rcv, s); ix.key = rc = lj_ir_kstr(J, s); } break; 1554 setstrV(J->L, rcv, s); ix.key = rc = lj_ir_kstr(J, s); } break;
1470 default: break; /* Handled later. */ 1555 default: break; /* Handled later. */
@@ -1502,9 +1587,11 @@ void lj_record_ins(jit_State *J)
1502 irop = (int)op - (int)BC_ISLT + (int)IR_LT; 1587 irop = (int)op - (int)BC_ISLT + (int)IR_LT;
1503 if (ta == IRT_NUM) { 1588 if (ta == IRT_NUM) {
1504 if ((irop & 1)) irop ^= 4; /* ISGE/ISGT are unordered. */ 1589 if ((irop & 1)) irop ^= 4; /* ISGE/ISGT are unordered. */
1505 if (!lj_ir_numcmp(numV(rav), numV(rcv), (IROp)irop)) irop ^= 5; 1590 if (!lj_ir_numcmp(numberVnum(rav), numberVnum(rcv), (IROp)irop))
1591 irop ^= 5;
1506 } else if (ta == IRT_INT) { 1592 } else if (ta == IRT_INT) {
1507 if (!lj_ir_numcmp(numV(rav), numV(rcv), (IROp)irop)) irop ^= 1; 1593 if (!lj_ir_numcmp(numberVnum(rav), numberVnum(rcv), (IROp)irop))
1594 irop ^= 1;
1508 } else if (ta == IRT_STR) { 1595 } else if (ta == IRT_STR) {
1509 if (!lj_ir_strcmp(strV(rav), strV(rcv), (IROp)irop)) irop ^= 1; 1596 if (!lj_ir_strcmp(strV(rav), strV(rcv), (IROp)irop)) irop ^= 1;
1510 ra = lj_ir_call(J, IRCALL_lj_str_cmp, ra, rc); 1597 ra = lj_ir_call(J, IRCALL_lj_str_cmp, ra, rc);
@@ -1599,13 +1686,11 @@ void lj_record_ins(jit_State *J)
1599 case BC_ADDVN: case BC_SUBVN: case BC_MULVN: case BC_DIVVN: 1686 case BC_ADDVN: case BC_SUBVN: case BC_MULVN: case BC_DIVVN:
1600 case BC_ADDVV: case BC_SUBVV: case BC_MULVV: case BC_DIVVV: { 1687 case BC_ADDVV: case BC_SUBVV: case BC_MULVV: case BC_DIVVV: {
1601 MMS mm = bcmode_mm(op); 1688 MMS mm = bcmode_mm(op);
1602 if (tref_isnumber_str(rb) && tref_isnumber_str(rc)) { 1689 if (tref_isnumber_str(rb) && tref_isnumber_str(rc))
1603 rb = lj_ir_tonum(J, rb); 1690 rc = lj_opt_narrow_arith(J, rb, rc, &ix.tabv, &ix.keyv,
1604 rc = lj_ir_tonum(J, rc); 1691 (int)mm - (int)MM_add + (int)IR_ADD);
1605 rc = emitir(IRTN((int)mm - (int)MM_add + (int)IR_ADD), rb, rc); 1692 else
1606 } else {
1607 rc = rec_mm_arith(J, &ix, mm); 1693 rc = rec_mm_arith(J, &ix, mm);
1608 }
1609 break; 1694 break;
1610 } 1695 }
1611 1696
@@ -1827,59 +1912,6 @@ void lj_record_ins(jit_State *J)
1827 1912
1828/* -- Recording setup ----------------------------------------------------- */ 1913/* -- Recording setup ----------------------------------------------------- */
1829 1914
1830/* Setup recording for a FORL loop. */
1831static void rec_setup_forl(jit_State *J, const BCIns *fori)
1832{
1833 BCReg ra = bc_a(*fori);
1834 cTValue *forbase = &J->L->base[ra];
1835 IRType t = (J->flags & JIT_F_OPT_NARROW) ? lj_opt_narrow_forl(forbase)
1836 : IRT_NUM;
1837 TRef start;
1838 TRef stop = fori_arg(J, fori, ra+FORL_STOP, t);
1839 TRef step = fori_arg(J, fori, ra+FORL_STEP, t);
1840 int dir = (0 <= numV(&forbase[FORL_STEP]));
1841 lua_assert(bc_op(*fori) == BC_FORI || bc_op(*fori) == BC_JFORI);
1842 J->scev.t.irt = t;
1843 J->scev.dir = dir;
1844 J->scev.stop = tref_ref(stop);
1845 J->scev.step = tref_ref(step);
1846 if (!tref_isk(step)) {
1847 /* Non-constant step: need a guard for the direction. */
1848 TRef zero = (t == IRT_INT) ? lj_ir_kint(J, 0) : lj_ir_knum_zero(J);
1849 emitir(IRTG(dir ? IR_GE : IR_LT, t), step, zero);
1850 /* Add hoistable overflow checks for a narrowed FORL index. */
1851 if (t == IRT_INT) {
1852 if (tref_isk(stop)) {
1853 /* Constant stop: optimize check away or to a range check for step. */
1854 int32_t k = IR(tref_ref(stop))->i;
1855 if (dir) {
1856 if (k > 0)
1857 emitir(IRTGI(IR_LE), step, lj_ir_kint(J, (int32_t)0x7fffffff-k));
1858 } else {
1859 if (k < 0)
1860 emitir(IRTGI(IR_GE), step, lj_ir_kint(J, (int32_t)0x80000000-k));
1861 }
1862 } else {
1863 /* Stop+step variable: need full overflow check. */
1864 TRef tr = emitir(IRTGI(IR_ADDOV), step, stop);
1865 emitir(IRTI(IR_USE), tr, 0); /* ADDOV is weak. Avoid dead result. */
1866 }
1867 }
1868 } else if (t == IRT_INT && !tref_isk(stop)) {
1869 /* Constant step: optimize overflow check to a range check for stop. */
1870 int32_t k = IR(tref_ref(step))->i;
1871 k = (int32_t)(dir ? 0x7fffffff : 0x80000000) - k;
1872 emitir(IRTGI(dir ? IR_LE : IR_GE), stop, lj_ir_kint(J, k));
1873 }
1874 J->scev.start = tref_ref(find_kinit(J, fori, ra+FORL_IDX, IRT_INT));
1875 start = sloadt(J, (int32_t)(ra+FORL_IDX),
1876 (t == IRT_INT && !J->scev.start) ? (IRT_INT|IRT_GUARD) : t,
1877 t == IRT_INT ? (IRSLOAD_CONVERT|IRSLOAD_INHERIT) : IRSLOAD_INHERIT);
1878 J->base[ra+FORL_EXT] = start;
1879 J->scev.idx = tref_ref(start);
1880 J->maxslot = ra+FORL_EXT+1;
1881}
1882
1883/* Setup recording for a root trace started by a hot loop. */ 1915/* Setup recording for a root trace started by a hot loop. */
1884static const BCIns *rec_setup_root(jit_State *J) 1916static const BCIns *rec_setup_root(jit_State *J)
1885{ 1917{
@@ -2033,7 +2065,7 @@ void lj_record_setup(jit_State *J)
2033 if (J->pc > proto_bc(J->pt) && bc_op(J->pc[-1]) == BC_JFORI && 2065 if (J->pc > proto_bc(J->pt) && bc_op(J->pc[-1]) == BC_JFORI &&
2034 bc_d(J->pc[bc_j(J->pc[-1])-1]) == root) { 2066 bc_d(J->pc[bc_j(J->pc[-1])-1]) == root) {
2035 lj_snap_add(J); 2067 lj_snap_add(J);
2036 rec_setup_forl(J, J->pc-1); 2068 rec_for_loop(J, J->pc-1, &J->scev, 1);
2037 goto sidecheck; 2069 goto sidecheck;
2038 } 2070 }
2039 } else { 2071 } else {
@@ -2054,7 +2086,7 @@ void lj_record_setup(jit_State *J)
2054 */ 2086 */
2055 lj_snap_add(J); 2087 lj_snap_add(J);
2056 if (bc_op(J->cur.startins) == BC_FORL) 2088 if (bc_op(J->cur.startins) == BC_FORL)
2057 rec_setup_forl(J, J->pc-1); 2089 rec_for_loop(J, J->pc-1, &J->scev, 1);
2058 if (1 + J->pt->framesize >= LJ_MAX_JSLOTS) 2090 if (1 + J->pt->framesize >= LJ_MAX_JSLOTS)
2059 lj_trace_err(J, LJ_TRERR_STACKOV); 2091 lj_trace_err(J, LJ_TRERR_STACKOV);
2060 } 2092 }