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 /src | |
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.
Diffstat (limited to 'src')
-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 |