summaryrefslogtreecommitdiff
path: root/src/lj_opt_split.c
diff options
context:
space:
mode:
authorMike Pall <mike>2011-02-03 04:13:51 +0100
committerMike Pall <mike>2011-02-03 04:22:27 +0100
commitdf65b8b419c12327254dec0df116c62525aaabad (patch)
treeb4ba6ea2841692123b49b3033420dbb7282cbcd6 /src/lj_opt_split.c
parent1027018b2135caf45057c3d3b3da03ffb0c6add3 (diff)
downloadluajit-df65b8b419c12327254dec0df116c62525aaabad.tar.gz
luajit-df65b8b419c12327254dec0df116c62525aaabad.tar.bz2
luajit-df65b8b419c12327254dec0df116c62525aaabad.zip
FFI: Rename IR_CNEWP to IR_CNEWI and use it to box 64 bit integers.
Generates smaller IR and DCE eliminates many intermediate boxes. Needs allocation sinking to eliminate the boxes kept alive by PHIs.
Diffstat (limited to '')
-rw-r--r--src/lj_opt_split.c50
1 files changed, 31 insertions, 19 deletions
diff --git a/src/lj_opt_split.c b/src/lj_opt_split.c
index f53616b3..90b2b49c 100644
--- a/src/lj_opt_split.c
+++ b/src/lj_opt_split.c
@@ -159,7 +159,8 @@ static void split_ir(jit_State *J)
159 ir->prev = lj_ir_kint(J, (int32_t)tv.u32.lo); 159 ir->prev = lj_ir_kint(J, (int32_t)tv.u32.lo);
160 hisubst[ref] = lj_ir_kint(J, (int32_t)tv.u32.hi); 160 hisubst[ref] = lj_ir_kint(J, (int32_t)tv.u32.hi);
161 } else { 161 } else {
162 ir->prev = (IRRef1)ref; /* Identity substitution for loword. */ 162 ir->prev = ref; /* Identity substitution for loword. */
163 hisubst[ref] = 0;
163 } 164 }
164 } 165 }
165 166
@@ -168,6 +169,7 @@ static void split_ir(jit_State *J)
168 IRIns *ir = &oir[ref]; 169 IRIns *ir = &oir[ref];
169 IRRef nref = lj_ir_nextins(J); 170 IRRef nref = lj_ir_nextins(J);
170 IRIns *nir = IR(nref); 171 IRIns *nir = IR(nref);
172 IRRef hi = 0;
171 173
172 /* Copy-substitute old instruction to new instruction. */ 174 /* Copy-substitute old instruction to new instruction. */
173 nir->op1 = ir->op1 < nk ? ir->op1 : oir[ir->op1].prev; 175 nir->op1 = ir->op1 < nk ? ir->op1 : oir[ir->op1].prev;
@@ -175,10 +177,11 @@ static void split_ir(jit_State *J)
175 ir->prev = nref; /* Loword substitution. */ 177 ir->prev = nref; /* Loword substitution. */
176 nir->o = ir->o; 178 nir->o = ir->o;
177 nir->t.irt = ir->t.irt & ~(IRT_MARK|IRT_ISPHI); 179 nir->t.irt = ir->t.irt & ~(IRT_MARK|IRT_ISPHI);
180 hisubst[ref] = 0;
178 181
179 /* Split 64 bit instructions. */ 182 /* Split 64 bit instructions. */
180 if (irt_isint64(ir->t)) { 183 if (irt_isint64(ir->t)) {
181 IRRef hi = hisubst[ir->op1]; 184 IRRef hiref = hisubst[ir->op1];
182 nir->t.irt = IRT_INT | (nir->t.irt & IRT_GUARD); /* Turn into INT op. */ 185 nir->t.irt = IRT_INT | (nir->t.irt & IRT_GUARD); /* Turn into INT op. */
183 switch (ir->o) { 186 switch (ir->o) {
184 case IR_ADD: 187 case IR_ADD:
@@ -186,13 +189,13 @@ static void split_ir(jit_State *J)
186 /* Use plain op for hiword if loword cannot produce a carry/borrow. */ 189 /* Use plain op for hiword if loword cannot produce a carry/borrow. */
187 if (irref_isk(nir->op2) && IR(nir->op2)->i == 0) { 190 if (irref_isk(nir->op2) && IR(nir->op2)->i == 0) {
188 ir->prev = nir->op1; /* Pass through loword. */ 191 ir->prev = nir->op1; /* Pass through loword. */
189 nir->op1 = hi; nir->op2 = hisubst[ir->op2]; 192 nir->op1 = hiref; nir->op2 = hisubst[ir->op2];
190 hi = nref; 193 hi = nref;
191 break; 194 break;
192 } 195 }
193 /* fallthrough */ 196 /* fallthrough */
194 case IR_NEG: 197 case IR_NEG:
195 hi = split_emit(J, IRTI(IR_HIOP), hi, hisubst[ir->op2]); 198 hi = split_emit(J, IRTI(IR_HIOP), hiref, hisubst[ir->op2]);
196 break; 199 break;
197 case IR_MUL: 200 case IR_MUL:
198 hi = split_call64(J, hisubst, oir, ir, IRCALL_lj_carith_mul64); 201 hi = split_call64(J, hisubst, oir, ir, IRCALL_lj_carith_mul64);
@@ -212,6 +215,13 @@ static void split_ir(jit_State *J)
212 irt_isi64(ir->t) ? IRCALL_lj_carith_powi64 : 215 irt_isi64(ir->t) ? IRCALL_lj_carith_powi64 :
213 IRCALL_lj_carith_powu64); 216 IRCALL_lj_carith_powu64);
214 break; 217 break;
218 case IR_FLOAD:
219 lua_assert(ir->op2 == IRFL_CDATA_INT64);
220 hi = split_emit(J, IRTI(IR_FLOAD), nir->op1, IRFL_CDATA_INT64HI);
221#if LJ_BE
222 ir->prev = hi; hi = nref;
223#endif
224 break;
215 case IR_XLOAD: 225 case IR_XLOAD:
216 hi = split_emit(J, IRTI(IR_XLOAD), split_ptr(J, nir->op1), ir->op2); 226 hi = split_emit(J, IRTI(IR_XLOAD), split_ptr(J, nir->op1), ir->op2);
217#if LJ_BE 227#if LJ_BE
@@ -220,19 +230,18 @@ static void split_ir(jit_State *J)
220 break; 230 break;
221 case IR_XSTORE: 231 case IR_XSTORE:
222#if LJ_LE 232#if LJ_LE
223 hi = hisubst[ir->op2]; 233 hiref = hisubst[ir->op2];
224#else 234#else
225 hi = nir->op2; nir->op2 = hisubst[ir->op2]; 235 hiref = nir->op2; nir->op2 = hisubst[ir->op2];
226#endif 236#endif
227 split_emit(J, IRTI(IR_XSTORE), split_ptr(J, nir->op1), hi); 237 split_emit(J, IRTI(IR_XSTORE), split_ptr(J, nir->op1), hiref);
228 continue; 238 break;
229 case IR_CONV: { /* Conversion to 64 bit integer. Others handled below. */ 239 case IR_CONV: { /* Conversion to 64 bit integer. Others handled below. */
230 IRType st = (IRType)(ir->op2 & IRCONV_SRCMASK); 240 IRType st = (IRType)(ir->op2 & IRCONV_SRCMASK);
231 if (st == IRT_NUM || st == IRT_FLOAT) { /* FP to 64 bit int conv. */ 241 if (st == IRT_NUM || st == IRT_FLOAT) { /* FP to 64 bit int conv. */
232 hi = split_emit(J, IRTI(IR_HIOP), nir->op1, nref); 242 hi = split_emit(J, IRTI(IR_HIOP), nir->op1, nref);
233 } else if (st == IRT_I64 || st == IRT_U64) { /* 64/64 bit cast. */ 243 } else if (st == IRT_I64 || st == IRT_U64) { /* 64/64 bit cast. */
234 /* Drop cast, since assembler doesn't care. */ 244 /* Drop cast, since assembler doesn't care. */
235 hisubst[ref] = hi;
236 goto fwdlo; 245 goto fwdlo;
237 } else if ((ir->op2 & IRCONV_SEXT)) { /* Sign-extend to 64 bit. */ 246 } else if ((ir->op2 & IRCONV_SEXT)) { /* Sign-extend to 64 bit. */
238 IRRef k31 = lj_ir_kint(J, 31); 247 IRRef k31 = lj_ir_kint(J, 31);
@@ -242,27 +251,26 @@ static void split_ir(jit_State *J)
242 nir->op2 = k31; 251 nir->op2 = k31;
243 hi = nref; 252 hi = nref;
244 } else { /* Zero-extend to 64 bit. */ 253 } else { /* Zero-extend to 64 bit. */
245 hisubst[ref] = lj_ir_kint(J, 0); 254 hi = lj_ir_kint(J, 0);
246 goto fwdlo; 255 goto fwdlo;
247 } 256 }
248 break; 257 break;
249 } 258 }
250 case IR_PHI: { 259 case IR_PHI: {
251 IRRef hi2; 260 IRRef hiref2;
252 if ((irref_isk(nir->op1) && irref_isk(nir->op2)) || 261 if ((irref_isk(nir->op1) && irref_isk(nir->op2)) ||
253 nir->op1 == nir->op2) 262 nir->op1 == nir->op2)
254 J->cur.nins--; /* Drop useless PHIs. */ 263 J->cur.nins--; /* Drop useless PHIs. */
255 hi2 = hisubst[ir->op2]; 264 hiref2 = hisubst[ir->op2];
256 if (!((irref_isk(hi) && irref_isk(hi2)) || hi == hi2)) 265 if (!((irref_isk(hiref) && irref_isk(hiref2)) || hiref == hiref2))
257 split_emit(J, IRTI(IR_PHI), hi, hi2); 266 split_emit(J, IRTI(IR_PHI), hiref, hiref2);
258 continue; 267 break;
259 } 268 }
260 default: 269 default:
261 lua_assert(ir->o <= IR_NE); 270 lua_assert(ir->o <= IR_NE); /* Comparisons. */
262 split_emit(J, IRTGI(IR_HIOP), hi, hisubst[ir->op2]); /* Comparisons. */ 271 split_emit(J, IRTGI(IR_HIOP), hiref, hisubst[ir->op2]);
263 continue; 272 break;
264 } 273 }
265 hisubst[ref] = hi; /* Store hiword substitution. */
266 } else if (ir->o == IR_CONV) { /* See above, too. */ 274 } else if (ir->o == IR_CONV) { /* See above, too. */
267 IRType st = (IRType)(ir->op2 & IRCONV_SRCMASK); 275 IRType st = (IRType)(ir->op2 & IRCONV_SRCMASK);
268 if (st == IRT_I64 || st == IRT_U64) { /* Conversion from 64 bit int. */ 276 if (st == IRT_I64 || st == IRT_U64) { /* Conversion from 64 bit int. */
@@ -277,9 +285,13 @@ static void split_ir(jit_State *J)
277 nir->op1 = nir->op2 = 0; 285 nir->op1 = nir->op2 = 0;
278 } 286 }
279 } 287 }
288 } else if (ir->o == IR_CNEWI) {
289 if (hisubst[ir->op2])
290 split_emit(J, IRT(IR_HIOP, IRT_NIL), nref, hisubst[ir->op2]);
280 } else if (ir->o == IR_LOOP) { 291 } else if (ir->o == IR_LOOP) {
281 J->loopref = nref; /* Needed by assembler. */ 292 J->loopref = nref; /* Needed by assembler. */
282 } 293 }
294 hisubst[ref] = hi; /* Store hiword substitution. */
283 } 295 }
284 296
285 /* Add PHI marks. */ 297 /* Add PHI marks. */