FFI: Fix and optimize recording of cdata[cdata].

This commit is contained in:
Mike Pall 2011-03-10 01:41:58 +01:00
parent 1c9981ae4c
commit 3f26e3a89d
2 changed files with 41 additions and 4 deletions

View File

@ -503,10 +503,17 @@ void LJ_FASTCALL recff_cdata_index(jit_State *J, RecordFFData *rd)
IRType t;
if (ctype_isenum(ctk->info)) ctk = ctype_child(cts, ctk);
if (ctype_isinteger(ctk->info) && (t = crec_ct2irt(ctk)) != IRT_CDATA) {
idx = emitir(IRT(IR_ADD, IRT_PTR), idx, lj_ir_kintp(J, sizeof(GCcdata)));
idx = emitir(IRT(IR_XLOAD, t), idx, 0);
if (!LJ_64 && (t == IRT_I64 || t == IRT_U64)) {
idx = emitconv(idx, IRT_INT, t, 0);
if (ctk->size == 8) {
idx = emitir(IRT(IR_FLOAD, t), idx, IRFL_CDATA_INT64);
} else {
idx = emitir(IRT(IR_ADD, IRT_PTR), idx,
lj_ir_kintp(J, sizeof(GCcdata)));
idx = emitir(IRT(IR_XLOAD, t), idx, 0);
}
if (LJ_64 && ctk->size < sizeof(intptr_t) && !(ctk->info & CTF_UNSIGNED))
idx = emitconv(idx, IRT_INTP, IRT_INT, IRCONV_SEXT);
if (!LJ_64 && ctk->size > sizeof(intptr_t)) {
idx = emitconv(idx, IRT_INTP, t, 0);
lj_needsplit(J);
}
goto integer_key;

View File

@ -897,6 +897,16 @@ LJFOLDF(simplify_conv_i64_num)
return NEXTFOLD;
}
LJFOLD(CONV CONV IRCONV_INT_I64) /* _INT */
LJFOLD(CONV CONV IRCONV_INT_U64) /* _INT */
LJFOLDF(simplify_conv_int_i64)
{
PHIBARRIER(fleft);
if ((fleft->op2 & IRCONV_SRCMASK) == IRT_INT)
return fleft->op1;
return NEXTFOLD;
}
/* Shortcut TOBIT + IRT_NUM <- IRT_INT/IRT_U32 conversion. */
LJFOLD(TOBIT CONV KNUM)
LJFOLDF(simplify_tobit_conv)
@ -956,6 +966,26 @@ LJFOLDF(simplify_conv_sext)
return NEXTFOLD;
}
/* Strength reduction of narrowing. */
LJFOLD(CONV ADD IRCONV_INT_I64)
LJFOLD(CONV SUB IRCONV_INT_I64)
LJFOLD(CONV MUL IRCONV_INT_I64)
LJFOLD(CONV ADD IRCONV_INT_U64)
LJFOLD(CONV SUB IRCONV_INT_U64)
LJFOLD(CONV MUL IRCONV_INT_U64)
LJFOLDF(simplify_conv_narrow)
{
IROp op = (IROp)fleft->o;
IRRef op1 = fleft->op1, op2 = fleft->op2, mode = fins->op2;
PHIBARRIER(fleft);
op1 = emitir(IRTI(IR_CONV), op1, mode);
op2 = emitir(IRTI(IR_CONV), op2, mode);
fins->ot = IRTI(op);
fins->op1 = op1;
fins->op2 = op2;
return RETRYFOLD;
}
/* Special CSE rule for CONV. */
LJFOLD(CONV any any)
LJFOLDF(cse_conv)