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); |
