aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Pall <mike>2010-09-13 01:23:19 +0200
committerMike Pall <mike>2010-09-13 01:23:19 +0200
commitc88169dc4672faa26d7e0ac9b1bf810a5d0534f4 (patch)
tree8fb9273dadb98ddaa6a667b97491cbb39490b3f4
parent4ba0eb5f8083e95852e15777bfc0da63653f4e19 (diff)
downloadluajit-c88169dc4672faa26d7e0ac9b1bf810a5d0534f4.tar.gz
luajit-c88169dc4672faa26d7e0ac9b1bf810a5d0534f4.tar.bz2
luajit-c88169dc4672faa26d7e0ac9b1bf810a5d0534f4.zip
Record y = select(x, ...) idiom.
-rw-r--r--src/lj_jit.h2
-rw-r--r--src/lj_record.c59
-rw-r--r--src/lj_trace.c1
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. */
1953static 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. */
1953static void rec_varg(jit_State *J, BCReg dst, ptrdiff_t nresults) 1965static 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