mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-07 23:24:09 +00:00
Decouple guard vs. INT check vs. TYPECHECK semantics for SLOAD.
This commit is contained in:
parent
36769c2f6b
commit
a61df8efbe
@ -209,7 +209,8 @@ local colorize, irtype
|
|||||||
|
|
||||||
-- Lookup table to convert some literals into names.
|
-- Lookup table to convert some literals into names.
|
||||||
local litname = {
|
local litname = {
|
||||||
["SLOAD "] = { [0] = "", "I", "R", "RI", "P", "PI", "PR", "PRI", },
|
["SLOAD "] = { [0] = "", "I", "R", "RI", "P", "PI", "PR", "PRI",
|
||||||
|
"T", "IT", "RT", "RIT", "PT", "PIT", "PRT", "PRIT", },
|
||||||
["XLOAD "] = { [0] = "", "R", "U", "RU", },
|
["XLOAD "] = { [0] = "", "R", "U", "RU", },
|
||||||
["TOINT "] = { [0] = "check", "index", "", },
|
["TOINT "] = { [0] = "check", "index", "", },
|
||||||
["FLOAD "] = vmdef.irfield,
|
["FLOAD "] = vmdef.irfield,
|
||||||
|
@ -1852,6 +1852,8 @@ static void asm_sload(ASMState *as, IRIns *ir)
|
|||||||
IRType1 t = ir->t;
|
IRType1 t = ir->t;
|
||||||
Reg base;
|
Reg base;
|
||||||
lua_assert(!(ir->op2 & IRSLOAD_PARENT)); /* Handled by asm_head_side(). */
|
lua_assert(!(ir->op2 & IRSLOAD_PARENT)); /* Handled by asm_head_side(). */
|
||||||
|
lua_assert(!irt_isguard(ir->t) ==
|
||||||
|
!((ir->op2 & IRSLOAD_TYPECHECK) || irt_isint(t)));
|
||||||
if (irt_isint(t)) {
|
if (irt_isint(t)) {
|
||||||
Reg left = ra_scratch(as, RSET_FPR);
|
Reg left = ra_scratch(as, RSET_FPR);
|
||||||
asm_tointg(as, ir, left); /* Frees dest reg. Do this before base alloc. */
|
asm_tointg(as, ir, left); /* Frees dest reg. Do this before base alloc. */
|
||||||
@ -1865,11 +1867,11 @@ static void asm_sload(ASMState *as, IRIns *ir)
|
|||||||
base = ra_alloc1(as, REF_BASE, RSET_GPR);
|
base = ra_alloc1(as, REF_BASE, RSET_GPR);
|
||||||
emit_movrmro(as, dest, base, ofs);
|
emit_movrmro(as, dest, base, ofs);
|
||||||
} else {
|
} else {
|
||||||
if (!irt_isguard(ir->t))
|
if (!(ir->op2 & IRSLOAD_TYPECHECK))
|
||||||
return; /* No type check: avoid base alloc. */
|
return; /* No type check: avoid base alloc. */
|
||||||
base = ra_alloc1(as, REF_BASE, RSET_GPR);
|
base = ra_alloc1(as, REF_BASE, RSET_GPR);
|
||||||
}
|
}
|
||||||
if (irt_isguard(ir->t)) {
|
if ((ir->op2 & IRSLOAD_TYPECHECK)) {
|
||||||
/* Need type check, even if the load result is unused. */
|
/* Need type check, even if the load result is unused. */
|
||||||
asm_guardcc(as, irt_isnum(t) ? CC_A : CC_NE);
|
asm_guardcc(as, irt_isnum(t) ? CC_A : CC_NE);
|
||||||
emit_i8(as, ~irt_type(t));
|
emit_i8(as, ~irt_type(t));
|
||||||
|
@ -192,6 +192,7 @@ IRFLDEF(FLENUM)
|
|||||||
#define IRSLOAD_INHERIT 1 /* Inherited by exits/side traces. */
|
#define IRSLOAD_INHERIT 1 /* Inherited by exits/side traces. */
|
||||||
#define IRSLOAD_READONLY 2 /* Read-only, omit slot store. */
|
#define IRSLOAD_READONLY 2 /* Read-only, omit slot store. */
|
||||||
#define IRSLOAD_PARENT 4 /* Coalesce with parent trace. */
|
#define IRSLOAD_PARENT 4 /* Coalesce with parent trace. */
|
||||||
|
#define IRSLOAD_TYPECHECK 8 /* Needs type check. */
|
||||||
|
|
||||||
/* XLOAD mode, stored in op2. */
|
/* XLOAD mode, stored in op2. */
|
||||||
#define IRXLOAD_READONLY 1 /* Load from read-only data. */
|
#define IRXLOAD_READONLY 1 /* Load from read-only data. */
|
||||||
|
@ -125,7 +125,7 @@ static void rec_check_slots(jit_State *J)
|
|||||||
/* Specialize a slot to a specific type. Note: slot can be negative! */
|
/* Specialize a slot to a specific type. Note: slot can be negative! */
|
||||||
static TRef sloadt(jit_State *J, int32_t slot, IRType t, int mode)
|
static TRef sloadt(jit_State *J, int32_t slot, IRType t, int mode)
|
||||||
{
|
{
|
||||||
/* No guard, since none of the callers need a type-checking SLOAD. */
|
/* Caller may set IRT_GUARD in t. */
|
||||||
TRef ref = emitir_raw(IRT(IR_SLOAD, t), (int32_t)J->baseslot+slot, mode);
|
TRef ref = emitir_raw(IRT(IR_SLOAD, t), (int32_t)J->baseslot+slot, mode);
|
||||||
J->base[slot] = ref;
|
J->base[slot] = ref;
|
||||||
return ref;
|
return ref;
|
||||||
@ -135,7 +135,8 @@ static TRef sloadt(jit_State *J, int32_t slot, IRType t, int mode)
|
|||||||
static TRef sload(jit_State *J, int32_t slot)
|
static TRef sload(jit_State *J, int32_t slot)
|
||||||
{
|
{
|
||||||
IRType t = itype2irt(&J->L->base[slot]);
|
IRType t = itype2irt(&J->L->base[slot]);
|
||||||
TRef ref = emitir_raw(IRTG(IR_SLOAD, t), (int32_t)J->baseslot+slot, 0);
|
TRef ref = emitir_raw(IRTG(IR_SLOAD, t), (int32_t)J->baseslot+slot,
|
||||||
|
IRSLOAD_TYPECHECK);
|
||||||
if (irtype_ispri(t)) ref = TREF_PRI(t); /* Canonicalize primitive refs. */
|
if (irtype_ispri(t)) ref = TREF_PRI(t); /* Canonicalize primitive refs. */
|
||||||
J->base[slot] = ref;
|
J->base[slot] = ref;
|
||||||
return ref;
|
return ref;
|
||||||
@ -251,8 +252,9 @@ static TRef fori_arg(jit_State *J, const BCIns *pc, BCReg slot, IRType t)
|
|||||||
}
|
}
|
||||||
if (J->base[slot])
|
if (J->base[slot])
|
||||||
return J->base[slot];
|
return J->base[slot];
|
||||||
else
|
if (t == IRT_INT)
|
||||||
return sloadt(J, (int32_t)slot, t, IRSLOAD_READONLY|IRSLOAD_INHERIT);
|
t |= IRT_GUARD;
|
||||||
|
return sloadt(J, (int32_t)slot, t, IRSLOAD_READONLY|IRSLOAD_INHERIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Simulate the runtime behavior of the FOR loop iterator.
|
/* Simulate the runtime behavior of the FOR loop iterator.
|
||||||
@ -2107,6 +2109,8 @@ static void rec_setup_forl(jit_State *J, const BCIns *fori)
|
|||||||
k = (int32_t)(dir ? 0x7fffffff : 0x80000000) - k;
|
k = (int32_t)(dir ? 0x7fffffff : 0x80000000) - k;
|
||||||
emitir(IRTGI(dir ? IR_LE : IR_GE), stop, lj_ir_kint(J, k));
|
emitir(IRTGI(dir ? IR_LE : IR_GE), stop, lj_ir_kint(J, k));
|
||||||
}
|
}
|
||||||
|
if (t == IRT_INT)
|
||||||
|
t |= IRT_GUARD;
|
||||||
J->base[ra+FORL_EXT] = sloadt(J, (int32_t)(ra+FORL_IDX), t, IRSLOAD_INHERIT);
|
J->base[ra+FORL_EXT] = sloadt(J, (int32_t)(ra+FORL_IDX), t, IRSLOAD_INHERIT);
|
||||||
J->maxslot = ra+FORL_EXT+1;
|
J->maxslot = ra+FORL_EXT+1;
|
||||||
}
|
}
|
||||||
@ -2195,7 +2199,7 @@ static void rec_setup_side(jit_State *J, Trace *T)
|
|||||||
tr = emitir_raw(IRT(IR_FRAME, IRT_PTR), tr, tr);
|
tr = emitir_raw(IRT(IR_FRAME, IRT_PTR), tr, tr);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case IR_SLOAD: /* Inherited SLOADs don't need a guard. */
|
case IR_SLOAD: /* Inherited SLOADs don't need a guard or type check. */
|
||||||
tr = emitir_raw(ir->ot & ~IRT_GUARD, s,
|
tr = emitir_raw(ir->ot & ~IRT_GUARD, s,
|
||||||
(ir->op2&IRSLOAD_READONLY) | IRSLOAD_INHERIT|IRSLOAD_PARENT);
|
(ir->op2&IRSLOAD_READONLY) | IRSLOAD_INHERIT|IRSLOAD_PARENT);
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user