Optimize table length computation with hinting.

10x faster on loop with t[#t+1] = x idiom. Also used by table.insert.
This commit is contained in:
Mike Pall
2020-05-27 19:20:44 +02:00
parent b2307c8ad8
commit 1a4ff13117
12 changed files with 135 additions and 82 deletions

View File

@@ -281,7 +281,7 @@ static void LJ_FASTCALL recff_rawlen(jit_State *J, RecordFFData *rd)
if (tref_isstr(tr))
J->base[0] = emitir(IRTI(IR_FLOAD), tr, IRFL_STR_LEN);
else if (tref_istab(tr))
J->base[0] = lj_ir_call(J, IRCALL_lj_tab_len, tr);
J->base[0] = emitir(IRTI(IR_ALEN), tr, TREF_NIL);
/* else: Interpreter will throw. */
UNUSED(rd);
}
@@ -1026,7 +1026,7 @@ static void LJ_FASTCALL recff_table_insert(jit_State *J, RecordFFData *rd)
rd->nres = 0;
if (tref_istab(ix.tab) && ix.val) {
if (!J->base[2]) { /* Simple push: t[#t+1] = v */
TRef trlen = lj_ir_call(J, IRCALL_lj_tab_len, ix.tab);
TRef trlen = emitir(IRTI(IR_ALEN), ix.tab, TREF_NIL);
GCtab *t = tabV(&rd->argv[0]);
ix.key = emitir(IRTI(IR_ADD), trlen, lj_ir_kint(J, 1));
settabV(J->L, &ix.tabv, t);
@@ -1050,7 +1050,7 @@ static void LJ_FASTCALL recff_table_concat(jit_State *J, RecordFFData *rd)
lj_opt_narrow_toint(J, J->base[2]) : lj_ir_kint(J, 1);
TRef tre = (J->base[1] && J->base[2] && !tref_isnil(J->base[3])) ?
lj_opt_narrow_toint(J, J->base[3]) :
lj_ir_call(J, IRCALL_lj_tab_len, tab);
emitir(IRTI(IR_ALEN), tab, TREF_NIL);
TRef hdr = recff_bufhdr(J);
TRef tr = lj_ir_call(J, IRCALL_lj_buf_puttab, hdr, tab, sep, tri, tre);
emitir(IRTG(IR_NE, IRT_PTR), tr, lj_ir_kptr(J, NULL));