mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-08 07:34:07 +00:00
Improve coalescing of multiple KPRI instructions to KNIL.
This commit is contained in:
parent
00d10711ae
commit
8876704e05
@ -419,14 +419,48 @@ static void expr_discharge(FuncState *fs, ExpDesc *e)
|
|||||||
e->k = VRELOCABLE;
|
e->k = VRELOCABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Emit bytecode to set a range of registers to nil. */
|
||||||
|
static void bcemit_nil(FuncState *fs, BCReg from, BCReg n)
|
||||||
|
{
|
||||||
|
if (fs->pc > fs->lasttarget) { /* No jumps to current position? */
|
||||||
|
BCIns *ip = &fs->bcbase[fs->pc-1].ins;
|
||||||
|
BCReg pto, pfrom = bc_a(*ip);
|
||||||
|
switch (bc_op(*ip)) { /* Try to merge with the previous instruction. */
|
||||||
|
case BC_KPRI:
|
||||||
|
if (bc_d(*ip) != ~LJ_TNIL) break;
|
||||||
|
if (from == pfrom) {
|
||||||
|
if (n == 1) return;
|
||||||
|
} else if (from == pfrom+1) {
|
||||||
|
from = pfrom;
|
||||||
|
n++;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
fs->pc--; /* Drop KPRI. */
|
||||||
|
break;
|
||||||
|
case BC_KNIL:
|
||||||
|
pto = bc_d(*ip);
|
||||||
|
if (pfrom <= from && from <= pto+1) { /* Can we connect both ranges? */
|
||||||
|
if (from+n-1 > pto)
|
||||||
|
setbc_d(ip, from+n-1); /* Patch previous instruction range. */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Emit new instruction or replace old instruction. */
|
||||||
|
bcemit_INS(fs, n == 1 ? BCINS_AD(BC_KPRI, from, VKNIL) :
|
||||||
|
BCINS_AD(BC_KNIL, from, from+n-1));
|
||||||
|
}
|
||||||
|
|
||||||
/* Discharge an expression to a specific register. Ignore branches. */
|
/* Discharge an expression to a specific register. Ignore branches. */
|
||||||
static void expr_toreg_nobranch(FuncState *fs, ExpDesc *e, BCReg reg)
|
static void expr_toreg_nobranch(FuncState *fs, ExpDesc *e, BCReg reg)
|
||||||
{
|
{
|
||||||
BCIns ins;
|
BCIns ins;
|
||||||
expr_discharge(fs, e);
|
expr_discharge(fs, e);
|
||||||
if (e->k <= VKTRUE) {
|
if (e->k == VKSTR) {
|
||||||
ins = BCINS_AD(BC_KPRI, reg, const_pri(e));
|
|
||||||
} else if (e->k == VKSTR) {
|
|
||||||
ins = BCINS_AD(BC_KSTR, reg, const_str(fs, e));
|
ins = BCINS_AD(BC_KSTR, reg, const_str(fs, e));
|
||||||
} else if (e->k == VKNUM) {
|
} else if (e->k == VKNUM) {
|
||||||
lua_Number n = expr_numV(e);
|
lua_Number n = expr_numV(e);
|
||||||
@ -442,6 +476,11 @@ static void expr_toreg_nobranch(FuncState *fs, ExpDesc *e, BCReg reg)
|
|||||||
if (reg == e->u.s.info)
|
if (reg == e->u.s.info)
|
||||||
goto noins;
|
goto noins;
|
||||||
ins = BCINS_AD(BC_MOV, reg, e->u.s.info);
|
ins = BCINS_AD(BC_MOV, reg, e->u.s.info);
|
||||||
|
} else if (e->k == VKNIL) {
|
||||||
|
bcemit_nil(fs, reg, 1);
|
||||||
|
goto noins;
|
||||||
|
} else if (e->k <= VKTRUE) {
|
||||||
|
ins = BCINS_AD(BC_KPRI, reg, const_pri(e));
|
||||||
} else {
|
} else {
|
||||||
lua_assert(e->k == VVOID || e->k == VJMP);
|
lua_assert(e->k == VVOID || e->k == VJMP);
|
||||||
return;
|
return;
|
||||||
@ -577,42 +616,6 @@ static void bcemit_method(FuncState *fs, ExpDesc *e, ExpDesc *key)
|
|||||||
e->k = VNONRELOC;
|
e->k = VNONRELOC;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Emit bytecode to set a range of registers to nil. */
|
|
||||||
static void bcemit_nil(FuncState *fs, BCReg from, BCReg n)
|
|
||||||
{
|
|
||||||
if (fs->pc > fs->lasttarget) { /* No jumps to current position? */
|
|
||||||
BCIns *ip = &fs->bcbase[fs->pc-1].ins;
|
|
||||||
BCReg pto, pfrom = bc_a(*ip);
|
|
||||||
switch (bc_op(*ip)) { /* Try to merge with the previous instruction. */
|
|
||||||
case BC_KPRI:
|
|
||||||
if (bc_d(*ip) != ~LJ_TNIL) break;
|
|
||||||
if (from == pfrom) {
|
|
||||||
if (n == 1) return;
|
|
||||||
} else if (from == pfrom+1) {
|
|
||||||
from = pfrom;
|
|
||||||
n++;
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
fs->pc--; /* Drop KPRI. */
|
|
||||||
break;
|
|
||||||
case BC_KNIL:
|
|
||||||
pto = bc_d(*ip);
|
|
||||||
if (pfrom <= from && from <= pto+1) { /* Can we connect both ranges? */
|
|
||||||
if (from+n-1 > pto)
|
|
||||||
setbc_d(ip, from+n-1); /* Patch previous instruction range. */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Emit new instruction or replace old instruction. */
|
|
||||||
bcemit_INS(fs, n == 1 ? BCINS_AD(BC_KPRI, from, VKNIL) :
|
|
||||||
BCINS_AD(BC_KNIL, from, from+n-1));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -- Bytecode emitter for branches --------------------------------------- */
|
/* -- Bytecode emitter for branches --------------------------------------- */
|
||||||
|
|
||||||
/* Emit unconditional branch. */
|
/* Emit unconditional branch. */
|
||||||
|
Loading…
Reference in New Issue
Block a user