From 1d1d9221f3e665de3fd3ee35d760efe684c59626 Mon Sep 17 00:00:00 2001 From: Mike Pall Date: Sun, 28 Mar 2010 06:50:39 +0200 Subject: [PATCH] Fold HREF of TNEW/TDUP to niltv. Fold HLOAD of niltv to nil. --- src/Makefile.dep | 4 ++-- src/lj_iropt.h | 1 + src/lj_opt_fold.c | 31 +++++++++++++++++++++++++++++++ src/lj_opt_mem.c | 30 ++++++++++++++++++++++++++++++ 4 files changed, 64 insertions(+), 2 deletions(-) diff --git a/src/Makefile.dep b/src/Makefile.dep index 3646349c..aeeeeff5 100644 --- a/src/Makefile.dep +++ b/src/Makefile.dep @@ -87,8 +87,8 @@ lj_obj.o: lj_obj.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_opt_dce.o: lj_opt_dce.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ lj_ir.h lj_jit.h lj_iropt.h lj_opt_fold.o: lj_opt_fold.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ - lj_str.h lj_ir.h lj_jit.h lj_iropt.h lj_trace.h lj_dispatch.h lj_bc.h \ - lj_traceerr.h lj_vm.h lj_folddef.h + lj_str.h lj_tab.h lj_ir.h lj_jit.h lj_iropt.h lj_trace.h lj_dispatch.h \ + lj_bc.h lj_traceerr.h lj_vm.h lj_folddef.h lj_opt_loop.o: lj_opt_loop.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ lj_err.h lj_errmsg.h lj_str.h lj_ir.h lj_jit.h lj_iropt.h lj_trace.h \ lj_dispatch.h lj_bc.h lj_traceerr.h lj_snap.h lj_vm.h diff --git a/src/lj_iropt.h b/src/lj_iropt.h index 1884892a..ee593b40 100644 --- a/src/lj_iropt.h +++ b/src/lj_iropt.h @@ -110,6 +110,7 @@ LJ_FUNC TRef LJ_FASTCALL lj_opt_fwd_hload(jit_State *J); 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_tab_len(jit_State *J); +LJ_FUNC int LJ_FASTCALL lj_opt_fwd_href_nokey(jit_State *J); LJ_FUNC int lj_opt_fwd_wasnonnil(jit_State *J, IROpT loadop, IRRef xref); /* Dead-store elimination. */ diff --git a/src/lj_opt_fold.c b/src/lj_opt_fold.c index 5eeffae3..c91f3382 100644 --- a/src/lj_opt_fold.c +++ b/src/lj_opt_fold.c @@ -13,6 +13,7 @@ #if LJ_HASJIT #include "lj_str.h" +#include "lj_tab.h" #include "lj_ir.h" #include "lj_jit.h" #include "lj_iropt.h" @@ -1163,6 +1164,15 @@ LJFOLDF(merge_eqne_snew_kgc) LJFOLD(ALOAD any) LJFOLDX(lj_opt_fwd_aload) +/* From HREF fwd (see below). Must eliminate, not supported by fwd/backend. */ +LJFOLD(HLOAD KPTR) +LJFOLDF(kfold_hload_kptr) +{ + UNUSED(J); + lua_assert(ir_kptr(fleft) == niltvg(J2G(J))); + return TREF_NIL; +} + LJFOLD(HLOAD any) LJFOLDX(lj_opt_fwd_hload) @@ -1202,6 +1212,27 @@ LJFOLDF(cse_uref) return EMITFOLD; } +LJFOLD(HREF TNEW any) +LJFOLDF(fwd_href_tnew) +{ + if (lj_opt_fwd_href_nokey(J)) + return lj_ir_kptr(J, niltvg(J2G(J))); + return NEXTFOLD; +} + +LJFOLD(HREF TDUP KPRI) +LJFOLD(HREF TDUP KGC) +LJFOLD(HREF TDUP KNUM) +LJFOLDF(fwd_href_tdup) +{ + TValue keyv; + lj_ir_kvalue(J->L, &keyv, fright); + if (lj_tab_get(J->L, ir_ktab(IR(fleft->op1)), &keyv) == niltvg(J2G(J)) && + lj_opt_fwd_href_nokey(J)) + return lj_ir_kptr(J, niltvg(J2G(J))); + return NEXTFOLD; +} + /* We can safely FOLD/CSE array/hash refs and field loads, since there ** are no corresponding stores. But NEWREF may invalidate all of them. ** Lacking better disambiguation for table references, these optimizations diff --git a/src/lj_opt_mem.c b/src/lj_opt_mem.c index 57948311..042d6081 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 fright (&J->fold.right) /* ** Caveat #1: return value is not always a TRef -- only use with tref_ref(). @@ -220,6 +221,34 @@ TRef LJ_FASTCALL lj_opt_fwd_hload(jit_State *J) return EMITFOLD; } +/* Check whether HREF of TNEW/TDUP can be folded to niltv. */ +int LJ_FASTCALL lj_opt_fwd_href_nokey(jit_State *J) +{ + IRRef lim = fins->op1; /* Search limit. */ + IRRef ref; + + /* The key for an ASTORE may end up in the hash part after a NEWREF. */ + if (irt_isnum(fright->t) && J->chain[IR_NEWREF] > lim) { + ref = J->chain[IR_ASTORE]; + while (ref > lim) { + if (ref < J->chain[IR_NEWREF]) + return 0; /* Conflict. */ + ref = IR(ref)->prev; + } + } + + /* Search for conflicting stores. */ + ref = J->chain[IR_HSTORE]; + while (ref > lim) { + IRIns *store = IR(ref); + if (aa_ahref(J, fins, IR(store->op1)) != ALIAS_NO) + return 0; /* Conflict. */ + ref = store->prev; + } + + return 1; /* No conflict. Can fold to niltv. */ +} + /* ASTORE/HSTORE elimination. */ TRef LJ_FASTCALL lj_opt_dse_ahstore(jit_State *J) { @@ -530,5 +559,6 @@ int lj_opt_fwd_wasnonnil(jit_State *J, IROpT loadop, IRRef xref) #undef IR #undef fins +#undef fright #endif