From b2c74c52cc9e850d53f2f7b06ffe2b096884f77a Mon Sep 17 00:00:00 2001 From: Mike Pall Date: Sun, 2 Jan 2011 22:21:10 +0100 Subject: [PATCH] FFI: Add support for cdata constants to IR. --- src/lj_opt_fold.c | 65 +++++++++++++++++++++++++++++++++++++---------- src/lj_record.c | 5 ++++ 2 files changed, 57 insertions(+), 13 deletions(-) diff --git a/src/lj_opt_fold.c b/src/lj_opt_fold.c index e05d6b7b..04dd713d 100644 --- a/src/lj_opt_fold.c +++ b/src/lj_opt_fold.c @@ -439,6 +439,34 @@ LJFOLDF(kfold_strcmp) return NEXTFOLD; } +/* -- Constant folding of pointer arithmetic ------------------------------ */ + +LJFOLD(ADD KGC KINT) +LJFOLD(ADD KGC KINT64) +LJFOLDF(kfold_add_kgc) +{ + GCobj *o = ir_kgc(fleft); +#if LJ_64 + ptrdiff_t ofs = (ptrdiff_t)ir_kint64(fright)->u64; +#else + ptrdiff_t ofs = fright->i; +#endif + return lj_ir_kptr(J, (char *)o + ofs); +} + +LJFOLD(ADD KPTR KINT) +LJFOLD(ADD KPTR KINT64) +LJFOLDF(kfold_add_kptr) +{ + void *p = ir_kptr(fleft); +#if LJ_64 + ptrdiff_t ofs = (ptrdiff_t)ir_kint64(fright)->u64; +#else + ptrdiff_t ofs = fright->i; +#endif + return lj_ir_kptr(J, (char *)p + ofs); +} + /* -- Constant folding of conversions ------------------------------------- */ LJFOLD(TOBIT KNUM KNUM) @@ -1462,18 +1490,23 @@ LJFOLDF(comm_bxor) /* -- Simplification of compound expressions ------------------------------ */ -static int32_t kfold_xload(IRIns *ir, const void *p) +static TRef kfold_xload(jit_State *J, IRIns *ir, const void *p) { + int32_t k; #if !LJ_TARGET_X86ORX64 #error "Missing support for unaligned loads" #endif switch (irt_type(ir->t)) { - case IRT_I8: return (int32_t)*(int8_t *)p; - case IRT_U8: return (int32_t)*(uint8_t *)p; - case IRT_I16: return (int32_t)*(int16_t *)p; - case IRT_U16: return (int32_t)*(uint16_t *)p; - default: lua_assert(irt_isint(ir->t)); return (int32_t)*(int32_t *)p; + case IRT_NUM: return lj_ir_knum_u64(J, *(uint64_t *)p); + case IRT_I8: k = (int32_t)*(int8_t *)p; break; + case IRT_U8: k = (int32_t)*(uint8_t *)p; break; + case IRT_I16: k = (int32_t)*(int16_t *)p; break; + case IRT_U16: k = (int32_t)*(uint16_t *)p; break; + case IRT_INT: case IRT_U32: k = *(int32_t *)p; break; + case IRT_I64: case IRT_U64: return lj_ir_kint64(J, *(uint64_t *)p); + default: return 0; } + return lj_ir_kint(J, k); } /* Turn: string.sub(str, a, b) == kstr @@ -1508,7 +1541,7 @@ LJFOLDF(merge_eqne_snew_kgc) IRTI(IR_XLOAD)); TRef tmp = emitir(ot, strref, IRXLOAD_READONLY | (len > 1 ? IRXLOAD_UNALIGNED : 0)); - TRef val = lj_ir_kint(J, kfold_xload(IR(tref_ref(tmp)), strdata(kstr))); + TRef val = kfold_xload(J, IR(tref_ref(tmp)), strdata(kstr)); if (len == 3) tmp = emitir(IRTI(IR_BAND), tmp, lj_ir_kint(J, LJ_ENDIAN_SELECT(0x00ffffff, 0xffffff00))); @@ -1672,9 +1705,17 @@ LJFOLDF(fload_str_len_snew) } /* The C type ID of cdata objects is immutable. */ +LJFOLD(FLOAD KGC IRFL_CDATA_TYPEID) +LJFOLDF(fload_cdata_typeid_kgc) +{ + if (LJ_LIKELY(J->flags & JIT_F_OPT_FOLD)) + return INTFOLD((int32_t)ir_kcdata(fleft)->typeid); + return NEXTFOLD; +} + LJFOLD(FLOAD CNEW IRFL_CDATA_TYPEID) LJFOLD(FLOAD CNEWP IRFL_CDATA_TYPEID) -LJFOLDF(fload_cdata_typeid_cnewi) +LJFOLDF(fload_cdata_typeid_cnew) { if (LJ_LIKELY(J->flags & JIT_F_OPT_FOLD)) return fleft->op1; /* No PHI barrier needed. CNEW/CNEWP op1 is const. */ @@ -1683,7 +1724,7 @@ LJFOLDF(fload_cdata_typeid_cnewi) /* Pointer cdata objects are immutable. */ LJFOLD(FLOAD CNEWP IRFL_CDATA_PTR) -LJFOLDF(fload_cdata_ptr_cnewi) +LJFOLDF(fload_cdata_ptr_cnew) { if (LJ_LIKELY(J->flags & JIT_F_OPT_FOLD)) return fleft->op2; /* Fold even across PHI to avoid allocations. */ @@ -1716,10 +1757,8 @@ LJFOLDF(fwd_sload) LJFOLD(XLOAD KPTR any) LJFOLDF(xload_kptr) { - /* Only fold read-only integer loads for now. */ - if ((fins->op2 & IRXLOAD_READONLY) && irt_isinteger(fins->t)) - return INTFOLD(kfold_xload(fins, ir_kptr(fleft))); - return NEXTFOLD; + TRef tr = kfold_xload(J, fins, ir_kptr(fleft)); + return tr ? tr : NEXTFOLD; } LJFOLD(XLOAD any any) diff --git a/src/lj_record.c b/src/lj_record.c index ec03afe1..2aaded14 100644 --- a/src/lj_record.c +++ b/src/lj_record.c @@ -1563,6 +1563,11 @@ void lj_record_ins(jit_State *J) J->base[ra++] = TREF_NIL; if (rc >= J->maxslot) J->maxslot = rc+1; break; +#if LJ_HASFFI + case BC_KCDATA: + rc = lj_ir_kgc(J, proto_kgc(J->pt, ~(ptrdiff_t)rc), IRT_CDATA); + break; +#endif /* -- Upvalue and function ops ------------------------------------------ */