diff options
| author | Mike Pall <mike> | 2010-03-28 06:50:39 +0200 |
|---|---|---|
| committer | Mike Pall <mike> | 2010-03-28 06:53:41 +0200 |
| commit | 1d1d9221f3e665de3fd3ee35d760efe684c59626 (patch) | |
| tree | c8dd00e08e83e6f961858b70ede131d167d85027 | |
| parent | e4bca9545186ffd6b9ee03f711adfa495d55c0fc (diff) | |
| download | luajit-1d1d9221f3e665de3fd3ee35d760efe684c59626.tar.gz luajit-1d1d9221f3e665de3fd3ee35d760efe684c59626.tar.bz2 luajit-1d1d9221f3e665de3fd3ee35d760efe684c59626.zip | |
Fold HREF of TNEW/TDUP to niltv. Fold HLOAD of niltv to nil.
| -rw-r--r-- | src/Makefile.dep | 4 | ||||
| -rw-r--r-- | src/lj_iropt.h | 1 | ||||
| -rw-r--r-- | src/lj_opt_fold.c | 31 | ||||
| -rw-r--r-- | 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 | |||
| 87 | lj_opt_dce.o: lj_opt_dce.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ | 87 | lj_opt_dce.o: lj_opt_dce.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ |
| 88 | lj_ir.h lj_jit.h lj_iropt.h | 88 | lj_ir.h lj_jit.h lj_iropt.h |
| 89 | lj_opt_fold.o: lj_opt_fold.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ | 89 | lj_opt_fold.o: lj_opt_fold.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ |
| 90 | lj_str.h lj_ir.h lj_jit.h lj_iropt.h lj_trace.h lj_dispatch.h lj_bc.h \ | 90 | lj_str.h lj_tab.h lj_ir.h lj_jit.h lj_iropt.h lj_trace.h lj_dispatch.h \ |
| 91 | lj_traceerr.h lj_vm.h lj_folddef.h | 91 | lj_bc.h lj_traceerr.h lj_vm.h lj_folddef.h |
| 92 | lj_opt_loop.o: lj_opt_loop.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ | 92 | lj_opt_loop.o: lj_opt_loop.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ |
| 93 | lj_err.h lj_errmsg.h lj_str.h lj_ir.h lj_jit.h lj_iropt.h lj_trace.h \ | 93 | lj_err.h lj_errmsg.h lj_str.h lj_ir.h lj_jit.h lj_iropt.h lj_trace.h \ |
| 94 | lj_dispatch.h lj_bc.h lj_traceerr.h lj_snap.h lj_vm.h | 94 | 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); | |||
| 110 | LJ_FUNC TRef LJ_FASTCALL lj_opt_fwd_uload(jit_State *J); | 110 | LJ_FUNC TRef LJ_FASTCALL lj_opt_fwd_uload(jit_State *J); |
| 111 | LJ_FUNC TRef LJ_FASTCALL lj_opt_fwd_fload(jit_State *J); | 111 | LJ_FUNC TRef LJ_FASTCALL lj_opt_fwd_fload(jit_State *J); |
| 112 | LJ_FUNC TRef LJ_FASTCALL lj_opt_fwd_tab_len(jit_State *J); | 112 | LJ_FUNC TRef LJ_FASTCALL lj_opt_fwd_tab_len(jit_State *J); |
| 113 | LJ_FUNC int LJ_FASTCALL lj_opt_fwd_href_nokey(jit_State *J); | ||
| 113 | LJ_FUNC int lj_opt_fwd_wasnonnil(jit_State *J, IROpT loadop, IRRef xref); | 114 | LJ_FUNC int lj_opt_fwd_wasnonnil(jit_State *J, IROpT loadop, IRRef xref); |
| 114 | 115 | ||
| 115 | /* Dead-store elimination. */ | 116 | /* 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 @@ | |||
| 13 | #if LJ_HASJIT | 13 | #if LJ_HASJIT |
| 14 | 14 | ||
| 15 | #include "lj_str.h" | 15 | #include "lj_str.h" |
| 16 | #include "lj_tab.h" | ||
| 16 | #include "lj_ir.h" | 17 | #include "lj_ir.h" |
| 17 | #include "lj_jit.h" | 18 | #include "lj_jit.h" |
| 18 | #include "lj_iropt.h" | 19 | #include "lj_iropt.h" |
| @@ -1163,6 +1164,15 @@ LJFOLDF(merge_eqne_snew_kgc) | |||
| 1163 | LJFOLD(ALOAD any) | 1164 | LJFOLD(ALOAD any) |
| 1164 | LJFOLDX(lj_opt_fwd_aload) | 1165 | LJFOLDX(lj_opt_fwd_aload) |
| 1165 | 1166 | ||
| 1167 | /* From HREF fwd (see below). Must eliminate, not supported by fwd/backend. */ | ||
| 1168 | LJFOLD(HLOAD KPTR) | ||
| 1169 | LJFOLDF(kfold_hload_kptr) | ||
| 1170 | { | ||
| 1171 | UNUSED(J); | ||
| 1172 | lua_assert(ir_kptr(fleft) == niltvg(J2G(J))); | ||
| 1173 | return TREF_NIL; | ||
| 1174 | } | ||
| 1175 | |||
| 1166 | LJFOLD(HLOAD any) | 1176 | LJFOLD(HLOAD any) |
| 1167 | LJFOLDX(lj_opt_fwd_hload) | 1177 | LJFOLDX(lj_opt_fwd_hload) |
| 1168 | 1178 | ||
| @@ -1202,6 +1212,27 @@ LJFOLDF(cse_uref) | |||
| 1202 | return EMITFOLD; | 1212 | return EMITFOLD; |
| 1203 | } | 1213 | } |
| 1204 | 1214 | ||
| 1215 | LJFOLD(HREF TNEW any) | ||
| 1216 | LJFOLDF(fwd_href_tnew) | ||
| 1217 | { | ||
| 1218 | if (lj_opt_fwd_href_nokey(J)) | ||
| 1219 | return lj_ir_kptr(J, niltvg(J2G(J))); | ||
| 1220 | return NEXTFOLD; | ||
| 1221 | } | ||
| 1222 | |||
| 1223 | LJFOLD(HREF TDUP KPRI) | ||
| 1224 | LJFOLD(HREF TDUP KGC) | ||
| 1225 | LJFOLD(HREF TDUP KNUM) | ||
| 1226 | LJFOLDF(fwd_href_tdup) | ||
| 1227 | { | ||
| 1228 | TValue keyv; | ||
| 1229 | lj_ir_kvalue(J->L, &keyv, fright); | ||
| 1230 | if (lj_tab_get(J->L, ir_ktab(IR(fleft->op1)), &keyv) == niltvg(J2G(J)) && | ||
| 1231 | lj_opt_fwd_href_nokey(J)) | ||
| 1232 | return lj_ir_kptr(J, niltvg(J2G(J))); | ||
| 1233 | return NEXTFOLD; | ||
| 1234 | } | ||
| 1235 | |||
| 1205 | /* We can safely FOLD/CSE array/hash refs and field loads, since there | 1236 | /* We can safely FOLD/CSE array/hash refs and field loads, since there |
| 1206 | ** are no corresponding stores. But NEWREF may invalidate all of them. | 1237 | ** are no corresponding stores. But NEWREF may invalidate all of them. |
| 1207 | ** Lacking better disambiguation for table references, these optimizations | 1238 | ** 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 @@ | |||
| 21 | /* Some local macros to save typing. Undef'd at the end. */ | 21 | /* Some local macros to save typing. Undef'd at the end. */ |
| 22 | #define IR(ref) (&J->cur.ir[(ref)]) | 22 | #define IR(ref) (&J->cur.ir[(ref)]) |
| 23 | #define fins (&J->fold.ins) | 23 | #define fins (&J->fold.ins) |
| 24 | #define fright (&J->fold.right) | ||
| 24 | 25 | ||
| 25 | /* | 26 | /* |
| 26 | ** Caveat #1: return value is not always a TRef -- only use with tref_ref(). | 27 | ** 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) | |||
| 220 | return EMITFOLD; | 221 | return EMITFOLD; |
| 221 | } | 222 | } |
| 222 | 223 | ||
| 224 | /* Check whether HREF of TNEW/TDUP can be folded to niltv. */ | ||
| 225 | int LJ_FASTCALL lj_opt_fwd_href_nokey(jit_State *J) | ||
| 226 | { | ||
| 227 | IRRef lim = fins->op1; /* Search limit. */ | ||
| 228 | IRRef ref; | ||
| 229 | |||
| 230 | /* The key for an ASTORE may end up in the hash part after a NEWREF. */ | ||
| 231 | if (irt_isnum(fright->t) && J->chain[IR_NEWREF] > lim) { | ||
| 232 | ref = J->chain[IR_ASTORE]; | ||
| 233 | while (ref > lim) { | ||
| 234 | if (ref < J->chain[IR_NEWREF]) | ||
| 235 | return 0; /* Conflict. */ | ||
| 236 | ref = IR(ref)->prev; | ||
| 237 | } | ||
| 238 | } | ||
| 239 | |||
| 240 | /* Search for conflicting stores. */ | ||
| 241 | ref = J->chain[IR_HSTORE]; | ||
| 242 | while (ref > lim) { | ||
| 243 | IRIns *store = IR(ref); | ||
| 244 | if (aa_ahref(J, fins, IR(store->op1)) != ALIAS_NO) | ||
| 245 | return 0; /* Conflict. */ | ||
| 246 | ref = store->prev; | ||
| 247 | } | ||
| 248 | |||
| 249 | return 1; /* No conflict. Can fold to niltv. */ | ||
| 250 | } | ||
| 251 | |||
| 223 | /* ASTORE/HSTORE elimination. */ | 252 | /* ASTORE/HSTORE elimination. */ |
| 224 | TRef LJ_FASTCALL lj_opt_dse_ahstore(jit_State *J) | 253 | TRef LJ_FASTCALL lj_opt_dse_ahstore(jit_State *J) |
| 225 | { | 254 | { |
| @@ -530,5 +559,6 @@ int lj_opt_fwd_wasnonnil(jit_State *J, IROpT loadop, IRRef xref) | |||
| 530 | 559 | ||
| 531 | #undef IR | 560 | #undef IR |
| 532 | #undef fins | 561 | #undef fins |
| 562 | #undef fright | ||
| 533 | 563 | ||
| 534 | #endif | 564 | #endif |
