diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/lj_opt_sink.c | 16 |
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. */ |
| 39 | static int sink_phidep(jit_State *J, IRRef ref) | 39 | static 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 | } |
