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 | |
parent | 4ba0eb5f8083e95852e15777bfc0da63653f4e19 (diff) | |
download | luajit-c88169dc4672faa26d7e0ac9b1bf810a5d0534f4.tar.gz luajit-c88169dc4672faa26d7e0ac9b1bf810a5d0534f4.tar.bz2 luajit-c88169dc4672faa26d7e0ac9b1bf810a5d0534f4.zip |
Record y = select(x, ...) idiom.
-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 | ||