From 3f26e3a89d54dfb761ca02fc89aaf15326f5f514 Mon Sep 17 00:00:00 2001 From: Mike Pall Date: Thu, 10 Mar 2011 01:41:58 +0100 Subject: [PATCH] FFI: Fix and optimize recording of cdata[cdata]. --- src/lj_crecord.c | 15 +++++++++++---- src/lj_opt_fold.c | 30 ++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/src/lj_crecord.c b/src/lj_crecord.c index d689b81b..c93cece3 100644 --- a/src/lj_crecord.c +++ b/src/lj_crecord.c @@ -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; diff --git a/src/lj_opt_fold.c b/src/lj_opt_fold.c index 495b784d..471a4b29 100644 --- a/src/lj_opt_fold.c +++ b/src/lj_opt_fold.c @@ -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)