aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lj_opt_sink.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/src/lj_opt_sink.c b/src/lj_opt_sink.c
index 9af35bea..f5542a47 100644
--- a/src/lj_opt_sink.c
+++ b/src/lj_opt_sink.c
@@ -36,12 +36,14 @@ static IRIns *sink_checkalloc(jit_State *J, IRIns *irs)
36} 36}
37 37
38/* Recursively check whether a value depends on a PHI. */ 38/* Recursively check whether a value depends on a PHI. */
39static int sink_phidep(jit_State *J, IRRef ref) 39static int sink_phidep(jit_State *J, IRRef ref, int *workp)
40{ 40{
41 IRIns *ir = IR(ref); 41 IRIns *ir = IR(ref);
42 if (!*workp) return 1; /* Give up and pretend it does. */
43 (*workp)--;
42 if (irt_isphi(ir->t)) return 1; 44 if (irt_isphi(ir->t)) return 1;
43 if (ir->op1 >= REF_FIRST && sink_phidep(J, ir->op1)) return 1; 45 if (ir->op1 >= REF_FIRST && sink_phidep(J, ir->op1, workp)) return 1;
44 if (ir->op2 >= REF_FIRST && sink_phidep(J, ir->op2)) return 1; 46 if (ir->op2 >= REF_FIRST && sink_phidep(J, ir->op2, workp)) return 1;
45 return 0; 47 return 0;
46} 48}
47 49
@@ -56,7 +58,13 @@ static int sink_checkphi(jit_State *J, IRIns *ira, IRRef ref)
56 return 1; /* Sinkable PHI. */ 58 return 1; /* Sinkable PHI. */
57 } 59 }
58 /* Otherwise the value must be loop-invariant. */ 60 /* Otherwise the value must be loop-invariant. */
59 return ref < J->loopref && !sink_phidep(J, ref); 61 if (ref < J->loopref) {
62 /* Check for PHI dependencies, but give up after reasonable effort. */
63 int work = 64;
64 return !sink_phidep(J, ref, &work);
65 } else {
66 return 0; /* Loop-variant. */
67 }
60 } 68 }
61 return 1; /* Constant (non-PHI). */ 69 return 1; /* Constant (non-PHI). */
62} 70}