diff options
| author | Mike Pall <mike> | 2010-09-13 01:23:19 +0200 |
|---|---|---|
| committer | Mike Pall <mike> | 2010-09-13 01:23:19 +0200 |
| commit | c88169dc4672faa26d7e0ac9b1bf810a5d0534f4 (patch) | |
| tree | 8fb9273dadb98ddaa6a667b97491cbb39490b3f4 /src | |
| parent | 4ba0eb5f8083e95852e15777bfc0da63653f4e19 (diff) | |
| download | luajit-c88169dc4672faa26d7e0ac9b1bf810a5d0534f4.tar.gz luajit-c88169dc4672faa26d7e0ac9b1bf810a5d0534f4.tar.bz2 luajit-c88169dc4672faa26d7e0ac9b1bf810a5d0534f4.zip | |
Record y = select(x, ...) idiom.
Diffstat (limited to 'src')
| -rw-r--r-- | src/lj_jit.h | 2 | ||||
| -rw-r--r-- | src/lj_record.c | 59 | ||||
| -rw-r--r-- | src/lj_trace.c | 1 |
3 files changed, 61 insertions, 1 deletions
diff --git a/src/lj_jit.h b/src/lj_jit.h index be85ecfe..c405ece9 100644 --- a/src/lj_jit.h +++ b/src/lj_jit.h | |||
| @@ -256,7 +256,7 @@ typedef struct jit_State { | |||
| 256 | uint8_t mergesnap; /* Allowed to merge with next snapshot. */ | 256 | uint8_t mergesnap; /* Allowed to merge with next snapshot. */ |
| 257 | uint8_t needsnap; /* Need snapshot before recording next bytecode. */ | 257 | uint8_t needsnap; /* Need snapshot before recording next bytecode. */ |
| 258 | IRType1 guardemit; /* Accumulated IRT_GUARD for emitted instructions. */ | 258 | IRType1 guardemit; /* Accumulated IRT_GUARD for emitted instructions. */ |
| 259 | uint8_t unused1; | 259 | uint8_t bcskip; /* Number of bytecode instructions to skip. */ |
| 260 | 260 | ||
| 261 | FoldState fold; /* Fold state. */ | 261 | FoldState fold; /* Fold state. */ |
| 262 | 262 | ||
diff --git a/src/lj_record.c b/src/lj_record.c index 5c998adf..e283d1e5 100644 --- a/src/lj_record.c +++ b/src/lj_record.c | |||
| @@ -1949,6 +1949,18 @@ static void rec_func_jit(jit_State *J, TraceNo lnk) | |||
| 1949 | 1949 | ||
| 1950 | /* -- Vararg handling ----------------------------------------------------- */ | 1950 | /* -- Vararg handling ----------------------------------------------------- */ |
| 1951 | 1951 | ||
| 1952 | /* Detect y = select(x, ...) idiom. */ | ||
| 1953 | static int select_detect(jit_State *J) | ||
| 1954 | { | ||
| 1955 | BCIns ins = J->pc[1]; | ||
| 1956 | if (bc_op(ins) == BC_CALLM && bc_b(ins) == 2 && bc_c(ins) == 1) { | ||
| 1957 | cTValue *func = &J->L->base[bc_a(ins)]; | ||
| 1958 | if (tvisfunc(func) && funcV(func)->c.ffid == FF_select) | ||
| 1959 | return 1; | ||
| 1960 | } | ||
| 1961 | return 0; | ||
| 1962 | } | ||
| 1963 | |||
| 1952 | /* Record vararg instruction. */ | 1964 | /* Record vararg instruction. */ |
| 1953 | static void rec_varg(jit_State *J, BCReg dst, ptrdiff_t nresults) | 1965 | static void rec_varg(jit_State *J, BCReg dst, ptrdiff_t nresults) |
| 1954 | { | 1966 | { |
| @@ -1997,7 +2009,48 @@ static void rec_varg(jit_State *J, BCReg dst, ptrdiff_t nresults) | |||
| 1997 | J->base[dst+i] = TREF_NIL; | 2009 | J->base[dst+i] = TREF_NIL; |
| 1998 | if (dst + (BCReg)nresults > J->maxslot) | 2010 | if (dst + (BCReg)nresults > J->maxslot) |
| 1999 | J->maxslot = dst + (BCReg)nresults; | 2011 | J->maxslot = dst + (BCReg)nresults; |
| 2012 | } else if (select_detect(J)) { /* y = select(x, ...) */ | ||
| 2013 | TRef tridx = J->base[dst-1]; | ||
| 2014 | TRef tr = TREF_NIL; | ||
| 2015 | ptrdiff_t idx = select_mode(J, tridx, &J->L->base[dst-1]); | ||
| 2016 | if (idx < 0) goto nyivarg; | ||
| 2017 | if (idx != 0 && tref_isk(tridx)) { | ||
| 2018 | emitir(IRTGI(idx <= nvararg ? IR_GE : IR_LT), | ||
| 2019 | fr, lj_ir_kint(J, frofs+8*(int32_t)idx)); | ||
| 2020 | frofs -= 8; /* Bias for 1-based index. */ | ||
| 2021 | } else if (idx <= nvararg) { /* Compute size. */ | ||
| 2022 | TRef tmp = emitir(IRTI(IR_ADD), fr, lj_ir_kint(J, -frofs)); | ||
| 2023 | if (numparams) | ||
| 2024 | emitir(IRTGI(IR_GE), tmp, lj_ir_kint(J, 0)); | ||
| 2025 | tr = emitir(IRTI(IR_BSHR), tmp, lj_ir_kint(J, 3)); | ||
| 2026 | if (idx != 0) { | ||
| 2027 | tridx = emitir(IRTI(IR_ADD), tridx, lj_ir_kint(J, -1)); | ||
| 2028 | rec_idx_abc(J, tr, tridx, (uint32_t)nvararg); | ||
| 2029 | } | ||
| 2030 | } else { | ||
| 2031 | TRef tmp = lj_ir_kint(J, frofs); | ||
| 2032 | if (idx != 0) { | ||
| 2033 | TRef tmp2 = emitir(IRTI(IR_BSHL), tridx, lj_ir_kint(J, 3)); | ||
| 2034 | tmp = emitir(IRTI(IR_ADD), tmp2, tmp); | ||
| 2035 | } else { | ||
| 2036 | tr = lj_ir_kint(J, 0); | ||
| 2037 | } | ||
| 2038 | emitir(IRTGI(IR_LT), fr, tmp); | ||
| 2039 | } | ||
| 2040 | if (idx != 0 && idx <= nvararg) { | ||
| 2041 | IRType t; | ||
| 2042 | TRef aref, vbase = emitir(IRTI(IR_SUB), REF_BASE, fr); | ||
| 2043 | vbase = emitir(IRT(IR_ADD, IRT_PTR), vbase, lj_ir_kint(J, frofs-8)); | ||
| 2044 | t = itype2irt(&J->L->base[idx-2-nvararg]); | ||
| 2045 | aref = emitir(IRT(IR_AREF, IRT_PTR), vbase, tridx); | ||
| 2046 | tr = emitir(IRTG(IR_ALOAD, t), aref, 0); | ||
| 2047 | if (irtype_ispri(t)) tr = TREF_PRI(t); /* Canonicalize primitives. */ | ||
| 2048 | } | ||
| 2049 | J->base[dst-2] = tr; | ||
| 2050 | J->maxslot = dst-1; | ||
| 2051 | J->bcskip = 2; /* Skip CALLM + select. */ | ||
| 2000 | } else { | 2052 | } else { |
| 2053 | nyivarg: | ||
| 2001 | setintV(&J->errinfo, BC_VARG); | 2054 | setintV(&J->errinfo, BC_VARG); |
| 2002 | lj_trace_err_info(J, LJ_TRERR_NYIBC); | 2055 | lj_trace_err_info(J, LJ_TRERR_NYIBC); |
| 2003 | } | 2056 | } |
| @@ -2058,6 +2111,12 @@ void lj_record_ins(jit_State *J) | |||
| 2058 | J->mergesnap = 1; | 2111 | J->mergesnap = 1; |
| 2059 | } | 2112 | } |
| 2060 | 2113 | ||
| 2114 | /* Skip some bytecodes. */ | ||
| 2115 | if (LJ_UNLIKELY(J->bcskip > 0)) { | ||
| 2116 | J->bcskip--; | ||
| 2117 | return; | ||
| 2118 | } | ||
| 2119 | |||
| 2061 | /* Record only closed loops for root traces. */ | 2120 | /* Record only closed loops for root traces. */ |
| 2062 | pc = J->pc; | 2121 | pc = J->pc; |
| 2063 | if (J->framedepth == 0 && | 2122 | if (J->framedepth == 0 && |
diff --git a/src/lj_trace.c b/src/lj_trace.c index fc531a19..8589a9e9 100644 --- a/src/lj_trace.c +++ b/src/lj_trace.c | |||
| @@ -386,6 +386,7 @@ static void trace_start(jit_State *J) | |||
| 386 | J->cur.snapmap = J->snapmapbuf; | 386 | J->cur.snapmap = J->snapmapbuf; |
| 387 | J->mergesnap = 0; | 387 | J->mergesnap = 0; |
| 388 | J->needsnap = 0; | 388 | J->needsnap = 0; |
| 389 | J->bcskip = 0; | ||
| 389 | J->guardemit.irt = 0; | 390 | J->guardemit.irt = 0; |
| 390 | setgcref(J->cur.startpt, obj2gco(J->pt)); | 391 | setgcref(J->cur.startpt, obj2gco(J->pt)); |
| 391 | 392 | ||
