One Level Up
Top Level
src/lj_opt_fold.c - luajit-2.0-src
Data types defined
Functions defined
Macros defined
Source code
- #define lj_opt_fold_c
- #define LUA_CORE
- #include <math.h>
- #include "lj_obj.h"
- #if LJ_HASJIT
- #include "lj_buf.h"
- #include "lj_str.h"
- #include "lj_tab.h"
- #include "lj_ir.h"
- #include "lj_jit.h"
- #include "lj_ircall.h"
- #include "lj_iropt.h"
- #include "lj_trace.h"
- #if LJ_HASFFI
- #include "lj_ctype.h"
- #include "lj_carith.h"
- #endif
- #include "lj_vm.h"
- #include "lj_strscan.h"
- #include "lj_strfmt.h"
- #define IR(ref) (&J->cur.ir[(ref)])
- #define fins (&J->fold.ins)
- #define fleft (&J->fold.left)
- #define fright (&J->fold.right)
- #define knumleft (ir_knum(fleft)->n)
- #define knumright (ir_knum(fright)->n)
- #define emitir(ot, a, b) (lj_ir_set(J, (ot), (a), (b)), lj_opt_fold(J))
- typedef IRRef (LJ_FASTCALL *FoldFunc)(jit_State *J);
- #define LJFOLD(x)
- #define LJFOLDX(x)
- #define LJFOLDF(name) static TRef LJ_FASTCALL fold_##name(jit_State *J)
- #define PHIBARRIER(ir) if (irt_isphi((ir)->t)) return NEXTFOLD
- #define gcstep_barrier(J, ref) \
- ((ref) < J->chain[IR_LOOP] && \
- (J->chain[IR_SNEW] || J->chain[IR_XSNEW] || \
- J->chain[IR_TNEW] || J->chain[IR_TDUP] || \
- J->chain[IR_CNEW] || J->chain[IR_CNEWI] || \
- J->chain[IR_BUFSTR] || J->chain[IR_TOSTR] || J->chain[IR_CALLA]))
- LJFOLD(ADD KNUM KNUM)
- LJFOLD(SUB KNUM KNUM)
- LJFOLD(MUL KNUM KNUM)
- LJFOLD(DIV KNUM KNUM)
- LJFOLD(NEG KNUM KNUM)
- LJFOLD(ABS KNUM KNUM)
- LJFOLD(ATAN2 KNUM KNUM)
- LJFOLD(LDEXP KNUM KNUM)
- LJFOLD(MIN KNUM KNUM)
- LJFOLD(MAX KNUM KNUM)
- LJFOLDF(kfold_numarith)
- {
- lua_Number a = knumleft;
- lua_Number b = knumright;
- lua_Number y = lj_vm_foldarith(a, b, fins->o - IR_ADD);
- return lj_ir_knum(J, y);
- }
- LJFOLD(LDEXP KNUM KINT)
- LJFOLDF(kfold_ldexp)
- {
- #if LJ_TARGET_X86ORX64
- UNUSED(J);
- return NEXTFOLD;
- #else
- return lj_ir_knum(J, ldexp(knumleft, fright->i));
- #endif
- }
- LJFOLD(FPMATH KNUM any)
- LJFOLDF(kfold_fpmath)
- {
- lua_Number a = knumleft;
- lua_Number y = lj_vm_foldfpm(a, fins->op2);
- return lj_ir_knum(J, y);
- }
- LJFOLD(POW KNUM KINT)
- LJFOLDF(kfold_numpow)
- {
- lua_Number a = knumleft;
- lua_Number b = (lua_Number)fright->i;
- lua_Number y = lj_vm_foldarith(a, b, IR_POW - IR_ADD);
- return lj_ir_knum(J, y);
- }
- LJFOLD(EQ KNUM KNUM)
- LJFOLD(NE KNUM KNUM)
- LJFOLD(LT KNUM KNUM)
- LJFOLD(GE KNUM KNUM)
- LJFOLD(LE KNUM KNUM)
- LJFOLD(GT KNUM KNUM)
- LJFOLD(ULT KNUM KNUM)
- LJFOLD(UGE KNUM KNUM)
- LJFOLD(ULE KNUM KNUM)
- LJFOLD(UGT KNUM KNUM)
- LJFOLDF(kfold_numcomp)
- {
- return CONDFOLD(lj_ir_numcmp(knumleft, knumright, (IROp)fins->o));
- }
- static int32_t kfold_intop(int32_t k1, int32_t k2, IROp op)
- {
- switch (op) {
- case IR_ADD: k1 += k2; break;
- case IR_SUB: k1 -= k2; break;
- case IR_MUL: k1 *= k2; break;
- case IR_MOD: k1 = lj_vm_modi(k1, k2); break;
- case IR_NEG: k1 = -k1; break;
- case IR_BAND: k1 &= k2; break;
- case IR_BOR: k1 |= k2; break;
- case IR_BXOR: k1 ^= k2; break;
- case IR_BSHL: k1 <<= (k2 & 31); break;
- case IR_BSHR: k1 = (int32_t)((uint32_t)k1 >> (k2 & 31)); break;
- case IR_BSAR: k1 >>= (k2 & 31); break;
- case IR_BROL: k1 = (int32_t)lj_rol((uint32_t)k1, (k2 & 31)); break;
- case IR_BROR: k1 = (int32_t)lj_ror((uint32_t)k1, (k2 & 31)); break;
- case IR_MIN: k1 = k1 < k2 ? k1 : k2; break;
- case IR_MAX: k1 = k1 > k2 ? k1 : k2; break;
- default: lua_assert(0); break;
- }
- return k1;
- }
- LJFOLD(ADD KINT KINT)
- LJFOLD(SUB KINT KINT)
- LJFOLD(MUL KINT KINT)
- LJFOLD(MOD KINT KINT)
- LJFOLD(NEG KINT KINT)
- LJFOLD(BAND KINT KINT)
- LJFOLD(BOR KINT KINT)
- LJFOLD(BXOR KINT KINT)
- LJFOLD(BSHL KINT KINT)
- LJFOLD(BSHR KINT KINT)
- LJFOLD(BSAR KINT KINT)
- LJFOLD(BROL KINT KINT)
- LJFOLD(BROR KINT KINT)
- LJFOLD(MIN KINT KINT)
- LJFOLD(MAX KINT KINT)
- LJFOLDF(kfold_intarith)
- {
- return INTFOLD(kfold_intop(fleft->i, fright->i, (IROp)fins->o));
- }
- LJFOLD(ADDOV KINT KINT)
- LJFOLD(SUBOV KINT KINT)
- LJFOLD(MULOV KINT KINT)
- LJFOLDF(kfold_intovarith)
- {
- lua_Number n = lj_vm_foldarith((lua_Number)fleft->i, (lua_Number)fright->i,
- fins->o - IR_ADDOV);
- int32_t k = lj_num2int(n);
- if (n != (lua_Number)k)
- return FAILFOLD;
- return INTFOLD(k);
- }
- LJFOLD(BNOT KINT)
- LJFOLDF(kfold_bnot)
- {
- return INTFOLD(~fleft->i);
- }
- LJFOLD(BSWAP KINT)
- LJFOLDF(kfold_bswap)
- {
- return INTFOLD((int32_t)lj_bswap((uint32_t)fleft->i));
- }
- LJFOLD(LT KINT KINT)
- LJFOLD(GE KINT KINT)
- LJFOLD(LE KINT KINT)
- LJFOLD(GT KINT KINT)
- LJFOLD(ULT KINT KINT)
- LJFOLD(UGE KINT KINT)
- LJFOLD(ULE KINT KINT)
- LJFOLD(UGT KINT KINT)
- LJFOLD(ABC KINT KINT)
- LJFOLDF(kfold_intcomp)
- {
- int32_t a = fleft->i, b = fright->i;
- switch ((IROp)fins->o) {
- case IR_LT: return CONDFOLD(a < b);
- case IR_GE: return CONDFOLD(a >= b);
- case IR_LE: return CONDFOLD(a <= b);
- case IR_GT: return CONDFOLD(a > b);
- case IR_ULT: return CONDFOLD((uint32_t)a < (uint32_t)b);
- case IR_UGE: return CONDFOLD((uint32_t)a >= (uint32_t)b);
- case IR_ULE: return CONDFOLD((uint32_t)a <= (uint32_t)b);
- case IR_ABC:
- case IR_UGT: return CONDFOLD((uint32_t)a > (uint32_t)b);
- default: lua_assert(0); return FAILFOLD;
- }
- }
- LJFOLD(UGE any KINT)
- LJFOLDF(kfold_intcomp0)
- {
- if (fright->i == 0)
- return DROPFOLD;
- return NEXTFOLD;
- }
- static uint64_t kfold_int64arith(uint64_t k1, uint64_t k2, IROp op)
- {
- switch (op) {
- #if LJ_HASFFI
- case IR_ADD: k1 += k2; break;
- case IR_SUB: k1 -= k2; break;
- case IR_MUL: k1 *= k2; break;
- case IR_BAND: k1 &= k2; break;
- case IR_BOR: k1 |= k2; break;
- case IR_BXOR: k1 ^= k2; break;
- #endif
- default: UNUSED(k2); lua_assert(0); break;
- }
- return k1;
- }
- LJFOLD(ADD KINT64 KINT64)
- LJFOLD(SUB KINT64 KINT64)
- LJFOLD(MUL KINT64 KINT64)
- LJFOLD(BAND KINT64 KINT64)
- LJFOLD(BOR KINT64 KINT64)
- LJFOLD(BXOR KINT64 KINT64)
- LJFOLDF(kfold_int64arith)
- {
- return INT64FOLD(kfold_int64arith(ir_k64(fleft)->u64,
- ir_k64(fright)->u64, (IROp)fins->o));
- }
- LJFOLD(DIV KINT64 KINT64)
- LJFOLD(MOD KINT64 KINT64)
- LJFOLD(POW KINT64 KINT64)
- LJFOLDF(kfold_int64arith2)
- {
- #if LJ_HASFFI
- uint64_t k1 = ir_k64(fleft)->u64, k2 = ir_k64(fright)->u64;
- if (irt_isi64(fins->t)) {
- k1 = fins->o == IR_DIV ? lj_carith_divi64((int64_t)k1, (int64_t)k2) :
- fins->o == IR_MOD ? lj_carith_modi64((int64_t)k1, (int64_t)k2) :
- lj_carith_powi64((int64_t)k1, (int64_t)k2);
- } else {
- k1 = fins->o == IR_DIV ? lj_carith_divu64(k1, k2) :
- fins->o == IR_MOD ? lj_carith_modu64(k1, k2) :
- lj_carith_powu64(k1, k2);
- }
- return INT64FOLD(k1);
- #else
- UNUSED(J); lua_assert(0); return FAILFOLD;
- #endif
- }
- LJFOLD(BSHL KINT64 KINT)
- LJFOLD(BSHR KINT64 KINT)
- LJFOLD(BSAR KINT64 KINT)
- LJFOLD(BROL KINT64 KINT)
- LJFOLD(BROR KINT64 KINT)
- LJFOLDF(kfold_int64shift)
- {
- #if LJ_HASFFI
- uint64_t k = ir_k64(fleft)->u64;
- int32_t sh = (fright->i & 63);
- return INT64FOLD(lj_carith_shift64(k, sh, fins->o - IR_BSHL));
- #else
- UNUSED(J); lua_assert(0); return FAILFOLD;
- #endif
- }
- LJFOLD(BNOT KINT64)
- LJFOLDF(kfold_bnot64)
- {
- #if LJ_HASFFI
- return INT64FOLD(~ir_k64(fleft)->u64);
- #else
- UNUSED(J); lua_assert(0); return FAILFOLD;
- #endif
- }
- LJFOLD(BSWAP KINT64)
- LJFOLDF(kfold_bswap64)
- {
- #if LJ_HASFFI
- return INT64FOLD(lj_bswap64(ir_k64(fleft)->u64));
- #else
- UNUSED(J); lua_assert(0); return FAILFOLD;
- #endif
- }
- LJFOLD(LT KINT64 KINT64)
- LJFOLD(GE KINT64 KINT64)
- LJFOLD(LE KINT64 KINT64)
- LJFOLD(GT KINT64 KINT64)
- LJFOLD(ULT KINT64 KINT64)
- LJFOLD(UGE KINT64 KINT64)
- LJFOLD(ULE KINT64 KINT64)
- LJFOLD(UGT KINT64 KINT64)
- LJFOLDF(kfold_int64comp)
- {
- #if LJ_HASFFI
- uint64_t a = ir_k64(fleft)->u64, b = ir_k64(fright)->u64;
- switch ((IROp)fins->o) {
- case IR_LT: return CONDFOLD(a < b);
- case IR_GE: return CONDFOLD(a >= b);
- case IR_LE: return CONDFOLD(a <= b);
- case IR_GT: return CONDFOLD(a > b);
- case IR_ULT: return CONDFOLD((uint64_t)a < (uint64_t)b);
- case IR_UGE: return CONDFOLD((uint64_t)a >= (uint64_t)b);
- case IR_ULE: return CONDFOLD((uint64_t)a <= (uint64_t)b);
- case IR_UGT: return CONDFOLD((uint64_t)a > (uint64_t)b);
- default: lua_assert(0); return FAILFOLD;
- }
- #else
- UNUSED(J); lua_assert(0); return FAILFOLD;
- #endif
- }
- LJFOLD(UGE any KINT64)
- LJFOLDF(kfold_int64comp0)
- {
- #if LJ_HASFFI
- if (ir_k64(fright)->u64 == 0)
- return DROPFOLD;
- return NEXTFOLD;
- #else
- UNUSED(J); lua_assert(0); return FAILFOLD;
- #endif
- }
- LJFOLD(SNEW KKPTR KINT)
- LJFOLDF(kfold_snew_kptr)
- {
- GCstr *s = lj_str_new(J->L, (const char *)ir_kptr(fleft), (size_t)fright->i);
- return lj_ir_kstr(J, s);
- }
- LJFOLD(SNEW any KINT)
- LJFOLDF(kfold_snew_empty)
- {
- if (fright->i == 0)
- return lj_ir_kstr(J, &J2G(J)->strempty);
- return NEXTFOLD;
- }
- LJFOLD(STRREF KGC KINT)
- LJFOLDF(kfold_strref)
- {
- GCstr *str = ir_kstr(fleft);
- lua_assert((MSize)fright->i <= str->len);
- return lj_ir_kkptr(J, (char *)strdata(str) + fright->i);
- }
- LJFOLD(STRREF SNEW any)
- LJFOLDF(kfold_strref_snew)
- {
- PHIBARRIER(fleft);
- if (irref_isk(fins->op2) && fright->i == 0) {
- return fleft->op1;
- } else {
-
- IRIns *ir = IR(fleft->op1);
- if (ir->o == IR_STRREF) {
- IRRef1 str = ir->op1;
- PHIBARRIER(ir);
- fins->op2 = emitir(IRTI(IR_ADD), ir->op2, fins->op2);
- fins->op1 = str;
- fins->ot = IRT(IR_STRREF, IRT_P32);
- return RETRYFOLD;
- }
- }
- return NEXTFOLD;
- }
- LJFOLD(CALLN CARG IRCALL_lj_str_cmp)
- LJFOLDF(kfold_strcmp)
- {
- if (irref_isk(fleft->op1) && irref_isk(fleft->op2)) {
- GCstr *a = ir_kstr(IR(fleft->op1));
- GCstr *b = ir_kstr(IR(fleft->op2));
- return INTFOLD(lj_str_cmp(a, b));
- }
- return NEXTFOLD;
- }
- LJFOLD(BUFPUT BUFHDR BUFSTR)
- LJFOLDF(bufput_append)
- {
-
- if ((J->flags & JIT_F_OPT_FWD) &&
- !(fleft->op2 & IRBUFHDR_APPEND) &&
- fleft->prev == fright->op2 &&
- fleft->op1 == IR(fright->op2)->op1) {
- IRRef ref = fins->op1;
- IR(ref)->op2 = (fleft->op2 | IRBUFHDR_APPEND);
- IR(ref)->op1 = fright->op1;
- return ref;
- }
- return EMITFOLD;
- }
- LJFOLD(BUFPUT any any)
- LJFOLDF(bufput_kgc)
- {
- if (LJ_LIKELY(J->flags & JIT_F_OPT_FOLD) && fright->o == IR_KGC) {
- GCstr *s2 = ir_kstr(fright);
- if (s2->len == 0) {
- return LEFTFOLD;
- } else {
- if (fleft->o == IR_BUFPUT && irref_isk(fleft->op2) &&
- !irt_isphi(fleft->t)) {
- GCstr *s1 = ir_kstr(IR(fleft->op2));
- IRRef kref = lj_ir_kstr(J, lj_buf_cat2str(J->L, s1, s2));
-
- IR(fins->op1)->op2 = kref;
- return fins->op1;
- }
- }
- }
- return EMITFOLD;
- }
- LJFOLD(BUFSTR any any)
- LJFOLDF(bufstr_kfold_cse)
- {
- lua_assert(fleft->o == IR_BUFHDR || fleft->o == IR_BUFPUT ||
- fleft->o == IR_CALLL);
- if (LJ_LIKELY(J->flags & JIT_F_OPT_FOLD)) {
- if (fleft->o == IR_BUFHDR) {
- if (!(fleft->op2 & IRBUFHDR_APPEND))
- return lj_ir_kstr(J, &J2G(J)->strempty);
- fins->op1 = fleft->op1;
- fins->op2 = fleft->prev;
- return CSEFOLD;
- } else if (fleft->o == IR_BUFPUT) {
- IRIns *irb = IR(fleft->op1);
- if (irb->o == IR_BUFHDR && !(irb->op2 & IRBUFHDR_APPEND))
- return fleft->op2;
- }
- }
-
- if (LJ_LIKELY(J->flags & JIT_F_OPT_CSE)) {
- IRRef ref = J->chain[IR_BUFSTR];
- while (ref) {
- IRIns *irs = IR(ref), *ira = fleft, *irb = IR(irs->op1);
- while (ira->o == irb->o && ira->op2 == irb->op2) {
- lua_assert(ira->o == IR_BUFHDR || ira->o == IR_BUFPUT ||
- ira->o == IR_CALLL || ira->o == IR_CARG);
- if (ira->o == IR_BUFHDR && !(ira->op2 & IRBUFHDR_APPEND))
- return ref;
- if (ira->o == IR_CALLL && ira->op2 == IRCALL_lj_buf_puttab)
- break;
- ira = IR(ira->op1);
- irb = IR(irb->op1);
- }
- ref = irs->prev;
- }
- }
- return EMITFOLD;
- }
- LJFOLD(CALLL CARG IRCALL_lj_buf_putstr_reverse)
- LJFOLD(CALLL CARG IRCALL_lj_buf_putstr_upper)
- LJFOLD(CALLL CARG IRCALL_lj_buf_putstr_lower)
- LJFOLD(CALLL CARG IRCALL_lj_strfmt_putquoted)
- LJFOLDF(bufput_kfold_op)
- {
- if (irref_isk(fleft->op2)) {
- const CCallInfo *ci = &lj_ir_callinfo[fins->op2];
- SBuf *sb = lj_buf_tmp_(J->L);
- sb = ((SBuf * (LJ_FASTCALL *)(SBuf *, GCstr *))ci->func)(sb,
- ir_kstr(IR(fleft->op2)));
- fins->o = IR_BUFPUT;
- fins->op1 = fleft->op1;
- fins->op2 = lj_ir_kstr(J, lj_buf_tostr(sb));
- return RETRYFOLD;
- }
- return EMITFOLD;
- }
- LJFOLD(CALLL CARG IRCALL_lj_buf_putstr_rep)
- LJFOLDF(bufput_kfold_rep)
- {
- if (irref_isk(fleft->op2)) {
- IRIns *irc = IR(fleft->op1);
- if (irref_isk(irc->op2)) {
- SBuf *sb = lj_buf_tmp_(J->L);
- sb = lj_buf_putstr_rep(sb, ir_kstr(IR(irc->op2)), IR(fleft->op2)->i);
- fins->o = IR_BUFPUT;
- fins->op1 = irc->op1;
- fins->op2 = lj_ir_kstr(J, lj_buf_tostr(sb));
- return RETRYFOLD;
- }
- }
- return EMITFOLD;
- }
- LJFOLD(CALLL CARG IRCALL_lj_strfmt_putfxint)
- LJFOLD(CALLL CARG IRCALL_lj_strfmt_putfnum_int)
- LJFOLD(CALLL CARG IRCALL_lj_strfmt_putfnum_uint)
- LJFOLD(CALLL CARG IRCALL_lj_strfmt_putfnum)
- LJFOLD(CALLL CARG IRCALL_lj_strfmt_putfstr)
- LJFOLD(CALLL CARG IRCALL_lj_strfmt_putfchar)
- LJFOLDF(bufput_kfold_fmt)
- {
- IRIns *irc = IR(fleft->op1);
- lua_assert(irref_isk(irc->op2));
- if (irref_isk(fleft->op2)) {
- SFormat sf = (SFormat)IR(irc->op2)->i;
- IRIns *ira = IR(fleft->op2);
- SBuf *sb = lj_buf_tmp_(J->L);
- switch (fins->op2) {
- case IRCALL_lj_strfmt_putfxint:
- sb = lj_strfmt_putfxint(sb, sf, ir_k64(ira)->u64);
- break;
- case IRCALL_lj_strfmt_putfstr:
- sb = lj_strfmt_putfstr(sb, sf, ir_kstr(ira));
- break;
- case IRCALL_lj_strfmt_putfchar:
- sb = lj_strfmt_putfchar(sb, sf, ira->i);
- break;
- case IRCALL_lj_strfmt_putfnum_int:
- case IRCALL_lj_strfmt_putfnum_uint:
- case IRCALL_lj_strfmt_putfnum:
- default: {
- const CCallInfo *ci = &lj_ir_callinfo[fins->op2];
- sb = ((SBuf * (*)(SBuf *, SFormat, lua_Number))ci->func)(sb, sf,
- ir_knum(ira)->n);
- break;
- }
- }
- fins->o = IR_BUFPUT;
- fins->op1 = irc->op1;
- fins->op2 = lj_ir_kstr(J, lj_buf_tostr(sb));
- return RETRYFOLD;
- }
- return EMITFOLD;
- }
- 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
- #if LJ_HASFFI
- if (irt_iscdata(fleft->t)) {
- CType *ct = ctype_raw(ctype_ctsG(J2G(J)), gco2cd(o)->ctypeid);
- if (ctype_isnum(ct->info) || ctype_isenum(ct->info) ||
- ctype_isptr(ct->info) || ctype_isfunc(ct->info) ||
- ctype_iscomplex(ct->info) || ctype_isvector(ct->info))
- return lj_ir_kkptr(J, (char *)o + ofs);
- }
- #endif
- return lj_ir_kptr(J, (char *)o + ofs);
- }
- LJFOLD(ADD KPTR KINT)
- LJFOLD(ADD KPTR KINT64)
- LJFOLD(ADD KKPTR KINT)
- LJFOLD(ADD KKPTR 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, fleft->o, (char *)p + ofs);
- }
- LJFOLD(ADD any KGC)
- LJFOLD(ADD any KPTR)
- LJFOLD(ADD any KKPTR)
- LJFOLDF(kfold_add_kright)
- {
- if (fleft->o == IR_KINT || fleft->o == IR_KINT64) {
- IRRef1 tmp = fins->op1; fins->op1 = fins->op2; fins->op2 = tmp;
- return RETRYFOLD;
- }
- return NEXTFOLD;
- }
- LJFOLD(TOBIT KNUM KNUM)
- LJFOLDF(kfold_tobit)
- {
- return INTFOLD(lj_num2bit(knumleft));
- }
- LJFOLD(CONV KINT IRCONV_NUM_INT)
- LJFOLDF(kfold_conv_kint_num)
- {
- return lj_ir_knum(J, (lua_Number)fleft->i);
- }
- LJFOLD(CONV KINT IRCONV_NUM_U32)
- LJFOLDF(kfold_conv_kintu32_num)
- {
- return lj_ir_knum(J, (lua_Number)(uint32_t)fleft->i);
- }
- LJFOLD(CONV KINT IRCONV_INT_I8)
- LJFOLD(CONV KINT IRCONV_INT_U8)
- LJFOLD(CONV KINT IRCONV_INT_I16)
- LJFOLD(CONV KINT IRCONV_INT_U16)
- LJFOLDF(kfold_conv_kint_ext)
- {
- int32_t k = fleft->i;
- if ((fins->op2 & IRCONV_SRCMASK) == IRT_I8) k = (int8_t)k;
- else if ((fins->op2 & IRCONV_SRCMASK) == IRT_U8) k = (uint8_t)k;
- else if ((fins->op2 & IRCONV_SRCMASK) == IRT_I16) k = (int16_t)k;
- else k = (uint16_t)k;
- return INTFOLD(k);
- }
- LJFOLD(CONV KINT IRCONV_I64_INT)
- LJFOLD(CONV KINT IRCONV_U64_INT)
- LJFOLD(CONV KINT IRCONV_I64_U32)
- LJFOLD(CONV KINT IRCONV_U64_U32)
- LJFOLDF(kfold_conv_kint_i64)
- {
- if ((fins->op2 & IRCONV_SEXT))
- return INT64FOLD((uint64_t)(int64_t)fleft->i);
- else
- return INT64FOLD((uint64_t)(int64_t)(uint32_t)fleft->i);
- }
- LJFOLD(CONV KINT64 IRCONV_NUM_I64)
- LJFOLDF(kfold_conv_kint64_num_i64)
- {
- return lj_ir_knum(J, (lua_Number)(int64_t)ir_kint64(fleft)->u64);
- }
- LJFOLD(CONV KINT64 IRCONV_NUM_U64)
- LJFOLDF(kfold_conv_kint64_num_u64)
- {
- return lj_ir_knum(J, (lua_Number)ir_kint64(fleft)->u64);
- }
- LJFOLD(CONV KINT64 IRCONV_INT_I64)
- LJFOLD(CONV KINT64 IRCONV_U32_I64)
- LJFOLDF(kfold_conv_kint64_int_i64)
- {
- return INTFOLD((int32_t)ir_kint64(fleft)->u64);
- }
- LJFOLD(CONV KNUM IRCONV_INT_NUM)
- LJFOLDF(kfold_conv_knum_int_num)
- {
- lua_Number n = knumleft;
- int32_t k = lj_num2int(n);
- if (irt_isguard(fins->t) && n != (lua_Number)k) {
-
- return FAILFOLD;
- }
- return INTFOLD(k);
- }
- LJFOLD(CONV KNUM IRCONV_U32_NUM)
- LJFOLDF(kfold_conv_knum_u32_num)
- {
- #ifdef _MSC_VER
- {
- volatile uint32_t u = (uint32_t)knumleft;
- return INTFOLD((int32_t)u);
- }
- #else
- return INTFOLD((int32_t)(uint32_t)knumleft);
- #endif
- }
- LJFOLD(CONV KNUM IRCONV_I64_NUM)
- LJFOLDF(kfold_conv_knum_i64_num)
- {
- return INT64FOLD((uint64_t)(int64_t)knumleft);
- }
- LJFOLD(CONV KNUM IRCONV_U64_NUM)
- LJFOLDF(kfold_conv_knum_u64_num)
- {
- return INT64FOLD(lj_num2u64(knumleft));
- }
- LJFOLD(TOSTR KNUM any)
- LJFOLDF(kfold_tostr_knum)
- {
- return lj_ir_kstr(J, lj_strfmt_num(J->L, ir_knum(fleft)));
- }
- LJFOLD(TOSTR KINT any)
- LJFOLDF(kfold_tostr_kint)
- {
- return lj_ir_kstr(J, fins->op2 == IRTOSTR_INT ?
- lj_strfmt_int(J->L, fleft->i) :
- lj_strfmt_char(J->L, fleft->i));
- }
- LJFOLD(STRTO KGC)
- LJFOLDF(kfold_strto)
- {
- TValue n;
- if (lj_strscan_num(ir_kstr(fleft), &n))
- return lj_ir_knum(J, numV(&n));
- return FAILFOLD;
- }
- LJFOLD(EQ FLOAD KNULL)
- LJFOLD(NE FLOAD KNULL)
- LJFOLDX(lj_opt_cse)
- LJFOLD(EQ any KNULL)
- LJFOLD(NE any KNULL)
- LJFOLD(EQ KNULL any)
- LJFOLD(NE KNULL any)
- LJFOLD(EQ KINT KINT)
- LJFOLD(NE KINT KINT)
- LJFOLD(EQ KINT64 KINT64)
- LJFOLD(NE KINT64 KINT64)
- LJFOLD(EQ KGC KGC)
- LJFOLD(NE KGC KGC)
- LJFOLDF(kfold_kref)
- {
- return CONDFOLD((fins->op1 == fins->op2) ^ (fins->o == IR_NE));
- }
- LJFOLD(FPMATH FPMATH IRFPM_FLOOR)
- LJFOLD(FPMATH FPMATH IRFPM_CEIL)
- LJFOLD(FPMATH FPMATH IRFPM_TRUNC)
- LJFOLDF(shortcut_round)
- {
- IRFPMathOp op = (IRFPMathOp)fleft->op2;
- if (op == IRFPM_FLOOR || op == IRFPM_CEIL || op == IRFPM_TRUNC)
- return LEFTFOLD;
- return NEXTFOLD;
- }
- LJFOLD(ABS ABS KNUM)
- LJFOLDF(shortcut_left)
- {
- return LEFTFOLD;
- }
- LJFOLD(ABS NEG KNUM)
- LJFOLDF(shortcut_dropleft)
- {
- PHIBARRIER(fleft);
- fins->op1 = fleft->op1;
- return RETRYFOLD;
- }
- LJFOLD(NEG NEG any)
- LJFOLD(BNOT BNOT)
- LJFOLD(BSWAP BSWAP)
- LJFOLDF(shortcut_leftleft)
- {
- PHIBARRIER(fleft);
- return fleft->op1;
- }
- LJFOLD(ADD NEG any)
- LJFOLDF(simplify_numadd_negx)
- {
- PHIBARRIER(fleft);
- fins->o = IR_SUB;
- fins->op1 = fins->op2;
- fins->op2 = fleft->op1;
- return RETRYFOLD;
- }
- LJFOLD(ADD any NEG)
- LJFOLDF(simplify_numadd_xneg)
- {
- PHIBARRIER(fright);
- fins->o = IR_SUB;
- fins->op2 = fright->op1;
- return RETRYFOLD;
- }
- LJFOLD(SUB any KNUM)
- LJFOLDF(simplify_numsub_k)
- {
- lua_Number n = knumright;
- if (n == 0.0)
- return LEFTFOLD;
- return NEXTFOLD;
- }
- LJFOLD(SUB NEG KNUM)
- LJFOLDF(simplify_numsub_negk)
- {
- PHIBARRIER(fleft);
- fins->op2 = fleft->op1;
- fins->op1 = (IRRef1)lj_ir_knum(J, -knumright);
- return RETRYFOLD;
- }
- LJFOLD(SUB any NEG)
- LJFOLDF(simplify_numsub_xneg)
- {
- PHIBARRIER(fright);
- fins->o = IR_ADD;
- fins->op2 = fright->op1;
- return RETRYFOLD;
- }
- LJFOLD(MUL any KNUM)
- LJFOLD(DIV any KNUM)
- LJFOLDF(simplify_nummuldiv_k)
- {
- lua_Number n = knumright;
- if (n == 1.0) {
- return LEFTFOLD;
- } else if (n == -1.0) {
- fins->o = IR_NEG;
- fins->op2 = (IRRef1)lj_ir_knum_neg(J);
- return RETRYFOLD;
- } else if (fins->o == IR_MUL && n == 2.0) {
- fins->o = IR_ADD;
- fins->op2 = fins->op1;
- return RETRYFOLD;
- } else if (fins->o == IR_DIV) {
- uint64_t u = ir_knum(fright)->u64;
- uint32_t ex = ((uint32_t)(u >> 52) & 0x7ff);
- if ((u & U64x(000fffff,ffffffff)) == 0 && ex - 1 < 0x7fd) {
- u = (u & ((uint64_t)1 << 63)) | ((uint64_t)(0x7fe - ex) << 52);
- fins->o = IR_MUL;
- fins->op2 = lj_ir_knum_u64(J, u);
- return RETRYFOLD;
- }
- }
- return NEXTFOLD;
- }
- LJFOLD(MUL NEG KNUM)
- LJFOLD(DIV NEG KNUM)
- LJFOLDF(simplify_nummuldiv_negk)
- {
- PHIBARRIER(fleft);
- fins->op1 = fleft->op1;
- fins->op2 = (IRRef1)lj_ir_knum(J, -knumright);
- return RETRYFOLD;
- }
- LJFOLD(MUL NEG NEG)
- LJFOLD(DIV NEG NEG)
- LJFOLDF(simplify_nummuldiv_negneg)
- {
- PHIBARRIER(fleft);
- PHIBARRIER(fright);
- fins->op1 = fleft->op1;
- fins->op2 = fright->op1;
- return RETRYFOLD;
- }
- LJFOLD(POW any KINT)
- LJFOLDF(simplify_numpow_xk)
- {
- int32_t k = fright->i;
- TRef ref = fins->op1;
- if (k == 0)
- return lj_ir_knum_one(J);
- if (k == 1)
- return LEFTFOLD;
- if ((uint32_t)(k+65536) > 2*65536u)
- return NEXTFOLD;
- if (k < 0) {
- ref = emitir(IRTN(IR_DIV), lj_ir_knum_one(J), ref);
- k = -k;
- }
-
- for (; (k & 1) == 0; k >>= 1)
- ref = emitir(IRTN(IR_MUL), ref, ref);
- if ((k >>= 1) != 0) {
- TRef tmp = emitir(IRTN(IR_MUL), ref, ref);
- for (; k != 1; k >>= 1) {
- if (k & 1)
- ref = emitir(IRTN(IR_MUL), ref, tmp);
- tmp = emitir(IRTN(IR_MUL), tmp, tmp);
- }
- ref = emitir(IRTN(IR_MUL), ref, tmp);
- }
- return ref;
- }
- LJFOLD(POW KNUM any)
- LJFOLDF(simplify_numpow_kx)
- {
- lua_Number n = knumleft;
- if (n == 2.0) {
- fins->o = IR_CONV;
- #if LJ_TARGET_X86ORX64
- fins->op1 = fins->op2;
- fins->op2 = IRCONV_NUM_INT;
- fins->op2 = (IRRef1)lj_opt_fold(J);
- #endif
- fins->op1 = (IRRef1)lj_ir_knum_one(J);
- fins->o = IR_LDEXP;
- return RETRYFOLD;
- }
- return NEXTFOLD;
- }
- LJFOLD(CONV CONV IRCONV_NUM_INT)
- LJFOLDF(shortcut_conv_num_int)
- {
- PHIBARRIER(fleft);
-
- if ((fleft->op2 & IRCONV_SRCMASK) == IRT_NUM && irt_isguard(fleft->t))
- return fleft->op1;
- return NEXTFOLD;
- }
- LJFOLD(CONV CONV IRCONV_INT_NUM)
- LJFOLD(CONV CONV IRCONV_U32_NUM)
- LJFOLDF(simplify_conv_int_num)
- {
-
- if ((fleft->op2 & IRCONV_SRCMASK) ==
- ((fins->op2 & IRCONV_DSTMASK) >> IRCONV_DSH))
- return fleft->op1;
- return NEXTFOLD;
- }
- LJFOLD(CONV CONV IRCONV_I64_NUM)
- LJFOLD(CONV CONV IRCONV_U64_NUM)
- LJFOLDF(simplify_conv_i64_num)
- {
- PHIBARRIER(fleft);
- if ((fleft->op2 & IRCONV_SRCMASK) == IRT_INT) {
-
- fins->op1 = fleft->op1;
- fins->op2 = ((IRT_I64<<5)|IRT_INT|IRCONV_SEXT);
- return RETRYFOLD;
- } else if ((fleft->op2 & IRCONV_SRCMASK) == IRT_U32) {
- #if LJ_TARGET_X64
- return fleft->op1;
- #else
-
- fins->op1 = fleft->op1;
- fins->op2 = (IRT_I64<<5)|IRT_U32;
- return RETRYFOLD;
- #endif
- }
- return NEXTFOLD;
- }
- LJFOLD(CONV CONV IRCONV_INT_I64)
- LJFOLD(CONV CONV IRCONV_INT_U64)
- LJFOLD(CONV CONV IRCONV_U32_I64)
- LJFOLD(CONV CONV IRCONV_U32_U64)
- LJFOLDF(simplify_conv_int_i64)
- {
- int src;
- PHIBARRIER(fleft);
- src = (fleft->op2 & IRCONV_SRCMASK);
- if (src == IRT_INT || src == IRT_U32) {
- if (src == ((fins->op2 & IRCONV_DSTMASK) >> IRCONV_DSH)) {
- return fleft->op1;
- } else {
- fins->op2 = ((fins->op2 & IRCONV_DSTMASK) | src);
- fins->op1 = fleft->op1;
- return RETRYFOLD;
- }
- }
- return NEXTFOLD;
- }
- LJFOLD(CONV CONV IRCONV_FLOAT_NUM)
- LJFOLDF(simplify_conv_flt_num)
- {
- PHIBARRIER(fleft);
- if ((fleft->op2 & IRCONV_SRCMASK) == IRT_FLOAT)
- return fleft->op1;
- return NEXTFOLD;
- }
- LJFOLD(TOBIT CONV KNUM)
- LJFOLDF(simplify_tobit_conv)
- {
-
- if ((fleft->op2 & IRCONV_SRCMASK) == IRT_INT) {
- lua_assert(irt_isnum(fleft->t));
- return fleft->op1;
- } else if ((fleft->op2 & IRCONV_SRCMASK) == IRT_U32) {
- lua_assert(irt_isnum(fleft->t));
- fins->o = IR_CONV;
- fins->op1 = fleft->op1;
- fins->op2 = (IRT_INT<<5)|IRT_U32;
- return RETRYFOLD;
- }
- return NEXTFOLD;
- }
- LJFOLD(FPMATH CONV IRFPM_FLOOR)
- LJFOLD(FPMATH CONV IRFPM_CEIL)
- LJFOLD(FPMATH CONV IRFPM_TRUNC)
- LJFOLDF(simplify_floor_conv)
- {
- if ((fleft->op2 & IRCONV_SRCMASK) == IRT_INT ||
- (fleft->op2 & IRCONV_SRCMASK) == IRT_U32)
- return LEFTFOLD;
- return NEXTFOLD;
- }
- LJFOLD(CONV any IRCONV_I64_INT)
- LJFOLD(CONV any IRCONV_U64_INT)
- LJFOLDF(simplify_conv_sext)
- {
- IRRef ref = fins->op1;
- int64_t ofs = 0;
- if (!(fins->op2 & IRCONV_SEXT))
- return NEXTFOLD;
- PHIBARRIER(fleft);
- if (fleft->o == IR_XLOAD && (irt_isu8(fleft->t) || irt_isu16(fleft->t)))
- goto ok_reduce;
- if (fleft->o == IR_ADD && irref_isk(fleft->op2)) {
- ofs = (int64_t)IR(fleft->op2)->i;
- ref = fleft->op1;
- }
-
- if (ref == J->scev.idx) {
- IRRef lo = J->scev.dir ? J->scev.start : J->scev.stop;
- lua_assert(irt_isint(J->scev.t));
- if (lo && IR(lo)->i + ofs >= 0) {
- ok_reduce:
- #if LJ_TARGET_X64
-
- return LEFTFOLD;
- #else
-
- fins->op2 &= ~IRCONV_SEXT;
- return RETRYFOLD;
- #endif
- }
- }
- return NEXTFOLD;
- }
- 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)
- LJFOLD(CONV ADD IRCONV_U32_I64)
- LJFOLD(CONV SUB IRCONV_U32_I64)
- LJFOLD(CONV MUL IRCONV_U32_I64)
- LJFOLD(CONV ADD IRCONV_U32_U64)
- LJFOLD(CONV SUB IRCONV_U32_U64)
- LJFOLD(CONV MUL IRCONV_U32_U64)
- LJFOLDF(simplify_conv_narrow)
- {
- IROp op = (IROp)fleft->o;
- IRType t = irt_type(fins->t);
- 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 = IRT(op, t);
- fins->op1 = op1;
- fins->op2 = op2;
- return RETRYFOLD;
- }
- LJFOLD(CONV any any)
- LJFOLDF(cse_conv)
- {
- if (LJ_LIKELY(J->flags & JIT_F_OPT_CSE)) {
- IRRef op1 = fins->op1, op2 = (fins->op2 & IRCONV_MODEMASK);
- uint8_t guard = irt_isguard(fins->t);
- IRRef ref = J->chain[IR_CONV];
- while (ref > op1) {
- IRIns *ir = IR(ref);
-
- if (ir->op1 == op1 && (ir->op2 & IRCONV_MODEMASK) == op2 &&
- irt_isguard(ir->t) >= guard)
- return ref;
- ref = ir->prev;
- }
- }
- return EMITFOLD;
- }
- LJFOLD(TOBIT ADD KNUM)
- LJFOLD(TOBIT SUB KNUM)
- LJFOLD(CONV ADD IRCONV_INT_NUM)
- LJFOLD(CONV SUB IRCONV_INT_NUM)
- LJFOLD(CONV ADD IRCONV_I64_NUM)
- LJFOLD(CONV SUB IRCONV_I64_NUM)
- LJFOLDF(narrow_convert)
- {
- PHIBARRIER(fleft);
-
- if (J->chain[IR_LOOP])
- return NEXTFOLD;
- lua_assert(fins->o != IR_CONV || (fins->op2&IRCONV_CONVMASK) != IRCONV_TOBIT);
- return lj_opt_narrow_convert(J);
- }
- LJFOLD(ADD any KINT)
- LJFOLD(ADDOV any KINT)
- LJFOLD(SUBOV any KINT)
- LJFOLDF(simplify_intadd_k)
- {
- if (fright->i == 0)
- return LEFTFOLD;
- return NEXTFOLD;
- }
- LJFOLD(MULOV any KINT)
- LJFOLDF(simplify_intmul_k)
- {
- if (fright->i == 0)
- return RIGHTFOLD;
- if (fright->i == 1)
- return LEFTFOLD;
- if (fright->i == 2) {
- fins->o = IR_ADDOV;
- fins->op2 = fins->op1;
- return RETRYFOLD;
- }
- return NEXTFOLD;
- }
- LJFOLD(SUB any KINT)
- LJFOLDF(simplify_intsub_k)
- {
- if (fright->i == 0)
- return LEFTFOLD;
- fins->o = IR_ADD;
- fins->op2 = (IRRef1)lj_ir_kint(J, -fright->i);
- return RETRYFOLD;
- }
- LJFOLD(SUB KINT any)
- LJFOLD(SUB KINT64 any)
- LJFOLDF(simplify_intsub_kleft)
- {
- if (fleft->o == IR_KINT ? (fleft->i == 0) : (ir_kint64(fleft)->u64 == 0)) {
- fins->o = IR_NEG;
- fins->op1 = fins->op2;
- return RETRYFOLD;
- }
- return NEXTFOLD;
- }
- LJFOLD(ADD any KINT64)
- LJFOLDF(simplify_intadd_k64)
- {
- if (ir_kint64(fright)->u64 == 0)
- return LEFTFOLD;
- return NEXTFOLD;
- }
- LJFOLD(SUB any KINT64)
- LJFOLDF(simplify_intsub_k64)
- {
- uint64_t k = ir_kint64(fright)->u64;
- if (k == 0)
- return LEFTFOLD;
- fins->o = IR_ADD;
- fins->op2 = (IRRef1)lj_ir_kint64(J, (uint64_t)-(int64_t)k);
- return RETRYFOLD;
- }
- static TRef simplify_intmul_k(jit_State *J, int32_t k)
- {
-
- if (k == 0) {
- return RIGHTFOLD;
- } else if (k == 1) {
- return LEFTFOLD;
- } else if ((k & (k-1)) == 0) {
- fins->o = IR_BSHL;
- fins->op2 = lj_ir_kint(J, lj_fls((uint32_t)k));
- return RETRYFOLD;
- }
- return NEXTFOLD;
- }
- LJFOLD(MUL any KINT)
- LJFOLDF(simplify_intmul_k32)
- {
- if (fright->i >= 0)
- return simplify_intmul_k(J, fright->i);
- return NEXTFOLD;
- }
- LJFOLD(MUL any KINT64)
- LJFOLDF(simplify_intmul_k64)
- {
- #if LJ_HASFFI
- if (ir_kint64(fright)->u64 < 0x80000000u)
- return simplify_intmul_k(J, (int32_t)ir_kint64(fright)->u64);
- return NEXTFOLD;
- #else
- UNUSED(J); lua_assert(0); return FAILFOLD;
- #endif
- }
- LJFOLD(MOD any KINT)
- LJFOLDF(simplify_intmod_k)
- {
- int32_t k = fright->i;
- lua_assert(k != 0);
- if (k > 0 && (k & (k-1)) == 0) {
- fins->o = IR_BAND;
- fins->op2 = lj_ir_kint(J, k-1);
- return RETRYFOLD;
- }
- return NEXTFOLD;
- }
- LJFOLD(MOD KINT any)
- LJFOLDF(simplify_intmod_kleft)
- {
- if (fleft->i == 0)
- return INTFOLD(0);
- return NEXTFOLD;
- }
- LJFOLD(SUB any any)
- LJFOLD(SUBOV any any)
- LJFOLDF(simplify_intsub)
- {
- if (fins->op1 == fins->op2 && !irt_isnum(fins->t))
- return irt_is64(fins->t) ? INT64FOLD(0) : INTFOLD(0);
- return NEXTFOLD;
- }
- LJFOLD(SUB ADD any)
- LJFOLDF(simplify_intsubadd_leftcancel)
- {
- if (!irt_isnum(fins->t)) {
- PHIBARRIER(fleft);
- if (fins->op2 == fleft->op1)
- return fleft->op2;
- if (fins->op2 == fleft->op2)
- return fleft->op1;
- }
- return NEXTFOLD;
- }
- LJFOLD(SUB SUB any)
- LJFOLDF(simplify_intsubsub_leftcancel)
- {
- if (!irt_isnum(fins->t)) {
- PHIBARRIER(fleft);
- if (fins->op2 == fleft->op1) {
- fins->op1 = (IRRef1)lj_ir_kint(J, 0);
- fins->op2 = fleft->op2;
- return RETRYFOLD;
- }
- }
- return NEXTFOLD;
- }
- LJFOLD(SUB any SUB)
- LJFOLDF(simplify_intsubsub_rightcancel)
- {
- if (!irt_isnum(fins->t)) {
- PHIBARRIER(fright);
- if (fins->op1 == fright->op1)
- return fright->op2;
- }
- return NEXTFOLD;
- }
- LJFOLD(SUB any ADD)
- LJFOLDF(simplify_intsubadd_rightcancel)
- {
- if (!irt_isnum(fins->t)) {
- PHIBARRIER(fright);
- if (fins->op1 == fright->op1) {
- fins->op2 = fright->op2;
- fins->op1 = (IRRef1)lj_ir_kint(J, 0);
- return RETRYFOLD;
- }
- if (fins->op1 == fright->op2) {
- fins->op2 = fright->op1;
- fins->op1 = (IRRef1)lj_ir_kint(J, 0);
- return RETRYFOLD;
- }
- }
- return NEXTFOLD;
- }
- LJFOLD(SUB ADD ADD)
- LJFOLDF(simplify_intsubaddadd_cancel)
- {
- if (!irt_isnum(fins->t)) {
- PHIBARRIER(fleft);
- PHIBARRIER(fright);
- if (fleft->op1 == fright->op1) {
- fins->op1 = fleft->op2;
- fins->op2 = fright->op2;
- return RETRYFOLD;
- }
- if (fleft->op1 == fright->op2) {
- fins->op1 = fleft->op2;
- fins->op2 = fright->op1;
- return RETRYFOLD;
- }
- if (fleft->op2 == fright->op1) {
- fins->op1 = fleft->op1;
- fins->op2 = fright->op2;
- return RETRYFOLD;
- }
- if (fleft->op2 == fright->op2) {
- fins->op1 = fleft->op1;
- fins->op2 = fright->op1;
- return RETRYFOLD;
- }
- }
- return NEXTFOLD;
- }
- LJFOLD(BAND any KINT)
- LJFOLD(BAND any KINT64)
- LJFOLDF(simplify_band_k)
- {
- int64_t k = fright->o == IR_KINT ? (int64_t)fright->i :
- (int64_t)ir_k64(fright)->u64;
- if (k == 0)
- return RIGHTFOLD;
- if (k == -1)
- return LEFTFOLD;
- return NEXTFOLD;
- }
- LJFOLD(BOR any KINT)
- LJFOLD(BOR any KINT64)
- LJFOLDF(simplify_bor_k)
- {
- int64_t k = fright->o == IR_KINT ? (int64_t)fright->i :
- (int64_t)ir_k64(fright)->u64;
- if (k == 0)
- return LEFTFOLD;
- if (k == -1)
- return RIGHTFOLD;
- return NEXTFOLD;
- }
- LJFOLD(BXOR any KINT)
- LJFOLD(BXOR any KINT64)
- LJFOLDF(simplify_bxor_k)
- {
- int64_t k = fright->o == IR_KINT ? (int64_t)fright->i :
- (int64_t)ir_k64(fright)->u64;
- if (k == 0)
- return LEFTFOLD;
- if (k == -1) {
- fins->o = IR_BNOT;
- fins->op2 = 0;
- return RETRYFOLD;
- }
- return NEXTFOLD;
- }
- LJFOLD(BSHL any KINT)
- LJFOLD(BSHR any KINT)
- LJFOLD(BSAR any KINT)
- LJFOLD(BROL any KINT)
- LJFOLD(BROR any KINT)
- LJFOLDF(simplify_shift_ik)
- {
- int32_t mask = irt_is64(fins->t) ? 63 : 31;
- int32_t k = (fright->i & mask);
- if (k == 0)
- return LEFTFOLD;
- if (k == 1 && fins->o == IR_BSHL) {
- fins->o = IR_ADD;
- fins->op2 = fins->op1;
- return RETRYFOLD;
- }
- if (k != fright->i) {
- fins->op2 = (IRRef1)lj_ir_kint(J, k);
- return RETRYFOLD;
- }
- #ifndef LJ_TARGET_UNIFYROT
- if (fins->o == IR_BROR) {
- fins->o = IR_BROL;
- fins->op2 = (IRRef1)lj_ir_kint(J, (-k)&mask);
- return RETRYFOLD;
- }
- #endif
- return NEXTFOLD;
- }
- LJFOLD(BSHL any BAND)
- LJFOLD(BSHR any BAND)
- LJFOLD(BSAR any BAND)
- LJFOLD(BROL any BAND)
- LJFOLD(BROR any BAND)
- LJFOLDF(simplify_shift_andk)
- {
- IRIns *irk = IR(fright->op2);
- PHIBARRIER(fright);
- if ((fins->o < IR_BROL ? LJ_TARGET_MASKSHIFT : LJ_TARGET_MASKROT) &&
- irk->o == IR_KINT) {
- int32_t mask = irt_is64(fins->t) ? 63 : 31;
- int32_t k = irk->i & mask;
- if (k == mask) {
- fins->op2 = fright->op1;
- return RETRYFOLD;
- }
- }
- return NEXTFOLD;
- }
- LJFOLD(BSHL KINT any)
- LJFOLD(BSHR KINT any)
- LJFOLD(BSHL KINT64 any)
- LJFOLD(BSHR KINT64 any)
- LJFOLDF(simplify_shift1_ki)
- {
- int64_t k = fleft->o == IR_KINT ? (int64_t)fleft->i :
- (int64_t)ir_k64(fleft)->u64;
- if (k == 0)
- return LEFTFOLD;
- return NEXTFOLD;
- }
- LJFOLD(BSAR KINT any)
- LJFOLD(BROL KINT any)
- LJFOLD(BROR KINT any)
- LJFOLD(BSAR KINT64 any)
- LJFOLD(BROL KINT64 any)
- LJFOLD(BROR KINT64 any)
- LJFOLDF(simplify_shift2_ki)
- {
- int64_t k = fleft->o == IR_KINT ? (int64_t)fleft->i :
- (int64_t)ir_k64(fleft)->u64;
- if (k == 0 || k == -1)
- return LEFTFOLD;
- return NEXTFOLD;
- }
- LJFOLD(BSHL BAND KINT)
- LJFOLD(BSHR BAND KINT)
- LJFOLD(BROL BAND KINT)
- LJFOLD(BROR BAND KINT)
- LJFOLDF(simplify_shiftk_andk)
- {
- IRIns *irk = IR(fleft->op2);
- PHIBARRIER(fleft);
- if (irk->o == IR_KINT) {
- int32_t k = kfold_intop(irk->i, fright->i, (IROp)fins->o);
- fins->op1 = fleft->op1;
- fins->op1 = (IRRef1)lj_opt_fold(J);
- fins->op2 = (IRRef1)lj_ir_kint(J, k);
- fins->ot = IRTI(IR_BAND);
- return RETRYFOLD;
- }
- return NEXTFOLD;
- }
- LJFOLD(BAND BSHL KINT)
- LJFOLD(BAND BSHR KINT)
- LJFOLDF(simplify_andk_shiftk)
- {
- IRIns *irk = IR(fleft->op2);
- if (irk->o == IR_KINT &&
- kfold_intop(-1, irk->i, (IROp)fleft->o) == fright->i)
- return LEFTFOLD;
- return NEXTFOLD;
- }
- LJFOLD(ADD ADD KINT)
- LJFOLD(MUL MUL KINT)
- LJFOLD(BAND BAND KINT)
- LJFOLD(BOR BOR KINT)
- LJFOLD(BXOR BXOR KINT)
- LJFOLDF(reassoc_intarith_k)
- {
- IRIns *irk = IR(fleft->op2);
- if (irk->o == IR_KINT) {
- int32_t k = kfold_intop(irk->i, fright->i, (IROp)fins->o);
- if (k == irk->i)
- return LEFTFOLD;
- PHIBARRIER(fleft);
- fins->op1 = fleft->op1;
- fins->op2 = (IRRef1)lj_ir_kint(J, k);
- return RETRYFOLD;
- }
- return NEXTFOLD;
- }
- LJFOLD(ADD ADD KINT64)
- LJFOLD(MUL MUL KINT64)
- LJFOLD(BAND BAND KINT64)
- LJFOLD(BOR BOR KINT64)
- LJFOLD(BXOR BXOR KINT64)
- LJFOLDF(reassoc_intarith_k64)
- {
- #if LJ_HASFFI
- IRIns *irk = IR(fleft->op2);
- if (irk->o == IR_KINT64) {
- uint64_t k = kfold_int64arith(ir_k64(irk)->u64,
- ir_k64(fright)->u64, (IROp)fins->o);
- PHIBARRIER(fleft);
- fins->op1 = fleft->op1;
- fins->op2 = (IRRef1)lj_ir_kint64(J, k);
- return RETRYFOLD;
- }
- return NEXTFOLD;
- #else
- UNUSED(J); lua_assert(0); return FAILFOLD;
- #endif
- }
- LJFOLD(MIN MIN any)
- LJFOLD(MAX MAX any)
- LJFOLD(BAND BAND any)
- LJFOLD(BOR BOR any)
- LJFOLDF(reassoc_dup)
- {
- if (fins->op2 == fleft->op1 || fins->op2 == fleft->op2)
- return LEFTFOLD;
- return NEXTFOLD;
- }
- LJFOLD(BXOR BXOR any)
- LJFOLDF(reassoc_bxor)
- {
- PHIBARRIER(fleft);
- if (fins->op2 == fleft->op1)
- return fleft->op2;
- if (fins->op2 == fleft->op2)
- return fleft->op1;
- return NEXTFOLD;
- }
- LJFOLD(BSHL BSHL KINT)
- LJFOLD(BSHR BSHR KINT)
- LJFOLD(BSAR BSAR KINT)
- LJFOLD(BROL BROL KINT)
- LJFOLD(BROR BROR KINT)
- LJFOLDF(reassoc_shift)
- {
- IRIns *irk = IR(fleft->op2);
- PHIBARRIER(fleft);
- if (irk->o == IR_KINT) {
- int32_t mask = irt_is64(fins->t) ? 63 : 31;
- int32_t k = (irk->i & mask) + (fright->i & mask);
- if (k > mask) {
- if (fins->o == IR_BSHL || fins->o == IR_BSHR)
- return mask == 31 ? INTFOLD(0) : INT64FOLD(0);
- else if (fins->o == IR_BSAR)
- k = mask;
- else
- k &= mask;
- }
- fins->op1 = fleft->op1;
- fins->op2 = (IRRef1)lj_ir_kint(J, k);
- return RETRYFOLD;
- }
- return NEXTFOLD;
- }
- LJFOLD(MIN MIN KNUM)
- LJFOLD(MAX MAX KNUM)
- LJFOLD(MIN MIN KINT)
- LJFOLD(MAX MAX KINT)
- LJFOLDF(reassoc_minmax_k)
- {
- IRIns *irk = IR(fleft->op2);
- if (irk->o == IR_KNUM) {
- lua_Number a = ir_knum(irk)->n;
- lua_Number y = lj_vm_foldarith(a, knumright, fins->o - IR_ADD);
- if (a == y)
- return LEFTFOLD;
- PHIBARRIER(fleft);
- fins->op1 = fleft->op1;
- fins->op2 = (IRRef1)lj_ir_knum(J, y);
- return RETRYFOLD;
- } else if (irk->o == IR_KINT) {
- int32_t a = irk->i;
- int32_t y = kfold_intop(a, fright->i, fins->o);
- if (a == y)
- return LEFTFOLD;
- PHIBARRIER(fleft);
- fins->op1 = fleft->op1;
- fins->op2 = (IRRef1)lj_ir_kint(J, y);
- return RETRYFOLD;
- }
- return NEXTFOLD;
- }
- LJFOLD(MIN MAX any)
- LJFOLD(MAX MIN any)
- LJFOLDF(reassoc_minmax_left)
- {
- if (fins->op2 == fleft->op1 || fins->op2 == fleft->op2)
- return RIGHTFOLD;
- return NEXTFOLD;
- }
- LJFOLD(MIN any MAX)
- LJFOLD(MAX any MIN)
- LJFOLDF(reassoc_minmax_right)
- {
- if (fins->op1 == fright->op1 || fins->op1 == fright->op2)
- return LEFTFOLD;
- return NEXTFOLD;
- }
- LJFOLD(ABC any ADD)
- LJFOLDF(abc_fwd)
- {
- if (LJ_LIKELY(J->flags & JIT_F_OPT_ABC)) {
- if (irref_isk(fright->op2)) {
- IRIns *add2 = IR(fright->op1);
- if (add2->o == IR_ADD && irref_isk(add2->op2) &&
- IR(fright->op2)->i == -IR(add2->op2)->i) {
- IRRef ref = J->chain[IR_ABC];
- IRRef lim = add2->op1;
- if (fins->op1 > lim) lim = fins->op1;
- while (ref > lim) {
- IRIns *ir = IR(ref);
- if (ir->op1 == fins->op1 && ir->op2 == add2->op1)
- return DROPFOLD;
- ref = ir->prev;
- }
- }
- }
- }
- return NEXTFOLD;
- }
- LJFOLD(ABC any KINT)
- LJFOLDF(abc_k)
- {
- if (LJ_LIKELY(J->flags & JIT_F_OPT_ABC)) {
- IRRef ref = J->chain[IR_ABC];
- IRRef asize = fins->op1;
- while (ref > asize) {
- IRIns *ir = IR(ref);
- if (ir->op1 == asize && irref_isk(ir->op2)) {
- int32_t k = IR(ir->op2)->i;
- if (fright->i > k)
- ir->op2 = fins->op2;
- return DROPFOLD;
- }
- ref = ir->prev;
- }
- return EMITFOLD;
- }
- return NEXTFOLD;
- }
- LJFOLD(ABC any any)
- LJFOLDF(abc_invar)
- {
-
- if (!irt_isint(fins->t) && fins->op1 < J->chain[IR_LOOP] &&
- !irt_isphi(IR(fins->op1)->t))
- return DROPFOLD;
- return NEXTFOLD;
- }
- LJFOLD(ADD any any)
- LJFOLD(MUL any any)
- LJFOLD(ADDOV any any)
- LJFOLD(MULOV any any)
- LJFOLDF(comm_swap)
- {
- if (fins->op1 < fins->op2) {
- IRRef1 tmp = fins->op1;
- fins->op1 = fins->op2;
- fins->op2 = tmp;
- return RETRYFOLD;
- }
- return NEXTFOLD;
- }
- LJFOLD(EQ any any)
- LJFOLD(NE any any)
- LJFOLDF(comm_equal)
- {
-
- if (fins->op1 == fins->op2 && !irt_isnum(fins->t))
- return CONDFOLD(fins->o == IR_EQ);
- return fold_comm_swap(J);
- }
- LJFOLD(LT any any)
- LJFOLD(GE any any)
- LJFOLD(LE any any)
- LJFOLD(GT any any)
- LJFOLD(ULT any any)
- LJFOLD(UGE any any)
- LJFOLD(ULE any any)
- LJFOLD(UGT any any)
- LJFOLDF(comm_comp)
- {
-
- if (fins->op1 == fins->op2 && !irt_isnum(fins->t))
- return CONDFOLD((fins->o ^ (fins->o >> 1)) & 1);
- if (fins->op1 < fins->op2) {
- IRRef1 tmp = fins->op1;
- fins->op1 = fins->op2;
- fins->op2 = tmp;
- fins->o ^= 3;
- return RETRYFOLD;
- }
- return NEXTFOLD;
- }
- LJFOLD(BAND any any)
- LJFOLD(BOR any any)
- LJFOLD(MIN any any)
- LJFOLD(MAX any any)
- LJFOLDF(comm_dup)
- {
- if (fins->op1 == fins->op2)
- return LEFTFOLD;
- return fold_comm_swap(J);
- }
- LJFOLD(BXOR any any)
- LJFOLDF(comm_bxor)
- {
- if (fins->op1 == fins->op2)
- return irt_is64(fins->t) ? INT64FOLD(0) : INTFOLD(0);
- return fold_comm_swap(J);
- }
- static TRef kfold_xload(jit_State *J, IRIns *ir, const void *p)
- {
- int32_t k;
- switch (irt_type(ir->t)) {
- 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)lj_getu16(p); break;
- case IRT_U16: k = (int32_t)(uint16_t)lj_getu16(p); break;
- case IRT_INT: case IRT_U32: k = (int32_t)lj_getu32(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);
- }
- LJFOLD(EQ SNEW KGC)
- LJFOLD(NE SNEW KGC)
- LJFOLDF(merge_eqne_snew_kgc)
- {
- GCstr *kstr = ir_kstr(fright);
- int32_t len = (int32_t)kstr->len;
- lua_assert(irt_isstr(fins->t));
- #if LJ_TARGET_UNALIGNED
- #define FOLD_SNEW_MAX_LEN 4
- #define FOLD_SNEW_TYPE8 IRT_I8
- #else
- #define FOLD_SNEW_MAX_LEN 1
- #define FOLD_SNEW_TYPE8 IRT_U8
- #endif
- PHIBARRIER(fleft);
- if (len <= FOLD_SNEW_MAX_LEN) {
- IROp op = (IROp)fins->o;
- IRRef strref = fleft->op1;
- if (IR(strref)->o != IR_STRREF)
- return NEXTFOLD;
- if (op == IR_EQ) {
- emitir(IRTGI(IR_EQ), fleft->op2, lj_ir_kint(J, len));
-
- } else {
-
- if (!irref_isk(fleft->op2))
- return NEXTFOLD;
- if (IR(fleft->op2)->i != len)
- return DROPFOLD;
- }
- if (len > 0) {
-
- uint16_t ot = (uint16_t)(len == 1 ? IRT(IR_XLOAD, FOLD_SNEW_TYPE8) :
- len == 2 ? IRT(IR_XLOAD, IRT_U16) :
- IRTI(IR_XLOAD));
- TRef tmp = emitir(ot, strref,
- IRXLOAD_READONLY | (len > 1 ? IRXLOAD_UNALIGNED : 0));
- 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)));
- fins->op1 = (IRRef1)tmp;
- fins->op2 = (IRRef1)val;
- fins->ot = (IROpT)IRTGI(op);
- return RETRYFOLD;
- } else {
- return DROPFOLD;
- }
- }
- return NEXTFOLD;
- }
- LJFOLD(ALOAD any)
- LJFOLDX(lj_opt_fwd_aload)
- LJFOLD(HLOAD KKPTR)
- LJFOLDF(kfold_hload_kkptr)
- {
- UNUSED(J);
- lua_assert(ir_kptr(fleft) == niltvg(J2G(J)));
- return TREF_NIL;
- }
- LJFOLD(HLOAD any)
- LJFOLDX(lj_opt_fwd_hload)
- LJFOLD(ULOAD any)
- LJFOLDX(lj_opt_fwd_uload)
- LJFOLD(CALLL any IRCALL_lj_tab_len)
- LJFOLDX(lj_opt_fwd_tab_len)
- LJFOLD(UREFO KGC any)
- LJFOLD(UREFC KGC any)
- LJFOLDF(cse_uref)
- {
- if (LJ_LIKELY(J->flags & JIT_F_OPT_CSE)) {
- IRRef ref = J->chain[fins->o];
- GCfunc *fn = ir_kfunc(fleft);
- GCupval *uv = gco2uv(gcref(fn->l.uvptr[(fins->op2 >> 8)]));
- while (ref > 0) {
- IRIns *ir = IR(ref);
- if (irref_isk(ir->op1)) {
- GCfunc *fn2 = ir_kfunc(IR(ir->op1));
- if (gco2uv(gcref(fn2->l.uvptr[(ir->op2 >> 8)])) == uv) {
- if (fins->o == IR_UREFO && gcstep_barrier(J, ref))
- break;
- return ref;
- }
- }
- ref = ir->prev;
- }
- }
- return EMITFOLD;
- }
- LJFOLD(HREFK any any)
- LJFOLDX(lj_opt_fwd_hrefk)
- LJFOLD(HREF TNEW any)
- LJFOLDF(fwd_href_tnew)
- {
- if (lj_opt_fwd_href_nokey(J))
- return lj_ir_kkptr(J, niltvg(J2G(J)));
- return NEXTFOLD;
- }
- LJFOLD(HREF TDUP KPRI)
- LJFOLD(HREF TDUP KGC)
- LJFOLD(HREF TDUP KNUM)
- LJFOLDF(fwd_href_tdup)
- {
- TValue keyv;
- lj_ir_kvalue(J->L, &keyv, fright);
- if (lj_tab_get(J->L, ir_ktab(IR(fleft->op1)), &keyv) == niltvg(J2G(J)) &&
- lj_opt_fwd_href_nokey(J))
- return lj_ir_kkptr(J, niltvg(J2G(J)));
- return NEXTFOLD;
- }
- LJFOLD(FLOAD TNEW IRFL_TAB_ASIZE)
- LJFOLDF(fload_tab_tnew_asize)
- {
- if (LJ_LIKELY(J->flags & JIT_F_OPT_FOLD) && lj_opt_fwd_tptr(J, fins->op1))
- return INTFOLD(fleft->op1);
- return NEXTFOLD;
- }
- LJFOLD(FLOAD TNEW IRFL_TAB_HMASK)
- LJFOLDF(fload_tab_tnew_hmask)
- {
- if (LJ_LIKELY(J->flags & JIT_F_OPT_FOLD) && lj_opt_fwd_tptr(J, fins->op1))
- return INTFOLD((1 << fleft->op2)-1);
- return NEXTFOLD;
- }
- LJFOLD(FLOAD TDUP IRFL_TAB_ASIZE)
- LJFOLDF(fload_tab_tdup_asize)
- {
- if (LJ_LIKELY(J->flags & JIT_F_OPT_FOLD) && lj_opt_fwd_tptr(J, fins->op1))
- return INTFOLD((int32_t)ir_ktab(IR(fleft->op1))->asize);
- return NEXTFOLD;
- }
- LJFOLD(FLOAD TDUP IRFL_TAB_HMASK)
- LJFOLDF(fload_tab_tdup_hmask)
- {
- if (LJ_LIKELY(J->flags & JIT_F_OPT_FOLD) && lj_opt_fwd_tptr(J, fins->op1))
- return INTFOLD((int32_t)ir_ktab(IR(fleft->op1))->hmask);
- return NEXTFOLD;
- }
- LJFOLD(HREF any any)
- LJFOLD(FLOAD any IRFL_TAB_ARRAY)
- LJFOLD(FLOAD any IRFL_TAB_NODE)
- LJFOLD(FLOAD any IRFL_TAB_ASIZE)
- LJFOLD(FLOAD any IRFL_TAB_HMASK)
- LJFOLDF(fload_tab_ah)
- {
- TRef tr = lj_opt_cse(J);
- return lj_opt_fwd_tptr(J, tref_ref(tr)) ? tr : EMITFOLD;
- }
- LJFOLD(FLOAD KGC IRFL_STR_LEN)
- LJFOLDF(fload_str_len_kgc)
- {
- if (LJ_LIKELY(J->flags & JIT_F_OPT_FOLD))
- return INTFOLD((int32_t)ir_kstr(fleft)->len);
- return NEXTFOLD;
- }
- LJFOLD(FLOAD SNEW IRFL_STR_LEN)
- LJFOLDF(fload_str_len_snew)
- {
- if (LJ_LIKELY(J->flags & JIT_F_OPT_FOLD)) {
- PHIBARRIER(fleft);
- return fleft->op2;
- }
- return NEXTFOLD;
- }
- LJFOLD(FLOAD TOSTR IRFL_STR_LEN)
- LJFOLDF(fload_str_len_tostr)
- {
- if (LJ_LIKELY(J->flags & JIT_F_OPT_FOLD) && fleft->op2 == IRTOSTR_CHAR)
- return INTFOLD(1);
- return NEXTFOLD;
- }
- LJFOLD(FLOAD KGC IRFL_CDATA_CTYPEID)
- LJFOLDF(fload_cdata_typeid_kgc)
- {
- if (LJ_LIKELY(J->flags & JIT_F_OPT_FOLD))
- return INTFOLD((int32_t)ir_kcdata(fleft)->ctypeid);
- return NEXTFOLD;
- }
- LJFOLD(FLOAD KGC IRFL_CDATA_PTR)
- LJFOLD(FLOAD KGC IRFL_CDATA_INT)
- LJFOLD(FLOAD KGC IRFL_CDATA_INT64)
- LJFOLDF(fload_cdata_int64_kgc)
- {
- if (LJ_LIKELY(J->flags & JIT_F_OPT_FOLD)) {
- void *p = cdataptr(ir_kcdata(fleft));
- if (irt_is64(fins->t))
- return INT64FOLD(*(uint64_t *)p);
- else
- return INTFOLD(*(int32_t *)p);
- }
- return NEXTFOLD;
- }
- LJFOLD(FLOAD CNEW IRFL_CDATA_CTYPEID)
- LJFOLD(FLOAD CNEWI IRFL_CDATA_CTYPEID)
- LJFOLDF(fload_cdata_typeid_cnew)
- {
- if (LJ_LIKELY(J->flags & JIT_F_OPT_FOLD))
- return fleft->op1;
- return NEXTFOLD;
- }
- LJFOLD(FLOAD CNEWI IRFL_CDATA_PTR)
- LJFOLD(FLOAD CNEWI IRFL_CDATA_INT)
- LJFOLD(FLOAD CNEWI IRFL_CDATA_INT64)
- LJFOLDF(fload_cdata_ptr_int64_cnew)
- {
- if (LJ_LIKELY(J->flags & JIT_F_OPT_FOLD))
- return fleft->op2;
- return NEXTFOLD;
- }
- LJFOLD(FLOAD any IRFL_STR_LEN)
- LJFOLD(FLOAD any IRFL_FUNC_ENV)
- LJFOLD(FLOAD any IRFL_THREAD_ENV)
- LJFOLD(FLOAD any IRFL_CDATA_CTYPEID)
- LJFOLD(FLOAD any IRFL_CDATA_PTR)
- LJFOLD(FLOAD any IRFL_CDATA_INT)
- LJFOLD(FLOAD any IRFL_CDATA_INT64)
- LJFOLD(VLOAD any any)
- LJFOLDX(lj_opt_cse)
- LJFOLD(FLOAD any any)
- LJFOLDX(lj_opt_fwd_fload)
- LJFOLD(SLOAD any any)
- LJFOLDF(fwd_sload)
- {
- if ((fins->op2 & IRSLOAD_FRAME)) {
- TRef tr = lj_opt_cse(J);
- return tref_ref(tr) < J->chain[IR_RETF] ? EMITFOLD : tr;
- } else {
- lua_assert(J->slot[fins->op1] != 0);
- return J->slot[fins->op1];
- }
- }
- LJFOLD(XLOAD KKPTR any)
- LJFOLDF(xload_kptr)
- {
- TRef tr = kfold_xload(J, fins, ir_kptr(fleft));
- return tr ? tr : NEXTFOLD;
- }
- LJFOLD(XLOAD any any)
- LJFOLDX(lj_opt_fwd_xload)
- LJFOLD(TBAR any)
- LJFOLD(OBAR any any)
- LJFOLD(UREFO any any)
- LJFOLDF(barrier_tab)
- {
- TRef tr = lj_opt_cse(J);
- if (gcstep_barrier(J, tref_ref(tr)))
- return EMITFOLD;
- return tr;
- }
- LJFOLD(TBAR TNEW)
- LJFOLD(TBAR TDUP)
- LJFOLDF(barrier_tnew_tdup)
- {
-
- if (fins->op1 < J->chain[IR_LOOP])
- return NEXTFOLD;
- return DROPFOLD;
- }
- LJFOLD(PROF any any)
- LJFOLDF(prof)
- {
- IRRef ref = J->chain[IR_PROF];
- if (ref+1 == J->cur.nins)
- return ref;
- return EMITFOLD;
- }
- LJFOLD(ASTORE any any)
- LJFOLD(HSTORE any any)
- LJFOLDX(lj_opt_dse_ahstore)
- LJFOLD(USTORE any any)
- LJFOLDX(lj_opt_dse_ustore)
- LJFOLD(FSTORE any any)
- LJFOLDX(lj_opt_dse_fstore)
- LJFOLD(XSTORE any any)
- LJFOLDX(lj_opt_dse_xstore)
- LJFOLD(NEWREF any any)
- LJFOLD(CALLA any any)
- LJFOLD(CALLL any any)
- LJFOLD(CALLS any any)
- LJFOLD(CALLXS any any)
- LJFOLD(XBAR)
- LJFOLD(RETF any any)
- LJFOLD(TNEW any any)
- LJFOLD(TDUP any)
- LJFOLD(CNEW any any)
- LJFOLD(XSNEW any any)
- LJFOLD(BUFHDR any any)
- LJFOLDX(lj_ir_emit)
- #include "lj_folddef.h"
- TRef LJ_FASTCALL lj_opt_fold(jit_State *J)
- {
- uint32_t key, any;
- IRRef ref;
- if (LJ_UNLIKELY((J->flags & JIT_F_OPT_MASK) != JIT_F_OPT_DEFAULT)) {
- lua_assert(((JIT_F_OPT_FOLD|JIT_F_OPT_FWD|JIT_F_OPT_CSE|JIT_F_OPT_DSE) |
- JIT_F_OPT_DEFAULT) == JIT_F_OPT_DEFAULT);
-
- if (!(J->flags & JIT_F_OPT_FOLD) && irm_kind(lj_ir_mode[fins->o]) == IRM_N)
- return lj_opt_cse(J);
-
- if ((J->flags & (JIT_F_OPT_FOLD|JIT_F_OPT_FWD|JIT_F_OPT_CSE)) !=
- (JIT_F_OPT_FOLD|JIT_F_OPT_FWD|JIT_F_OPT_CSE) &&
- irm_kind(lj_ir_mode[fins->o]) == IRM_L && fins->o != IR_SLOAD)
- return lj_ir_emit(J);
-
- if ((J->flags & (JIT_F_OPT_FOLD|JIT_F_OPT_DSE)) !=
- (JIT_F_OPT_FOLD|JIT_F_OPT_DSE) &&
- irm_kind(lj_ir_mode[fins->o]) == IRM_S)
- return lj_ir_emit(J);
- }
-
- retry:
-
- key = ((uint32_t)fins->o << 17);
- if (fins->op1 >= J->cur.nk) {
- key += (uint32_t)IR(fins->op1)->o << 10;
- *fleft = *IR(fins->op1);
- }
- if (fins->op2 >= J->cur.nk) {
- key += (uint32_t)IR(fins->op2)->o;
- *fright = *IR(fins->op2);
- } else {
- key += (fins->op2 & 0x3ffu);
- }
-
- any = 0;
- for (;;) {
- uint32_t k = key | (any & 0x1ffff);
- uint32_t h = fold_hashkey(k);
- uint32_t fh = fold_hash[h];
- if ((fh & 0xffffff) == k || (fh = fold_hash[h+1], (fh & 0xffffff) == k)) {
- ref = (IRRef)tref_ref(fold_func[fh >> 24](J));
- if (ref != NEXTFOLD)
- break;
- }
- if (any == 0xfffff)
- return lj_opt_cse(J);
- any = (any | (any >> 10)) ^ 0xffc00;
- }
-
- if (LJ_LIKELY(ref >= MAX_FOLD))
- return TREF(ref, irt_t(IR(ref)->t));
- if (ref == RETRYFOLD)
- goto retry;
- if (ref == KINTFOLD)
- return lj_ir_kint(J, fins->i);
- if (ref == FAILFOLD)
- lj_trace_err(J, LJ_TRERR_GFAIL);
- lua_assert(ref == DROPFOLD);
- return REF_DROP;
- }
- TRef LJ_FASTCALL lj_opt_cse(jit_State *J)
- {
-
- IRRef2 op12 = (IRRef2)fins->op1 + ((IRRef2)fins->op2 << 16);
- IROp op = fins->o;
- if (LJ_LIKELY(J->flags & JIT_F_OPT_CSE)) {
-
- IRRef ref = J->chain[op];
- IRRef lim = fins->op1;
- if (fins->op2 > lim) lim = fins->op2;
- while (ref > lim) {
- if (IR(ref)->op12 == op12)
- return TREF(ref, irt_t(IR(ref)->t));
- ref = IR(ref)->prev;
- }
- }
-
- {
- IRRef ref = lj_ir_nextins(J);
- IRIns *ir = IR(ref);
- ir->prev = J->chain[op];
- ir->op12 = op12;
- J->chain[op] = (IRRef1)ref;
- ir->o = fins->o;
- J->guardemit.irt |= fins->t.irt;
- return TREF(ref, irt_t((ir->t = fins->t)));
- }
- }
- TRef LJ_FASTCALL lj_opt_cselim(jit_State *J, IRRef lim)
- {
- IRRef ref = J->chain[fins->o];
- IRRef2 op12 = (IRRef2)fins->op1 + ((IRRef2)fins->op2 << 16);
- while (ref > lim) {
- if (IR(ref)->op12 == op12)
- return ref;
- ref = IR(ref)->prev;
- }
- return lj_ir_emit(J);
- }
- #undef IR
- #undef fins
- #undef fleft
- #undef fright
- #undef knumleft
- #undef knumright
- #undef emitir
- #endif
One Level Up
Top Level