Fast forward to sync public repo.

Compile math.sinh(), math.cosh(), math.tanh() and math.random().
Compile various io.*() functions.
Drive the GC forward on string allocations in the parser.
Improve KNUM fuse vs. load heuristics.
Add abstract C call handling to IR.
This commit is contained in:
Mike Pall
2009-12-08 20:35:29 +01:00
parent 5287b93264
commit 3f1f9e11f4
44 changed files with 1218 additions and 766 deletions

View File

@@ -282,21 +282,50 @@ LJFOLD(STRTO KGC)
LJFOLDF(kfold_strto)
{
TValue n;
if (lj_str_numconv(strdata(ir_kstr(fleft)), &n))
if (lj_str_tonum(ir_kstr(fleft), &n))
return lj_ir_knum(J, numV(&n));
return FAILFOLD;
}
LJFOLD(SNEW STRREF KINT)
LJFOLDF(kfold_snew)
LJFOLD(SNEW KPTR KINT)
LJFOLDF(kfold_snew_kptr)
{
GCstr *s = lj_str_new(J->L, (const char *)ir_kptr(fleft), (size_t)fright->i);
return lj_ir_kstr(J, s);
}
LJFOLD(SNEW any KINT)
LJFOLDF(kfold_snew_empty)
{
if (fright->i == 0)
return lj_ir_kstr(J, lj_str_new(J->L, "", 0));
return NEXTFOLD;
}
LJFOLD(STRREF KGC KINT)
LJFOLDF(kfold_strref)
{
GCstr *str = ir_kstr(fleft);
lua_assert((MSize)fright->i < str->len);
return lj_ir_kptr(J, (char *)strdata(str) + fright->i);
}
LJFOLD(STRREF SNEW any)
LJFOLDF(kfold_strref_snew)
{
PHIBARRIER(fleft);
if (irref_isk(fleft->op1) && irref_isk(fleft->op2)) {
const char *s = strdata(ir_kstr(IR(fleft->op1)));
int32_t ofs = IR(fleft->op2)->i;
return lj_ir_kstr(J, lj_str_new(J->L, s+ofs, (size_t)fright->i));
if (irref_isk(fins->op2) && fright->i == 0) {
return fleft->op1; /* strref(snew(ptr, len), 0) ==> ptr */
} else {
/* Reassociate: strref(snew(strref(str, a), len), b) ==> strref(str, a+b) */
IRIns *ir = IR(fleft->op1);
IRRef1 str = ir->op1; /* IRIns * is not valid across emitir. */
lua_assert(ir->o == IR_STRREF);
PHIBARRIER(ir);
fins->op2 = emitir(IRTI(IR_ADD), ir->op2, fins->op2); /* Clobbers fins! */
fins->op1 = str;
fins->ot = IRT(IR_STRREF, IRT_PTR);
return RETRYFOLD;
}
return NEXTFOLD;
}
@@ -343,16 +372,13 @@ LJFOLDF(kfold_intcomp)
}
}
LJFOLD(LT KGC KGC)
LJFOLD(GE KGC KGC)
LJFOLD(LE KGC KGC)
LJFOLD(GT KGC KGC)
LJFOLDF(kfold_strcomp)
LJFOLD(CALLN CARG IRCALL_lj_str_cmp)
LJFOLDF(kfold_strcmp)
{
if (irt_isstr(fins->t)) {
GCstr *a = ir_kstr(fleft);
GCstr *b = ir_kstr(fright);
return CONDFOLD(lj_ir_strcmp(a, b, (IROp)fins->o));
if (irref_isk(fleft->op1) && irref_isk(fleft->op2)) {
GCstr *a = ir_kstr(IR(fleft->op1));
GCstr *b = ir_kstr(IR(fleft->op2));
return INTFOLD(lj_str_cmp(a, b));
}
return NEXTFOLD;
}
@@ -1070,7 +1096,8 @@ LJFOLDF(merge_eqne_snew_kgc)
uint16_t ot = (uint16_t)(len == 1 ? IRT(IR_XLOAD, IRT_I8) :
len == 2 ? IRT(IR_XLOAD, IRT_U16) :
IRTI(IR_XLOAD));
TRef tmp = emitir(ot, strref, len > 1 ? IRXLOAD_UNALIGNED : 0);
TRef tmp = emitir(ot, strref,
IRXLOAD_READONLY | (len > 1 ? IRXLOAD_UNALIGNED : 0));
TRef val = lj_ir_kint(J, kfold_xload(IR(tref_ref(tmp)), strdata(kstr)));
if (len == 3)
tmp = emitir(IRTI(IR_BAND), tmp,
@@ -1103,8 +1130,8 @@ LJFOLDX(lj_opt_fwd_hload)
LJFOLD(ULOAD any)
LJFOLDX(lj_opt_fwd_uload)
LJFOLD(TLEN any)
LJFOLDX(lj_opt_fwd_tlen)
LJFOLD(CALLL any IRCALL_lj_tab_len)
LJFOLDX(lj_opt_fwd_tab_len)
/* Upvalue refs are really loads, but there are no corresponding stores.
** So CSE is ok for them, except for UREFO across a GC step (see below).
@@ -1194,13 +1221,23 @@ LJFOLDF(fload_tab_ah)
/* Strings are immutable, so we can safely FOLD/CSE the related FLOAD. */
LJFOLD(FLOAD KGC IRFL_STR_LEN)
LJFOLDF(fload_str_len)
LJFOLDF(fload_str_len_kgc)
{
if (LJ_LIKELY(J->flags & JIT_F_OPT_FOLD))
return INTFOLD((int32_t)ir_kstr(fleft)->len);
return NEXTFOLD;
}
LJFOLD(FLOAD SNEW IRFL_STR_LEN)
LJFOLDF(fload_str_len_snew)
{
if (LJ_LIKELY(J->flags & JIT_F_OPT_FOLD)) {
PHIBARRIER(fleft);
return fleft->op2;
}
return NEXTFOLD;
}
LJFOLD(FLOAD any IRFL_STR_LEN)
LJFOLDX(lj_opt_cse)
@@ -1216,20 +1253,28 @@ LJFOLDF(fwd_sload)
return J->slot[fins->op1];
}
/* Strings are immutable, so we can safely FOLD/CSE an XLOAD of a string. */
LJFOLD(XLOAD STRREF any)
LJFOLDF(xload_str)
LJFOLD(XLOAD KPTR any)
LJFOLDF(xload_kptr)
{
if (irref_isk(fleft->op1) && irref_isk(fleft->op2)) {
GCstr *str = ir_kstr(IR(fleft->op1));
int32_t ofs = IR(fleft->op2)->i;
lua_assert((MSize)ofs < str->len);
lua_assert((MSize)(ofs + (1<<((fins->op2>>8)&3))) <= str->len);
return INTFOLD(kfold_xload(fins, strdata(str)+ofs));
}
return CSEFOLD;
/* Only fold read-only integer loads for now. */
if ((fins->op2 & IRXLOAD_READONLY) && irt_isinteger(fins->t))
return INTFOLD(kfold_xload(fins, ir_kptr(fleft)));
return NEXTFOLD;
}
/* CSE for XLOAD depends on the type, but not on the IRXLOAD_* flags. */
LJFOLD(XLOAD any any)
LJFOLDF(fwd_xload)
{
IRRef ref = J->chain[IR_XLOAD];
IRRef op1 = fins->op1;
while (ref > op1) {
if (IR(ref)->op1 == op1 && irt_sametype(IR(ref)->t, fins->t))
return ref;
ref = IR(ref)->prev;
}
return EMITFOLD;
}
/* No XLOAD of non-strings (yet), so we don't need a (XLOAD any any) rule. */
/* -- Write barriers ------------------------------------------------------ */
@@ -1279,12 +1324,11 @@ LJFOLD(FSTORE any any)
LJFOLDX(lj_opt_dse_fstore)
LJFOLD(NEWREF any any) /* Treated like a store. */
LJFOLD(CALLS any any)
LJFOLD(CALLL any any) /* Safeguard fallback. */
LJFOLD(TNEW any any)
LJFOLD(TDUP any)
LJFOLDF(store_raw)
{
return EMITFOLD;
}
LJFOLDX(lj_ir_emit)
/* ------------------------------------------------------------------------ */
@@ -1402,6 +1446,19 @@ TRef LJ_FASTCALL lj_opt_cse(jit_State *J)
}
}
/* CSE with explicit search limit. */
TRef LJ_FASTCALL lj_opt_cselim(jit_State *J, IRRef lim)
{
IRRef ref = J->chain[fins->o];
IRRef2 op12 = (IRRef2)fins->op1 + ((IRRef2)fins->op2 << 16);
while (ref > lim) {
if (IR(ref)->op12 == op12)
return ref;
ref = IR(ref)->prev;
}
return lj_ir_emit(J);
}
/* ------------------------------------------------------------------------ */
#undef IR