diff options
| author | Mike Pall <mike> | 2016-05-21 00:30:36 +0200 |
|---|---|---|
| committer | Mike Pall <mike> | 2016-05-21 01:00:49 +0200 |
| commit | 786dbb2ebdde16eadd7464cd5cbeb5d95a5e46f0 (patch) | |
| tree | 8b66463365b467be31250334ea434a2f572b3c5d | |
| parent | cfa188f1349ba4c843394b53f270cb64635b9805 (diff) | |
| download | luajit-786dbb2ebdde16eadd7464cd5cbeb5d95a5e46f0.tar.gz luajit-786dbb2ebdde16eadd7464cd5cbeb5d95a5e46f0.tar.bz2 luajit-786dbb2ebdde16eadd7464cd5cbeb5d95a5e46f0.zip | |
Add IR_FLOAD with REF_NIL for field loads from GG_State.
Contributed by Peter Cawley.
| -rw-r--r-- | src/Makefile.dep | 4 | ||||
| -rw-r--r-- | src/lj_asm_arm.h | 32 | ||||
| -rw-r--r-- | src/lj_asm_mips.h | 20 | ||||
| -rw-r--r-- | src/lj_asm_ppc.h | 20 | ||||
| -rw-r--r-- | src/lj_asm_x86.h | 11 | ||||
| -rw-r--r-- | src/lj_ir.c | 8 | ||||
| -rw-r--r-- | src/lj_iropt.h | 2 | ||||
| -rw-r--r-- | src/lj_opt_split.c | 6 |
8 files changed, 72 insertions, 31 deletions
diff --git a/src/Makefile.dep b/src/Makefile.dep index 76b29108..1df1ce6c 100644 --- a/src/Makefile.dep +++ b/src/Makefile.dep | |||
| @@ -162,8 +162,8 @@ lj_opt_narrow.o: lj_opt_narrow.c lj_obj.h lua.h luaconf.h lj_def.h \ | |||
| 162 | lj_opt_sink.o: lj_opt_sink.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ | 162 | lj_opt_sink.o: lj_opt_sink.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ |
| 163 | lj_ir.h lj_jit.h lj_iropt.h lj_target.h lj_target_*.h | 163 | lj_ir.h lj_jit.h lj_iropt.h lj_target.h lj_target_*.h |
| 164 | lj_opt_split.o: lj_opt_split.c lj_obj.h lua.h luaconf.h lj_def.h \ | 164 | lj_opt_split.o: lj_opt_split.c lj_obj.h lua.h luaconf.h lj_def.h \ |
| 165 | lj_arch.h lj_err.h lj_errmsg.h lj_buf.h lj_gc.h lj_str.h lj_ir.h \ | 165 | lj_arch.h lj_err.h lj_errmsg.h lj_buf.h lj_gc.h lj_str.h lj_dispatch.h \ |
| 166 | lj_jit.h lj_ircall.h lj_iropt.h lj_vm.h | 166 | lj_bc.h lj_jit.h lj_ir.h lj_ircall.h lj_iropt.h lj_vm.h |
| 167 | lj_parse.o: lj_parse.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ | 167 | lj_parse.o: lj_parse.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ |
| 168 | lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_buf.h lj_str.h lj_tab.h \ | 168 | lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_buf.h lj_str.h lj_tab.h \ |
| 169 | lj_func.h lj_state.h lj_bc.h lj_ctype.h lj_strfmt.h lj_lex.h lj_parse.h \ | 169 | lj_func.h lj_state.h lj_bc.h lj_ctype.h lj_strfmt.h lj_lex.h lj_parse.h \ |
diff --git a/src/lj_asm_arm.h b/src/lj_asm_arm.h index c64d59e7..23f42919 100644 --- a/src/lj_asm_arm.h +++ b/src/lj_asm_arm.h | |||
| @@ -997,22 +997,26 @@ static ARMIns asm_fxstoreins(IRIns *ir) | |||
| 997 | 997 | ||
| 998 | static void asm_fload(ASMState *as, IRIns *ir) | 998 | static void asm_fload(ASMState *as, IRIns *ir) |
| 999 | { | 999 | { |
| 1000 | Reg dest = ra_dest(as, ir, RSET_GPR); | 1000 | if (ir->op1 == REF_NIL) { |
| 1001 | Reg idx = ra_alloc1(as, ir->op1, RSET_GPR); | 1001 | lua_assert(!ra_used(ir)); /* We can end up here if DCE is turned off. */ |
| 1002 | ARMIns ai = asm_fxloadins(ir); | 1002 | } else { |
| 1003 | int32_t ofs; | 1003 | Reg dest = ra_dest(as, ir, RSET_GPR); |
| 1004 | if (ir->op2 == IRFL_TAB_ARRAY) { | 1004 | Reg idx = ra_alloc1(as, ir->op1, RSET_GPR); |
| 1005 | ofs = asm_fuseabase(as, ir->op1); | 1005 | ARMIns ai = asm_fxloadins(ir); |
| 1006 | if (ofs) { /* Turn the t->array load into an add for colocated arrays. */ | 1006 | int32_t ofs; |
| 1007 | emit_dn(as, ARMI_ADD|ARMI_K12|ofs, dest, idx); | 1007 | if (ir->op2 == IRFL_TAB_ARRAY) { |
| 1008 | return; | 1008 | ofs = asm_fuseabase(as, ir->op1); |
| 1009 | if (ofs) { /* Turn the t->array load into an add for colocated arrays. */ | ||
| 1010 | emit_dn(as, ARMI_ADD|ARMI_K12|ofs, dest, idx); | ||
| 1011 | return; | ||
| 1012 | } | ||
| 1009 | } | 1013 | } |
| 1014 | ofs = field_ofs[ir->op2]; | ||
| 1015 | if ((ai & 0x04000000)) | ||
| 1016 | emit_lso(as, ai, dest, idx, ofs); | ||
| 1017 | else | ||
| 1018 | emit_lsox(as, ai, dest, idx, ofs); | ||
| 1010 | } | 1019 | } |
| 1011 | ofs = field_ofs[ir->op2]; | ||
| 1012 | if ((ai & 0x04000000)) | ||
| 1013 | emit_lso(as, ai, dest, idx, ofs); | ||
| 1014 | else | ||
| 1015 | emit_lsox(as, ai, dest, idx, ofs); | ||
| 1016 | } | 1020 | } |
| 1017 | 1021 | ||
| 1018 | static void asm_fstore(ASMState *as, IRIns *ir) | 1022 | static void asm_fstore(ASMState *as, IRIns *ir) |
diff --git a/src/lj_asm_mips.h b/src/lj_asm_mips.h index d37bc132..6094be68 100644 --- a/src/lj_asm_mips.h +++ b/src/lj_asm_mips.h | |||
| @@ -896,17 +896,23 @@ static MIPSIns asm_fxstoreins(IRIns *ir) | |||
| 896 | static void asm_fload(ASMState *as, IRIns *ir) | 896 | static void asm_fload(ASMState *as, IRIns *ir) |
| 897 | { | 897 | { |
| 898 | Reg dest = ra_dest(as, ir, RSET_GPR); | 898 | Reg dest = ra_dest(as, ir, RSET_GPR); |
| 899 | Reg idx = ra_alloc1(as, ir->op1, RSET_GPR); | ||
| 900 | MIPSIns mi = asm_fxloadins(ir); | 899 | MIPSIns mi = asm_fxloadins(ir); |
| 900 | Reg idx; | ||
| 901 | int32_t ofs; | 901 | int32_t ofs; |
| 902 | if (ir->op2 == IRFL_TAB_ARRAY) { | 902 | if (ir->op1 == REF_NIL) { |
| 903 | ofs = asm_fuseabase(as, ir->op1); | 903 | idx = RID_JGL; |
| 904 | if (ofs) { /* Turn the t->array load into an add for colocated arrays. */ | 904 | ofs = ir->op2 - 32768; |
| 905 | emit_tsi(as, MIPSI_ADDIU, dest, idx, ofs); | 905 | } else { |
| 906 | return; | 906 | idx = ra_alloc1(as, ir->op1, RSET_GPR); |
| 907 | if (ir->op2 == IRFL_TAB_ARRAY) { | ||
| 908 | ofs = asm_fuseabase(as, ir->op1); | ||
| 909 | if (ofs) { /* Turn the t->array load into an add for colocated arrays. */ | ||
| 910 | emit_tsi(as, MIPSI_ADDIU, dest, idx, ofs); | ||
| 911 | return; | ||
| 912 | } | ||
| 907 | } | 913 | } |
| 914 | ofs = field_ofs[ir->op2]; | ||
| 908 | } | 915 | } |
| 909 | ofs = field_ofs[ir->op2]; | ||
| 910 | lua_assert(!irt_isfp(ir->t)); | 916 | lua_assert(!irt_isfp(ir->t)); |
| 911 | emit_tsi(as, mi, dest, idx, ofs); | 917 | emit_tsi(as, mi, dest, idx, ofs); |
| 912 | } | 918 | } |
diff --git a/src/lj_asm_ppc.h b/src/lj_asm_ppc.h index e270b36c..46821515 100644 --- a/src/lj_asm_ppc.h +++ b/src/lj_asm_ppc.h | |||
| @@ -804,17 +804,23 @@ static PPCIns asm_fxstoreins(IRIns *ir) | |||
| 804 | static void asm_fload(ASMState *as, IRIns *ir) | 804 | static void asm_fload(ASMState *as, IRIns *ir) |
| 805 | { | 805 | { |
| 806 | Reg dest = ra_dest(as, ir, RSET_GPR); | 806 | Reg dest = ra_dest(as, ir, RSET_GPR); |
| 807 | Reg idx = ra_alloc1(as, ir->op1, RSET_GPR); | ||
| 808 | PPCIns pi = asm_fxloadins(ir); | 807 | PPCIns pi = asm_fxloadins(ir); |
| 808 | Reg idx; | ||
| 809 | int32_t ofs; | 809 | int32_t ofs; |
| 810 | if (ir->op2 == IRFL_TAB_ARRAY) { | 810 | if (ir->op1 == REF_NIL) { |
| 811 | ofs = asm_fuseabase(as, ir->op1); | 811 | idx = RID_JGL; |
| 812 | if (ofs) { /* Turn the t->array load into an add for colocated arrays. */ | 812 | ofs = ir->op2 - 32768; |
| 813 | emit_tai(as, PPCI_ADDI, dest, idx, ofs); | 813 | } else { |
| 814 | return; | 814 | idx = ra_alloc1(as, ir->op1, RSET_GPR); |
| 815 | if (ir->op2 == IRFL_TAB_ARRAY) { | ||
| 816 | ofs = asm_fuseabase(as, ir->op1); | ||
| 817 | if (ofs) { /* Turn the t->array load into an add for colocated arrays. */ | ||
| 818 | emit_tai(as, PPCI_ADDI, dest, idx, ofs); | ||
| 819 | return; | ||
| 820 | } | ||
| 815 | } | 821 | } |
| 822 | ofs = field_ofs[ir->op2]; | ||
| 816 | } | 823 | } |
| 817 | ofs = field_ofs[ir->op2]; | ||
| 818 | lua_assert(!irt_isi8(ir->t)); | 824 | lua_assert(!irt_isi8(ir->t)); |
| 819 | emit_tai(as, pi, dest, idx, ofs); | 825 | emit_tai(as, pi, dest, idx, ofs); |
| 820 | } | 826 | } |
diff --git a/src/lj_asm_x86.h b/src/lj_asm_x86.h index e3ed7554..69d1256e 100644 --- a/src/lj_asm_x86.h +++ b/src/lj_asm_x86.h | |||
| @@ -205,8 +205,13 @@ static void asm_fuseahuref(ASMState *as, IRRef ref, RegSet allow) | |||
| 205 | static void asm_fusefref(ASMState *as, IRIns *ir, RegSet allow) | 205 | static void asm_fusefref(ASMState *as, IRIns *ir, RegSet allow) |
| 206 | { | 206 | { |
| 207 | lua_assert(ir->o == IR_FLOAD || ir->o == IR_FREF); | 207 | lua_assert(ir->o == IR_FLOAD || ir->o == IR_FREF); |
| 208 | as->mrm.ofs = field_ofs[ir->op2]; | ||
| 209 | as->mrm.idx = RID_NONE; | 208 | as->mrm.idx = RID_NONE; |
| 209 | if (ir->op1 == REF_NIL) { | ||
| 210 | as->mrm.ofs = (int32_t)ir->op2 + ptr2addr(J2GG(as->J)); | ||
| 211 | as->mrm.base = RID_NONE; | ||
| 212 | return; | ||
| 213 | } | ||
| 214 | as->mrm.ofs = field_ofs[ir->op2]; | ||
| 210 | if (irref_isk(ir->op1)) { | 215 | if (irref_isk(ir->op1)) { |
| 211 | as->mrm.ofs += IR(ir->op1)->i; | 216 | as->mrm.ofs += IR(ir->op1)->i; |
| 212 | as->mrm.base = RID_NONE; | 217 | as->mrm.base = RID_NONE; |
| @@ -369,6 +374,10 @@ static Reg asm_fuseload(ASMState *as, IRRef ref, RegSet allow) | |||
| 369 | return RID_MRM; | 374 | return RID_MRM; |
| 370 | } | 375 | } |
| 371 | } | 376 | } |
| 377 | if (ir->o == IR_FLOAD && ir->op1 == REF_NIL) { | ||
| 378 | asm_fusefref(as, ir, RSET_EMPTY); | ||
| 379 | return RID_MRM; | ||
| 380 | } | ||
| 372 | if (!(as->freeset & allow) && !irref_isk(ref) && | 381 | if (!(as->freeset & allow) && !irref_isk(ref) && |
| 373 | (allow == RSET_EMPTY || ra_hasspill(ir->s) || iscrossref(as, ref))) | 382 | (allow == RSET_EMPTY || ra_hasspill(ir->s) || iscrossref(as, ref))) |
| 374 | goto fusespill; | 383 | goto fusespill; |
diff --git a/src/lj_ir.c b/src/lj_ir.c index 6a1ecc13..593b4127 100644 --- a/src/lj_ir.c +++ b/src/lj_ir.c | |||
| @@ -145,6 +145,14 @@ TRef lj_ir_call(jit_State *J, IRCallID id, ...) | |||
| 145 | return emitir(CCI_OPTYPE(ci), tr, id); | 145 | return emitir(CCI_OPTYPE(ci), tr, id); |
| 146 | } | 146 | } |
| 147 | 147 | ||
| 148 | /* Load field of type t from GG_State + offset. */ | ||
| 149 | LJ_FUNC TRef lj_ir_ggfload(jit_State *J, IRType t, uintptr_t ofs) | ||
| 150 | { | ||
| 151 | lua_assert(ofs >= IRFL__MAX && ofs < REF_BIAS); | ||
| 152 | lj_ir_set(J, IRT(IR_FLOAD, t), REF_NIL, ofs); | ||
| 153 | return lj_opt_fold(J); | ||
| 154 | } | ||
| 155 | |||
| 148 | /* -- Interning of constants ---------------------------------------------- */ | 156 | /* -- Interning of constants ---------------------------------------------- */ |
| 149 | 157 | ||
| 150 | /* | 158 | /* |
diff --git a/src/lj_iropt.h b/src/lj_iropt.h index 67221c6f..3e758b2e 100644 --- a/src/lj_iropt.h +++ b/src/lj_iropt.h | |||
| @@ -36,6 +36,8 @@ static LJ_AINLINE IRRef lj_ir_nextins(jit_State *J) | |||
| 36 | return ref; | 36 | return ref; |
| 37 | } | 37 | } |
| 38 | 38 | ||
| 39 | LJ_FUNC TRef lj_ir_ggfload(jit_State *J, IRType t, uintptr_t ofs); | ||
| 40 | |||
| 39 | /* Interning of constants. */ | 41 | /* Interning of constants. */ |
| 40 | LJ_FUNC TRef LJ_FASTCALL lj_ir_kint(jit_State *J, int32_t k); | 42 | LJ_FUNC TRef LJ_FASTCALL lj_ir_kint(jit_State *J, int32_t k); |
| 41 | LJ_FUNC void lj_ir_k64_freeall(jit_State *J); | 43 | LJ_FUNC void lj_ir_k64_freeall(jit_State *J); |
diff --git a/src/lj_opt_split.c b/src/lj_opt_split.c index 6def4161..49c9ae47 100644 --- a/src/lj_opt_split.c +++ b/src/lj_opt_split.c | |||
| @@ -12,6 +12,7 @@ | |||
| 12 | 12 | ||
| 13 | #include "lj_err.h" | 13 | #include "lj_err.h" |
| 14 | #include "lj_buf.h" | 14 | #include "lj_buf.h" |
| 15 | #include "lj_dispatch.h" | ||
| 15 | #include "lj_ir.h" | 16 | #include "lj_ir.h" |
| 16 | #include "lj_jit.h" | 17 | #include "lj_jit.h" |
| 17 | #include "lj_ircall.h" | 18 | #include "lj_ircall.h" |
| @@ -448,6 +449,11 @@ static void split_ir(jit_State *J) | |||
| 448 | case IR_STRTO: | 449 | case IR_STRTO: |
| 449 | hi = split_emit(J, IRT(IR_HIOP, IRT_SOFTFP), nref, nref); | 450 | hi = split_emit(J, IRT(IR_HIOP, IRT_SOFTFP), nref, nref); |
| 450 | break; | 451 | break; |
| 452 | case IR_FLOAD: | ||
| 453 | lua_assert(ir->op1 == REF_NIL); | ||
| 454 | hi = lj_ir_kint(J, *(int32_t*)((char*)J2GG(J) + ir->op2 + LJ_LE*4)); | ||
| 455 | nir->op2 += LJ_BE*4; | ||
| 456 | break; | ||
| 451 | case IR_XLOAD: { | 457 | case IR_XLOAD: { |
| 452 | IRIns inslo = *nir; /* Save/undo the emit of the lo XLOAD. */ | 458 | IRIns inslo = *nir; /* Save/undo the emit of the lo XLOAD. */ |
| 453 | J->cur.nins--; | 459 | J->cur.nins--; |
