summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Pall <mike>2022-01-13 15:13:59 +0100
committerMike Pall <mike>2022-01-13 15:13:59 +0100
commita01602a826c4187432f404f6a5a112f75fe914ff (patch)
tree0547a295ad0a8995cce80a9950c2b0b051383598
parentc8bcf1e5fb8eb72c7e35604fdfd27bba512761bb (diff)
downloadluajit2-a01602a826c4187432f404f6a5a112f75fe914ff.tar.gz
Limit work done in SINK pass.
Reported by XmiliaH.
-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)
}
/* Recursively check whether a value depends on a PHI. */
-static int sink_phidep(jit_State *J, IRRef ref)
+static int sink_phidep(jit_State *J, IRRef ref, int *workp)
{
IRIns *ir = IR(ref);
+ if (!*workp) return 1; /* Give up and pretend it does. */
+ (*workp)--;
if (irt_isphi(ir->t)) return 1;
- if (ir->op1 >= REF_FIRST && sink_phidep(J, ir->op1)) return 1;
- if (ir->op2 >= REF_FIRST && sink_phidep(J, ir->op2)) return 1;
+ if (ir->op1 >= REF_FIRST && sink_phidep(J, ir->op1, workp)) return 1;
+ if (ir->op2 >= REF_FIRST && sink_phidep(J, ir->op2, workp)) return 1;
return 0;
}
@@ -56,7 +58,13 @@ static int sink_checkphi(jit_State *J, IRIns *ira, IRRef ref)
return 1; /* Sinkable PHI. */
}
/* Otherwise the value must be loop-invariant. */
- return ref < J->loopref && !sink_phidep(J, ref);
+ if (ref < J->loopref) {
+ /* Check for PHI dependencies, but give up after reasonable effort. */
+ int work = 64;
+ return !sink_phidep(J, ref, &work);
+ } else {
+ return 0; /* Loop-variant. */
+ }
}
return 1; /* Constant (non-PHI). */
}