aboutsummaryrefslogtreecommitdiff
path: root/src/lj_opt_fold.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lj_opt_fold.c')
-rw-r--r--src/lj_opt_fold.c47
1 files changed, 38 insertions, 9 deletions
diff --git a/src/lj_opt_fold.c b/src/lj_opt_fold.c
index 743dfb07..ce78505b 100644
--- a/src/lj_opt_fold.c
+++ b/src/lj_opt_fold.c
@@ -2134,8 +2134,26 @@ LJFOLDX(lj_opt_fwd_uload)
2134LJFOLD(ALEN any any) 2134LJFOLD(ALEN any any)
2135LJFOLDX(lj_opt_fwd_alen) 2135LJFOLDX(lj_opt_fwd_alen)
2136 2136
2137/* Try to merge UREFO/UREFC into referenced instruction. */
2138static TRef merge_uref(jit_State *J, IRRef ref, IRIns* ir)
2139{
2140 if (ir->o == IR_UREFO && irt_isguard(ir->t)) {
2141 /* Might be pointing to some other coroutine's stack.
2142 ** And GC might shrink said stack, thereby repointing the upvalue.
2143 ** GC might even collect said coroutine, thereby closing the upvalue.
2144 */
2145 if (gcstep_barrier(J, ref))
2146 return EMITFOLD; /* So cannot merge. */
2147 /* Current fins wants a check, but ir doesn't have one. */
2148 if ((irt_t(fins->t) & (IRT_GUARD|IRT_TYPE)) == (IRT_GUARD|IRT_PGC) &&
2149 irt_type(ir->t) == IRT_IGC)
2150 ir->t.irt += IRT_PGC-IRT_IGC; /* So install a check. */
2151 }
2152 return ref; /* Not a TRef, but the caller doesn't care. */
2153}
2154
2137/* Upvalue refs are really loads, but there are no corresponding stores. 2155/* Upvalue refs are really loads, but there are no corresponding stores.
2138** So CSE is ok for them, except for UREFO across a GC step (see below). 2156** So CSE is ok for them, except for guarded UREFO across a GC step.
2139** If the referenced function is const, its upvalue addresses are const, too. 2157** If the referenced function is const, its upvalue addresses are const, too.
2140** This can be used to improve CSE by looking for the same address, 2158** This can be used to improve CSE by looking for the same address,
2141** even if the upvalues originate from a different function. 2159** even if the upvalues originate from a different function.
@@ -2153,9 +2171,7 @@ LJFOLDF(cse_uref)
2153 if (irref_isk(ir->op1)) { 2171 if (irref_isk(ir->op1)) {
2154 GCfunc *fn2 = ir_kfunc(IR(ir->op1)); 2172 GCfunc *fn2 = ir_kfunc(IR(ir->op1));
2155 if (gco2uv(gcref(fn2->l.uvptr[(ir->op2 >> 8)])) == uv) { 2173 if (gco2uv(gcref(fn2->l.uvptr[(ir->op2 >> 8)])) == uv) {
2156 if (fins->o == IR_UREFO && gcstep_barrier(J, ref)) 2174 return merge_uref(J, ref, ir);
2157 break;
2158 return ref;
2159 } 2175 }
2160 } 2176 }
2161 ref = ir->prev; 2177 ref = ir->prev;
@@ -2164,6 +2180,24 @@ LJFOLDF(cse_uref)
2164 return EMITFOLD; 2180 return EMITFOLD;
2165} 2181}
2166 2182
2183/* Custom CSE for UREFO. */
2184LJFOLD(UREFO any any)
2185LJFOLDF(cse_urefo)
2186{
2187 if (LJ_LIKELY(J->flags & JIT_F_OPT_CSE)) {
2188 IRRef ref = J->chain[IR_UREFO];
2189 IRRef lim = fins->op1;
2190 IRRef2 op12 = (IRRef2)fins->op1 + ((IRRef2)fins->op2 << 16);
2191 while (ref > lim) {
2192 IRIns *ir = IR(ref);
2193 if (ir->op12 == op12)
2194 return merge_uref(J, ref, ir);
2195 ref = ir->prev;
2196 }
2197 }
2198 return EMITFOLD;
2199}
2200
2167LJFOLD(HREFK any any) 2201LJFOLD(HREFK any any)
2168LJFOLDX(lj_opt_fwd_hrefk) 2202LJFOLDX(lj_opt_fwd_hrefk)
2169 2203
@@ -2384,14 +2418,9 @@ LJFOLDF(fold_base)
2384 2418
2385/* Write barriers are amenable to CSE, but not across any incremental 2419/* Write barriers are amenable to CSE, but not across any incremental
2386** GC steps. 2420** GC steps.
2387**
2388** The same logic applies to open upvalue references, because a stack
2389** may be resized during a GC step (not the current stack, but maybe that
2390** of a coroutine).
2391*/ 2421*/
2392LJFOLD(TBAR any) 2422LJFOLD(TBAR any)
2393LJFOLD(OBAR any any) 2423LJFOLD(OBAR any any)
2394LJFOLD(UREFO any any)
2395LJFOLDF(barrier_tab) 2424LJFOLDF(barrier_tab)
2396{ 2425{
2397 TRef tr = lj_opt_cse(J); 2426 TRef tr = lj_opt_cse(J);