small peephole optimizations
This commit is contained in:
89
lcode.c
89
lcode.c
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lcode.c,v 2.138 2017/11/28 15:26:15 roberto Exp roberto $
|
** $Id: lcode.c,v 2.140 2017/11/30 13:17:06 roberto Exp roberto $
|
||||||
** Code generator for Lua
|
** Code generator for Lua
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -134,17 +134,10 @@ void luaK_concat (FuncState *fs, int *l1, int l2) {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
** Create a jump instruction and return its position, so its destination
|
** Create a jump instruction and return its position, so its destination
|
||||||
** can be fixed later (with 'fixjump'). If there are jumps to
|
** can be fixed later (with 'fixjump').
|
||||||
** this position (kept in 'jpc'), link them all together so that
|
|
||||||
** 'patchlistaux' will fix all them directly to the final destination.
|
|
||||||
*/
|
*/
|
||||||
int luaK_jump (FuncState *fs) {
|
int luaK_jump (FuncState *fs) {
|
||||||
int jpc = fs->jpc; /* save list of jumps to here */
|
return codesJ(fs, OP_JMP, NO_JUMP, 0);
|
||||||
int j;
|
|
||||||
fs->jpc = NO_JUMP; /* no more jumps to here */
|
|
||||||
j = codesJ(fs, OP_JMP, NO_JUMP, 0);
|
|
||||||
luaK_concat(fs, &j, jpc); /* keep them on hold */
|
|
||||||
return j;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -249,39 +242,20 @@ static void patchlistaux (FuncState *fs, int list, int vtarget, int reg,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Ensure all pending jumps to current position are fixed (jumping
|
|
||||||
** to current position with no values) and reset list of pending
|
|
||||||
** jumps
|
|
||||||
*/
|
|
||||||
static void dischargejpc (FuncState *fs) {
|
|
||||||
patchlistaux(fs, fs->jpc, fs->pc, NO_REG, fs->pc);
|
|
||||||
fs->jpc = NO_JUMP;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Add elements in 'list' to list of pending jumps to "here"
|
|
||||||
** (current position)
|
|
||||||
*/
|
|
||||||
void luaK_patchtohere (FuncState *fs, int list) {
|
|
||||||
luaK_getlabel(fs); /* mark "here" as a jump target */
|
|
||||||
luaK_concat(fs, &fs->jpc, list);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Path all jumps in 'list' to jump to 'target'.
|
** Path all jumps in 'list' to jump to 'target'.
|
||||||
** (The assert means that we cannot fix a jump to a forward address
|
** (The assert means that we cannot fix a jump to a forward address
|
||||||
** because we only know addresses once code is generated.)
|
** because we only know addresses once code is generated.)
|
||||||
*/
|
*/
|
||||||
void luaK_patchlist (FuncState *fs, int list, int target) {
|
void luaK_patchlist (FuncState *fs, int list, int target) {
|
||||||
if (target == fs->pc) /* 'target' is current position? */
|
lua_assert(target <= fs->pc);
|
||||||
luaK_patchtohere(fs, list); /* add list to pending jumps */
|
|
||||||
else {
|
|
||||||
lua_assert(target < fs->pc);
|
|
||||||
patchlistaux(fs, list, target, NO_REG, target);
|
patchlistaux(fs, list, target, NO_REG, target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void luaK_patchtohere (FuncState *fs, int list) {
|
||||||
|
int hr = luaK_getlabel(fs); /* mark "here" as a jump target */
|
||||||
|
luaK_patchlist(fs, list, hr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -365,7 +339,6 @@ static void savelineinfo (FuncState *fs, Proto *f, int pc, int line) {
|
|||||||
*/
|
*/
|
||||||
static int luaK_code (FuncState *fs, Instruction i) {
|
static int luaK_code (FuncState *fs, Instruction i) {
|
||||||
Proto *f = fs->f;
|
Proto *f = fs->f;
|
||||||
dischargejpc(fs); /* 'pc' will change */
|
|
||||||
/* put new instruction in code array */
|
/* put new instruction in code array */
|
||||||
luaM_growvector(fs->ls->L, f->code, fs->pc, f->sizecode, Instruction,
|
luaM_growvector(fs->ls->L, f->code, fs->pc, f->sizecode, Instruction,
|
||||||
MAX_INT, "opcodes");
|
MAX_INT, "opcodes");
|
||||||
@@ -1537,3 +1510,45 @@ void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) {
|
|||||||
fs->freereg = base + 1; /* free registers with list values */
|
fs->freereg = base + 1; /* free registers with list values */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** return the final target of a jump (skipping jumps to jumps)
|
||||||
|
*/
|
||||||
|
static int finaltarget (Instruction *code, int i) {
|
||||||
|
int count;
|
||||||
|
for (count = 0; count < 100; count++) { /* avoid infinite loops */
|
||||||
|
Instruction pc = code[i];
|
||||||
|
if (GET_OPCODE(pc) != OP_JMP)
|
||||||
|
break;
|
||||||
|
else
|
||||||
|
i += GETARG_sJ(pc) + 1;
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Do a final pass over the code of a function, doing small peephole
|
||||||
|
** optimizations and adjustments.
|
||||||
|
*/
|
||||||
|
void luaK_finish (FuncState *fs) {
|
||||||
|
int i;
|
||||||
|
Proto *p = fs->f;
|
||||||
|
for (i = 0; i < fs->pc; i++) {
|
||||||
|
Instruction *pc = &p->code[i];
|
||||||
|
switch (GET_OPCODE(*pc)) {
|
||||||
|
case OP_RETURN: case OP_RETURN0: case OP_RETURN1:
|
||||||
|
case OP_TAILCALL: {
|
||||||
|
if (p->sizep > 0)
|
||||||
|
SETARG_k(*pc, 1); /* signal that they must close upvalues */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case OP_JMP: {
|
||||||
|
int target = finaltarget(p->code, i);
|
||||||
|
fixjump(fs, i, target);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
3
lcode.h
3
lcode.h
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lcode.h,v 1.67 2017/09/28 16:53:29 roberto Exp roberto $
|
** $Id: lcode.h,v 1.68 2017/10/04 21:56:32 roberto Exp roberto $
|
||||||
** Code generator for Lua
|
** Code generator for Lua
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -88,6 +88,7 @@ LUAI_FUNC void luaK_infix (FuncState *fs, BinOpr op, expdesc *v);
|
|||||||
LUAI_FUNC void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1,
|
LUAI_FUNC void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1,
|
||||||
expdesc *v2, int line);
|
expdesc *v2, int line);
|
||||||
LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore);
|
LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore);
|
||||||
|
LUAI_FUNC void luaK_finish (FuncState *fs);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lparser.c,v 2.167 2017/10/04 21:53:03 roberto Exp roberto $
|
** $Id: lparser.c,v 2.168 2017/11/23 16:35:54 roberto Exp roberto $
|
||||||
** Lua Parser
|
** Lua Parser
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -547,7 +547,6 @@ static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) {
|
|||||||
fs->previousline = f->linedefined;
|
fs->previousline = f->linedefined;
|
||||||
fs->iwthabs = 0;
|
fs->iwthabs = 0;
|
||||||
fs->lasttarget = 0;
|
fs->lasttarget = 0;
|
||||||
fs->jpc = NO_JUMP;
|
|
||||||
fs->freereg = 0;
|
fs->freereg = 0;
|
||||||
fs->nk = 0;
|
fs->nk = 0;
|
||||||
fs->nabslineinfo = 0;
|
fs->nabslineinfo = 0;
|
||||||
@@ -569,6 +568,7 @@ static void close_func (LexState *ls) {
|
|||||||
Proto *f = fs->f;
|
Proto *f = fs->f;
|
||||||
luaK_ret(fs, 0, 0); /* final return */
|
luaK_ret(fs, 0, 0); /* final return */
|
||||||
leaveblock(fs);
|
leaveblock(fs);
|
||||||
|
luaK_finish(fs);
|
||||||
luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction);
|
luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction);
|
||||||
f->sizecode = fs->pc;
|
f->sizecode = fs->pc;
|
||||||
luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->pc, ls_byte);
|
luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->pc, ls_byte);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lparser.h,v 1.77 2017/04/28 20:57:45 roberto Exp roberto $
|
** $Id: lparser.h,v 1.78 2017/06/27 11:35:31 roberto Exp roberto $
|
||||||
** Lua Parser
|
** Lua Parser
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -124,7 +124,6 @@ typedef struct FuncState {
|
|||||||
int pc; /* next position to code (equivalent to 'ncode') */
|
int pc; /* next position to code (equivalent to 'ncode') */
|
||||||
int lasttarget; /* 'label' of last 'jump label' */
|
int lasttarget; /* 'label' of last 'jump label' */
|
||||||
int previousline; /* last line that was saved in 'lineinfo' */
|
int previousline; /* last line that was saved in 'lineinfo' */
|
||||||
int jpc; /* list of pending jumps to 'pc' */
|
|
||||||
int nk; /* number of elements in 'k' */
|
int nk; /* number of elements in 'k' */
|
||||||
int np; /* number of elements in 'p' */
|
int np; /* number of elements in 'p' */
|
||||||
int nabslineinfo; /* number of elements in 'abslineinfo' */
|
int nabslineinfo; /* number of elements in 'abslineinfo' */
|
||||||
|
|||||||
10
lvm.c
10
lvm.c
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lvm.c,v 2.321 2017/11/29 13:02:17 roberto Exp roberto $
|
** $Id: lvm.c,v 2.322 2017/11/29 16:57:36 roberto Exp roberto $
|
||||||
** Lua virtual machine
|
** Lua virtual machine
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -1453,7 +1453,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
|||||||
/* next instruction will do the return */
|
/* next instruction will do the return */
|
||||||
}
|
}
|
||||||
else { /* tail call */
|
else { /* tail call */
|
||||||
if (cl->p->sizep > 0) /* close upvalues from previous call */
|
if (TESTARG_k(i)) /* close upvalues from previous call */
|
||||||
luaF_close(L, ci->func + 1);
|
luaF_close(L, ci->func + 1);
|
||||||
luaD_pretailcall(L, ci, ra, b); /* prepare call frame */
|
luaD_pretailcall(L, ci, ra, b); /* prepare call frame */
|
||||||
goto tailcall;
|
goto tailcall;
|
||||||
@@ -1462,7 +1462,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
|||||||
}
|
}
|
||||||
vmcase(OP_RETURN) {
|
vmcase(OP_RETURN) {
|
||||||
int b = GETARG_B(i);
|
int b = GETARG_B(i);
|
||||||
if (cl->p->sizep > 0)
|
if (TESTARG_k(i))
|
||||||
luaF_close(L, base);
|
luaF_close(L, base);
|
||||||
halfProtect(
|
halfProtect(
|
||||||
luaD_poscall(L, ci, ra, (b != 0 ? b - 1 : cast_int(L->top - ra)))
|
luaD_poscall(L, ci, ra, (b != 0 ? b - 1 : cast_int(L->top - ra)))
|
||||||
@@ -1470,7 +1470,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
vmcase(OP_RETURN0) {
|
vmcase(OP_RETURN0) {
|
||||||
if (cl->p->sizep > 0)
|
if (TESTARG_k(i))
|
||||||
luaF_close(L, base);
|
luaF_close(L, base);
|
||||||
if (L->hookmask)
|
if (L->hookmask)
|
||||||
halfProtect(luaD_poscall(L, ci, ra, 0)); /* no hurry... */
|
halfProtect(luaD_poscall(L, ci, ra, 0)); /* no hurry... */
|
||||||
@@ -1484,7 +1484,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
vmcase(OP_RETURN1) {
|
vmcase(OP_RETURN1) {
|
||||||
if (cl->p->sizep > 0)
|
if (TESTARG_k(i))
|
||||||
luaF_close(L, base);
|
luaF_close(L, base);
|
||||||
if (L->hookmask)
|
if (L->hookmask)
|
||||||
halfProtect(luaD_poscall(L, ci, ra, 1)); /* no hurry... */
|
halfProtect(luaD_poscall(L, ci, ra, 1)); /* no hurry... */
|
||||||
|
|||||||
Reference in New Issue
Block a user