diff options
| author | Mike Pall <mike> | 2013-10-26 17:31:23 +0200 |
|---|---|---|
| committer | Mike Pall <mike> | 2013-10-26 17:31:23 +0200 |
| commit | 8944e27762712679e50962598ed1be8dc1fbe7be (patch) | |
| tree | 6274750e290d398e9bc009dc3132c9e57aeb8d6c | |
| parent | 7e538b5f0ae1dfa7667f3a974d570f0cd8190aca (diff) | |
| download | luajit-8944e27762712679e50962598ed1be8dc1fbe7be.tar.gz luajit-8944e27762712679e50962598ed1be8dc1fbe7be.tar.bz2 luajit-8944e27762712679e50962598ed1be8dc1fbe7be.zip | |
Fix handling of redundant PHIs.
| -rw-r--r-- | src/lj_opt_loop.c | 31 |
1 files changed, 15 insertions, 16 deletions
diff --git a/src/lj_opt_loop.c b/src/lj_opt_loop.c index 3a119f47..fa5e03e4 100644 --- a/src/lj_opt_loop.c +++ b/src/lj_opt_loop.c | |||
| @@ -105,20 +105,24 @@ static void loop_emit_phi(jit_State *J, IRRef1 *subst, IRRef1 *phi, IRRef nphi, | |||
| 105 | SnapNo onsnap) | 105 | SnapNo onsnap) |
| 106 | { | 106 | { |
| 107 | int passx = 0; | 107 | int passx = 0; |
| 108 | IRRef i, nslots; | 108 | IRRef i, j, nslots; |
| 109 | IRRef invar = J->chain[IR_LOOP]; | 109 | IRRef invar = J->chain[IR_LOOP]; |
| 110 | /* Pass #1: mark redundant and potentially redundant PHIs. */ | 110 | /* Pass #1: mark redundant and potentially redundant PHIs. */ |
| 111 | for (i = 0; i < nphi; i++) { | 111 | for (i = 0, j = 0; i < nphi; i++) { |
| 112 | IRRef lref = phi[i]; | 112 | IRRef lref = phi[i]; |
| 113 | IRRef rref = subst[lref]; | 113 | IRRef rref = subst[lref]; |
| 114 | if (lref == rref || rref == REF_DROP) { /* Invariants are redundant. */ | 114 | if (lref == rref || rref == REF_DROP) { /* Invariants are redundant. */ |
| 115 | irt_setmark(IR(lref)->t); | 115 | irt_clearphi(IR(lref)->t); |
| 116 | } else if (!(IR(rref)->op1 == lref || IR(rref)->op2 == lref)) { | 116 | } else { |
| 117 | /* Quick check for simple recurrences failed, need pass2. */ | 117 | phi[j++] = (IRRef1)lref; |
| 118 | irt_setmark(IR(lref)->t); | 118 | if (!(IR(rref)->op1 == lref || IR(rref)->op2 == lref)) { |
| 119 | passx = 1; | 119 | /* Quick check for simple recurrences failed, need pass2. */ |
| 120 | irt_setmark(IR(lref)->t); | ||
| 121 | passx = 1; | ||
| 122 | } | ||
| 120 | } | 123 | } |
| 121 | } | 124 | } |
| 125 | nphi = j; | ||
| 122 | /* Pass #2: traverse variant part and clear marks of non-redundant PHIs. */ | 126 | /* Pass #2: traverse variant part and clear marks of non-redundant PHIs. */ |
| 123 | if (passx) { | 127 | if (passx) { |
| 124 | SnapNo s; | 128 | SnapNo s; |
| @@ -174,15 +178,10 @@ static void loop_emit_phi(jit_State *J, IRRef1 *subst, IRRef1 *phi, IRRef nphi, | |||
| 174 | IRRef lref = phi[i]; | 178 | IRRef lref = phi[i]; |
| 175 | IRIns *ir = IR(lref); | 179 | IRIns *ir = IR(lref); |
| 176 | if (!irt_ismarked(ir->t)) { /* Propagate only from unmarked PHIs. */ | 180 | if (!irt_ismarked(ir->t)) { /* Propagate only from unmarked PHIs. */ |
| 177 | IRRef rref = subst[lref]; | 181 | IRIns *irr = IR(subst[lref]); |
| 178 | if (lref == rref) { /* Mark redundant PHI. */ | 182 | if (irt_ismarked(irr->t)) { /* Right ref points to other PHI? */ |
| 179 | irt_setmark(ir->t); | 183 | irt_clearmark(irr->t); /* Mark that PHI as non-redundant. */ |
| 180 | } else { | 184 | passx = 1; /* Retry. */ |
| 181 | IRIns *irr = IR(rref); | ||
| 182 | if (irt_ismarked(irr->t)) { /* Right ref points to other PHI? */ | ||
| 183 | irt_clearmark(irr->t); /* Mark that PHI as non-redundant. */ | ||
| 184 | passx = 1; /* Retry. */ | ||
| 185 | } | ||
| 186 | } | 185 | } |
| 187 | } | 186 | } |
| 188 | } | 187 | } |
