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 /src/lj_opt_loop.c | |
parent | 7e538b5f0ae1dfa7667f3a974d570f0cd8190aca (diff) | |
download | luajit-8944e27762712679e50962598ed1be8dc1fbe7be.tar.gz luajit-8944e27762712679e50962598ed1be8dc1fbe7be.tar.bz2 luajit-8944e27762712679e50962598ed1be8dc1fbe7be.zip |
Fix handling of redundant PHIs.
Diffstat (limited to 'src/lj_opt_loop.c')
-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 | } |