Limit work done in SINK pass.

Reported by XmiliaH.
master
Mike Pall 2022-01-13 15:13:59 +01:00
parent c8bcf1e5fb
commit a01602a826
1 changed files with 12 additions and 4 deletions

View File

@ -36,12 +36,14 @@ static IRIns *sink_checkalloc(jit_State *J, IRIns *irs)
} }
/* Recursively check whether a value depends on a PHI. */ /* 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); IRIns *ir = IR(ref);
if (!*workp) return 1; /* Give up and pretend it does. */
(*workp)--;
if (irt_isphi(ir->t)) return 1; if (irt_isphi(ir->t)) return 1;
if (ir->op1 >= REF_FIRST && sink_phidep(J, ir->op1)) 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)) return 1; if (ir->op2 >= REF_FIRST && sink_phidep(J, ir->op2, workp)) return 1;
return 0; return 0;
} }
@ -56,7 +58,13 @@ static int sink_checkphi(jit_State *J, IRIns *ira, IRRef ref)
return 1; /* Sinkable PHI. */ return 1; /* Sinkable PHI. */
} }
/* Otherwise the value must be loop-invariant. */ /* 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). */ return 1; /* Constant (non-PHI). */
} }