diff --git a/src/lj_iropt.h b/src/lj_iropt.h index caa420f4..81d522e8 100644 --- a/src/lj_iropt.h +++ b/src/lj_iropt.h @@ -120,6 +120,7 @@ LJ_FUNC TRef LJ_FASTCALL lj_opt_fwd_uload(jit_State *J); LJ_FUNC TRef LJ_FASTCALL lj_opt_fwd_fload(jit_State *J); LJ_FUNC TRef LJ_FASTCALL lj_opt_fwd_xload(jit_State *J); LJ_FUNC TRef LJ_FASTCALL lj_opt_fwd_tab_len(jit_State *J); +LJ_FUNC TRef LJ_FASTCALL lj_opt_fwd_hrefk(jit_State *J); LJ_FUNC int LJ_FASTCALL lj_opt_fwd_href_nokey(jit_State *J); LJ_FUNC int LJ_FASTCALL lj_opt_fwd_tptr(jit_State *J, IRRef lim); LJ_FUNC int lj_opt_fwd_wasnonnil(jit_State *J, IROpT loadop, IRRef xref); diff --git a/src/lj_opt_fold.c b/src/lj_opt_fold.c index 41d1ff8a..5a634bbc 100644 --- a/src/lj_opt_fold.c +++ b/src/lj_opt_fold.c @@ -1846,6 +1846,9 @@ LJFOLDF(cse_uref) return EMITFOLD; } +LJFOLD(HREFK any any) +LJFOLDX(lj_opt_fwd_hrefk) + LJFOLD(HREF TNEW any) LJFOLDF(fwd_href_tnew) { diff --git a/src/lj_opt_mem.c b/src/lj_opt_mem.c index a0bfba19..a7e0d35e 100644 --- a/src/lj_opt_mem.c +++ b/src/lj_opt_mem.c @@ -21,6 +21,7 @@ /* Some local macros to save typing. Undef'd at the end. */ #define IR(ref) (&J->cur.ir[(ref)]) #define fins (&J->fold.ins) +#define fleft (&J->fold.left) #define fright (&J->fold.right) /* @@ -255,6 +256,30 @@ TRef LJ_FASTCALL lj_opt_fwd_hload(jit_State *J) return EMITFOLD; } +/* HREFK forwarding. */ +TRef LJ_FASTCALL lj_opt_fwd_hrefk(jit_State *J) +{ + IRRef tab = fleft->op1; + IRRef ref = J->chain[IR_NEWREF]; + while (ref > tab) { + IRIns *newref = IR(ref); + if (tab == newref->op1) { + if (fright->op1 == newref->op2) + return ref; /* Forward from NEWREF. */ + else + goto docse; + } else if (aa_table(J, tab, newref->op1) != ALIAS_NO) { + goto docse; + } + ref = newref->prev; + } + /* No conflicting NEWREF: key location unchanged for HREFK of TDUP. */ + if (IR(tab)->o == IR_TDUP) + fins->t.irt &= ~IRT_GUARD; /* Drop HREFK guard. */ +docse: + return CSEFOLD; +} + /* Check whether HREF of TNEW/TDUP can be folded to niltv. */ int LJ_FASTCALL lj_opt_fwd_href_nokey(jit_State *J) { @@ -872,6 +897,7 @@ int lj_opt_fwd_wasnonnil(jit_State *J, IROpT loadop, IRRef xref) #undef IR #undef fins +#undef fleft #undef fright #endif