diff options
author | Mike Pall <mike> | 2011-11-24 00:42:14 +0100 |
---|---|---|
committer | Mike Pall <mike> | 2011-11-24 00:42:14 +0100 |
commit | 923738459de649ef2369ab48fcc1bfd523168e41 (patch) | |
tree | e4fe9308caddbae44fad09fd921208a0662436c5 /src | |
parent | bd758df76ae7a34a18c6da755b46be1959abeb79 (diff) | |
download | luajit-923738459de649ef2369ab48fcc1bfd523168e41.tar.gz luajit-923738459de649ef2369ab48fcc1bfd523168e41.tar.bz2 luajit-923738459de649ef2369ab48fcc1bfd523168e41.zip |
Do not eliminate PHIs only referenced from other PHIs.
Diffstat (limited to 'src')
-rw-r--r-- | src/lj_opt_loop.c | 54 |
1 files changed, 41 insertions, 13 deletions
diff --git a/src/lj_opt_loop.c b/src/lj_opt_loop.c index c3d115b2..460297b6 100644 --- a/src/lj_opt_loop.c +++ b/src/lj_opt_loop.c | |||
@@ -104,7 +104,7 @@ | |||
104 | static void loop_emit_phi(jit_State *J, IRRef1 *subst, IRRef1 *phi, IRRef nphi, | 104 | static void loop_emit_phi(jit_State *J, IRRef1 *subst, IRRef1 *phi, IRRef nphi, |
105 | SnapNo onsnap) | 105 | SnapNo onsnap) |
106 | { | 106 | { |
107 | int pass2 = 0; | 107 | int passx = 0; |
108 | IRRef i, nslots; | 108 | IRRef i, 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. */ |
@@ -116,16 +116,28 @@ static void loop_emit_phi(jit_State *J, IRRef1 *subst, IRRef1 *phi, IRRef nphi, | |||
116 | } else if (!(IR(rref)->op1 == lref || IR(rref)->op2 == lref)) { | 116 | } else if (!(IR(rref)->op1 == lref || IR(rref)->op2 == lref)) { |
117 | /* Quick check for simple recurrences failed, need pass2. */ | 117 | /* Quick check for simple recurrences failed, need pass2. */ |
118 | irt_setmark(IR(lref)->t); | 118 | irt_setmark(IR(lref)->t); |
119 | pass2 = 1; | 119 | passx = 1; |
120 | } | 120 | } |
121 | } | 121 | } |
122 | /* Pass #2: traverse variant part and clear marks of non-redundant PHIs. */ | 122 | /* Pass #2: traverse variant part and clear marks of non-redundant PHIs. */ |
123 | if (pass2) { | 123 | if (passx) { |
124 | SnapNo s; | 124 | SnapNo s; |
125 | for (i = J->cur.nins-1; i > invar; i--) { | 125 | for (i = J->cur.nins-1; i > invar; i--) { |
126 | IRIns *ir = IR(i); | 126 | IRIns *ir = IR(i); |
127 | if (!irref_isk(ir->op1)) irt_clearmark(IR(ir->op1)->t); | ||
128 | if (!irref_isk(ir->op2)) irt_clearmark(IR(ir->op2)->t); | 127 | if (!irref_isk(ir->op2)) irt_clearmark(IR(ir->op2)->t); |
128 | if (!irref_isk(ir->op1)) { | ||
129 | irt_clearmark(IR(ir->op1)->t); | ||
130 | if (ir->op1 < invar && | ||
131 | ir->o >= IR_CALLN && ir->o <= IR_CARG) { /* ORDER IR */ | ||
132 | ir = IR(ir->op1); | ||
133 | while (ir->o == IR_CARG) { | ||
134 | if (!irref_isk(ir->op2)) irt_clearmark(IR(ir->op2)->t); | ||
135 | if (irref_isk(ir->op1)) break; | ||
136 | ir = IR(ir->op1); | ||
137 | irt_clearmark(ir->t); | ||
138 | } | ||
139 | } | ||
140 | } | ||
129 | } | 141 | } |
130 | for (s = J->cur.nsnap-1; s >= onsnap; s--) { | 142 | for (s = J->cur.nsnap-1; s >= onsnap; s--) { |
131 | SnapShot *snap = &J->cur.snap[s]; | 143 | SnapShot *snap = &J->cur.snap[s]; |
@@ -155,19 +167,35 @@ static void loop_emit_phi(jit_State *J, IRRef1 *subst, IRRef1 *phi, IRRef nphi, | |||
155 | break; | 167 | break; |
156 | } | 168 | } |
157 | } | 169 | } |
158 | /* Pass #4: emit PHI instructions or eliminate PHIs. */ | 170 | /* Pass #4: propagate non-redundant PHIs. */ |
171 | while (passx) { | ||
172 | passx = 0; | ||
173 | for (i = 0; i < nphi; i++) { | ||
174 | IRRef lref = phi[i]; | ||
175 | IRIns *ir = IR(lref); | ||
176 | if (!irt_ismarked(ir->t)) { /* Propagate only from unmarked PHIs. */ | ||
177 | IRRef rref = subst[lref]; | ||
178 | if (lref == rref) { /* Mark redundant PHI. */ | ||
179 | irt_setmark(ir->t); | ||
180 | } else { | ||
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 | } | ||
187 | } | ||
188 | } | ||
189 | } | ||
190 | /* Pass #5: emit PHI instructions or eliminate PHIs. */ | ||
159 | for (i = 0; i < nphi; i++) { | 191 | for (i = 0; i < nphi; i++) { |
160 | IRRef lref = phi[i]; | 192 | IRRef lref = phi[i]; |
161 | IRIns *ir = IR(lref); | 193 | IRIns *ir = IR(lref); |
162 | if (!irt_ismarked(ir->t)) { /* Emit PHI if not marked and not redundant. */ | 194 | if (!irt_ismarked(ir->t)) { /* Emit PHI if not marked. */ |
163 | IRRef rref = subst[lref]; | 195 | IRRef rref = subst[lref]; |
164 | if (lref == rref) { | 196 | if (rref > invar) |
165 | irt_clearphi(ir->t); | 197 | irt_setphi(IR(rref)->t); |
166 | } else { | 198 | emitir_raw(IRT(IR_PHI, irt_type(ir->t)), lref, rref); |
167 | if (rref > invar) | ||
168 | irt_setphi(IR(rref)->t); | ||
169 | emitir_raw(IRT(IR_PHI, irt_type(ir->t)), lref, rref); | ||
170 | } | ||
171 | } else { /* Otherwise eliminate PHI. */ | 199 | } else { /* Otherwise eliminate PHI. */ |
172 | irt_clearmark(ir->t); | 200 | irt_clearmark(ir->t); |
173 | irt_clearphi(ir->t); | 201 | irt_clearphi(ir->t); |