Introduce lj_ir_ggfload (IR_FLOAD with NIL op1 => load from GG).

This commit is contained in:
Peter Cawley 2016-05-09 22:51:58 +01:00
parent 26cd51981c
commit 5201498a06
7 changed files with 68 additions and 16 deletions

View File

@ -163,7 +163,7 @@ lj_opt_sink.o: lj_opt_sink.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_ir.h lj_jit.h lj_iropt.h lj_target.h lj_target_*.h
lj_opt_split.o: lj_opt_split.c lj_obj.h lua.h luaconf.h lj_def.h \
lj_arch.h lj_err.h lj_errmsg.h lj_buf.h lj_gc.h lj_str.h lj_ir.h \
lj_jit.h lj_ircall.h lj_iropt.h lj_vm.h
lj_jit.h lj_ircall.h lj_iropt.h lj_vm.h lj_dispatch.h lj_bc.h
lj_parse.o: lj_parse.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
lj_gc.h lj_err.h lj_errmsg.h lj_debug.h lj_buf.h lj_str.h lj_tab.h \
lj_func.h lj_state.h lj_bc.h lj_ctype.h lj_strfmt.h lj_lex.h lj_parse.h \

View File

@ -897,17 +897,23 @@ static MIPSIns asm_fxstoreins(IRIns *ir)
static void asm_fload(ASMState *as, IRIns *ir)
{
Reg dest = ra_dest(as, ir, RSET_GPR);
Reg idx = ra_alloc1(as, ir->op1, RSET_GPR);
MIPSIns mi = asm_fxloadins(ir);
Reg idx;
int32_t ofs;
if (ir->op2 == IRFL_TAB_ARRAY) {
ofs = asm_fuseabase(as, ir->op1);
if (ofs) { /* Turn the t->array load into an add for colocated arrays. */
emit_tsi(as, MIPSI_ADDIU, dest, idx, ofs);
return;
if (ir->op1 == REF_NIL) {
idx = RID_JGL;
ofs = ir->op2 - 32768;
} else {
idx = ra_alloc1(as, ir->op1, RSET_GPR);
if (ir->op2 == IRFL_TAB_ARRAY) {
ofs = asm_fuseabase(as, ir->op1);
if (ofs) { /* Turn the t->array load into an add for colocated arrays. */
emit_tsi(as, MIPSI_ADDIU, dest, idx, ofs);
return;
}
}
ofs = field_ofs[ir->op2];
}
ofs = field_ofs[ir->op2];
lua_assert(!irt_isfp(ir->t));
emit_tsi(as, mi, dest, idx, ofs);
}

View File

@ -807,17 +807,23 @@ static PPCIns asm_fxstoreins(IRIns *ir)
static void asm_fload(ASMState *as, IRIns *ir)
{
Reg dest = ra_dest(as, ir, RSET_GPR);
Reg idx = ra_alloc1(as, ir->op1, RSET_GPR);
PPCIns pi = asm_fxloadins(ir);
Reg idx;
int32_t ofs;
if (ir->op2 == IRFL_TAB_ARRAY) {
ofs = asm_fuseabase(as, ir->op1);
if (ofs) { /* Turn the t->array load into an add for colocated arrays. */
emit_tai(as, PPCI_ADDI, dest, idx, ofs);
return;
if (ir->op1 == REF_NIL) {
idx = RID_JGL;
ofs = ir->op2 - 32768;
} else {
idx = ra_alloc1(as, ir->op1, RSET_GPR);
if (ir->op2 == IRFL_TAB_ARRAY) {
ofs = asm_fuseabase(as, ir->op1);
if (ofs) { /* Turn the t->array load into an add for colocated arrays. */
emit_tai(as, PPCI_ADDI, dest, idx, ofs);
return;
}
}
ofs = field_ofs[ir->op2];
}
ofs = field_ofs[ir->op2];
lua_assert(!irt_isi8(ir->t));
emit_tai(as, pi, dest, idx, ofs);
}

View File

@ -205,8 +205,13 @@ static void asm_fuseahuref(ASMState *as, IRRef ref, RegSet allow)
static void asm_fusefref(ASMState *as, IRIns *ir, RegSet allow)
{
lua_assert(ir->o == IR_FLOAD || ir->o == IR_FREF);
as->mrm.ofs = field_ofs[ir->op2];
as->mrm.idx = RID_NONE;
if (ir->op1 == REF_NIL) {
as->mrm.ofs = (int32_t)ir->op2 + ptr2addr(J2GG(as->J));
as->mrm.base = RID_NONE;
return;
}
as->mrm.ofs = field_ofs[ir->op2];
if (irref_isk(ir->op1)) {
as->mrm.ofs += IR(ir->op1)->i;
as->mrm.base = RID_NONE;
@ -369,6 +374,10 @@ static Reg asm_fuseload(ASMState *as, IRRef ref, RegSet allow)
return RID_MRM;
}
}
if (ir->o == IR_FLOAD && ir->op1 == REF_NIL) {
asm_fusefref(as, ir, RSET_EMPTY);
return RID_MRM;
}
if (!(as->freeset & allow) && !irref_isk(ref) &&
(allow == RSET_EMPTY || ra_hasspill(ir->s) || iscrossref(as, ref)))
goto fusespill;

View File

@ -514,6 +514,30 @@ void lj_ir_rollback(jit_State *J, IRRef ref)
J->cur.nins = nins;
}
/* Load field of type t from GG+ofs */
LJ_FUNC TRef lj_ir_ggfload(jit_State *J, IRType t, uintptr_t ofs)
{
IRIns *ir, *cir = J->cur.ir;
IRRef2 op12 = IRREF2((IRRef1)REF_NIL, (IRRef1)ofs);
IRRef ref;
lua_assert(ofs >= IRFL__MAX && ofs == (IRRef1)ofs);
for (ref = J->chain[IR_FLOAD]; ref; ref = cir[ref].prev) {
if (cir[ref].op12 == op12) {
lua_assert(cir[ref].t.irt == t);
goto found;
}
}
ref = lj_ir_nextins(J);
ir = IR(ref);
ir->op12 = op12;
ir->t.irt = t;
ir->o = IR_FLOAD;
ir->prev = J->chain[IR_FLOAD];
J->chain[IR_FLOAD] = (IRRef1)ref;
found:
return TREF(ref, t);
}
#undef IR
#undef fins
#undef emitir

View File

@ -90,6 +90,7 @@ LJ_FUNC TRef LJ_FASTCALL lj_ir_tostr(jit_State *J, TRef tr);
LJ_FUNC int lj_ir_numcmp(lua_Number a, lua_Number b, IROp op);
LJ_FUNC int lj_ir_strcmp(GCstr *a, GCstr *b, IROp op);
LJ_FUNC void lj_ir_rollback(jit_State *J, IRRef ref);
LJ_FUNC TRef lj_ir_ggfload(jit_State *J, IRType t, uintptr_t ofs);
/* Emit IR instructions with on-the-fly optimizations. */
LJ_FUNC TRef LJ_FASTCALL lj_opt_fold(jit_State *J);

View File

@ -12,6 +12,7 @@
#include "lj_err.h"
#include "lj_buf.h"
#include "lj_dispatch.h"
#include "lj_ir.h"
#include "lj_jit.h"
#include "lj_ircall.h"
@ -448,6 +449,11 @@ static void split_ir(jit_State *J)
case IR_STRTO:
hi = split_emit(J, IRT(IR_HIOP, IRT_SOFTFP), nref, nref);
break;
case IR_FLOAD:
lua_assert(ir->op1 == REF_NIL);
hi = lj_ir_kint(J, *(int32_t*)((char*)J2GG(J) + ir->op2 + LJ_LE*4));
nir->op2 += LJ_BE*4;
break;
case IR_XLOAD: {
IRIns inslo = *nir; /* Save/undo the emit of the lo XLOAD. */
J->cur.nins--;