summaryrefslogtreecommitdiff
path: root/src/lj_opt_loop.c
diff options
context:
space:
mode:
authorMike Pall <mike>2013-10-26 17:31:23 +0200
committerMike Pall <mike>2013-10-26 17:31:23 +0200
commit8944e27762712679e50962598ed1be8dc1fbe7be (patch)
tree6274750e290d398e9bc009dc3132c9e57aeb8d6c /src/lj_opt_loop.c
parent7e538b5f0ae1dfa7667f3a974d570f0cd8190aca (diff)
downloadluajit-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.c31
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 }