diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/lj_opt_fold.c | 216 |
1 files changed, 112 insertions, 104 deletions
diff --git a/src/lj_opt_fold.c b/src/lj_opt_fold.c index e61a6533..74a64533 100644 --- a/src/lj_opt_fold.c +++ b/src/lj_opt_fold.c | |||
@@ -155,7 +155,7 @@ typedef IRRef (LJ_FASTCALL *FoldFunc)(jit_State *J); | |||
155 | (J->chain[IR_SNEW] || J->chain[IR_TNEW] || J->chain[IR_TDUP] || \ | 155 | (J->chain[IR_SNEW] || J->chain[IR_TNEW] || J->chain[IR_TDUP] || \ |
156 | J->chain[IR_CNEW] || J->chain[IR_CNEWI] || J->chain[IR_TOSTR])) | 156 | J->chain[IR_CNEW] || J->chain[IR_CNEWI] || J->chain[IR_TOSTR])) |
157 | 157 | ||
158 | /* -- Constant folding ---------------------------------------------------- */ | 158 | /* -- Constant folding for FP numbers ------------------------------------- */ |
159 | 159 | ||
160 | LJFOLD(ADD KNUM KNUM) | 160 | LJFOLD(ADD KNUM KNUM) |
161 | LJFOLD(SUB KNUM KNUM) | 161 | LJFOLD(SUB KNUM KNUM) |
@@ -192,6 +192,24 @@ LJFOLDF(kfold_powi) | |||
192 | return lj_ir_knum(J, y); | 192 | return lj_ir_knum(J, y); |
193 | } | 193 | } |
194 | 194 | ||
195 | /* Must not use kfold_kref for numbers (could be NaN). */ | ||
196 | LJFOLD(EQ KNUM KNUM) | ||
197 | LJFOLD(NE KNUM KNUM) | ||
198 | LJFOLD(LT KNUM KNUM) | ||
199 | LJFOLD(GE KNUM KNUM) | ||
200 | LJFOLD(LE KNUM KNUM) | ||
201 | LJFOLD(GT KNUM KNUM) | ||
202 | LJFOLD(ULT KNUM KNUM) | ||
203 | LJFOLD(UGE KNUM KNUM) | ||
204 | LJFOLD(ULE KNUM KNUM) | ||
205 | LJFOLD(UGT KNUM KNUM) | ||
206 | LJFOLDF(kfold_numcomp) | ||
207 | { | ||
208 | return CONDFOLD(lj_ir_numcmp(knumleft, knumright, (IROp)fins->o)); | ||
209 | } | ||
210 | |||
211 | /* -- Constant folding for 32 bit integers -------------------------------- */ | ||
212 | |||
195 | static int32_t kfold_intop(int32_t k1, int32_t k2, IROp op) | 213 | static int32_t kfold_intop(int32_t k1, int32_t k2, IROp op) |
196 | { | 214 | { |
197 | switch (op) { | 215 | switch (op) { |
@@ -239,6 +257,98 @@ LJFOLDF(kfold_bswap) | |||
239 | return INTFOLD((int32_t)lj_bswap((uint32_t)fleft->i)); | 257 | return INTFOLD((int32_t)lj_bswap((uint32_t)fleft->i)); |
240 | } | 258 | } |
241 | 259 | ||
260 | LJFOLD(LT KINT KINT) | ||
261 | LJFOLD(GE KINT KINT) | ||
262 | LJFOLD(LE KINT KINT) | ||
263 | LJFOLD(GT KINT KINT) | ||
264 | LJFOLD(ULT KINT KINT) | ||
265 | LJFOLD(UGE KINT KINT) | ||
266 | LJFOLD(ULE KINT KINT) | ||
267 | LJFOLD(UGT KINT KINT) | ||
268 | LJFOLD(ABC KINT KINT) | ||
269 | LJFOLDF(kfold_intcomp) | ||
270 | { | ||
271 | int32_t a = fleft->i, b = fright->i; | ||
272 | switch ((IROp)fins->o) { | ||
273 | case IR_LT: return CONDFOLD(a < b); | ||
274 | case IR_GE: return CONDFOLD(a >= b); | ||
275 | case IR_LE: return CONDFOLD(a <= b); | ||
276 | case IR_GT: return CONDFOLD(a > b); | ||
277 | case IR_ULT: return CONDFOLD((uint32_t)a < (uint32_t)b); | ||
278 | case IR_UGE: return CONDFOLD((uint32_t)a >= (uint32_t)b); | ||
279 | case IR_ULE: return CONDFOLD((uint32_t)a <= (uint32_t)b); | ||
280 | case IR_ABC: | ||
281 | case IR_UGT: return CONDFOLD((uint32_t)a > (uint32_t)b); | ||
282 | default: lua_assert(0); return FAILFOLD; | ||
283 | } | ||
284 | } | ||
285 | |||
286 | LJFOLD(UGE any KINT) | ||
287 | LJFOLDF(kfold_intcomp0) | ||
288 | { | ||
289 | if (fright->i == 0) | ||
290 | return DROPFOLD; | ||
291 | return NEXTFOLD; | ||
292 | } | ||
293 | |||
294 | /* -- Constant folding for strings ---------------------------------------- */ | ||
295 | |||
296 | LJFOLD(SNEW KPTR KINT) | ||
297 | LJFOLDF(kfold_snew_kptr) | ||
298 | { | ||
299 | GCstr *s = lj_str_new(J->L, (const char *)ir_kptr(fleft), (size_t)fright->i); | ||
300 | return lj_ir_kstr(J, s); | ||
301 | } | ||
302 | |||
303 | LJFOLD(SNEW any KINT) | ||
304 | LJFOLDF(kfold_snew_empty) | ||
305 | { | ||
306 | if (fright->i == 0) | ||
307 | return lj_ir_kstr(J, lj_str_new(J->L, "", 0)); | ||
308 | return NEXTFOLD; | ||
309 | } | ||
310 | |||
311 | LJFOLD(STRREF KGC KINT) | ||
312 | LJFOLDF(kfold_strref) | ||
313 | { | ||
314 | GCstr *str = ir_kstr(fleft); | ||
315 | lua_assert((MSize)fright->i < str->len); | ||
316 | return lj_ir_kptr(J, (char *)strdata(str) + fright->i); | ||
317 | } | ||
318 | |||
319 | LJFOLD(STRREF SNEW any) | ||
320 | LJFOLDF(kfold_strref_snew) | ||
321 | { | ||
322 | PHIBARRIER(fleft); | ||
323 | if (irref_isk(fins->op2) && fright->i == 0) { | ||
324 | return fleft->op1; /* strref(snew(ptr, len), 0) ==> ptr */ | ||
325 | } else { | ||
326 | /* Reassociate: strref(snew(strref(str, a), len), b) ==> strref(str, a+b) */ | ||
327 | IRIns *ir = IR(fleft->op1); | ||
328 | IRRef1 str = ir->op1; /* IRIns * is not valid across emitir. */ | ||
329 | lua_assert(ir->o == IR_STRREF); | ||
330 | PHIBARRIER(ir); | ||
331 | fins->op2 = emitir(IRTI(IR_ADD), ir->op2, fins->op2); /* Clobbers fins! */ | ||
332 | fins->op1 = str; | ||
333 | fins->ot = IRT(IR_STRREF, IRT_P32); | ||
334 | return RETRYFOLD; | ||
335 | } | ||
336 | return NEXTFOLD; | ||
337 | } | ||
338 | |||
339 | LJFOLD(CALLN CARG IRCALL_lj_str_cmp) | ||
340 | LJFOLDF(kfold_strcmp) | ||
341 | { | ||
342 | if (irref_isk(fleft->op1) && irref_isk(fleft->op2)) { | ||
343 | GCstr *a = ir_kstr(IR(fleft->op1)); | ||
344 | GCstr *b = ir_kstr(IR(fleft->op2)); | ||
345 | return INTFOLD(lj_str_cmp(a, b)); | ||
346 | } | ||
347 | return NEXTFOLD; | ||
348 | } | ||
349 | |||
350 | /* -- Constant folding of conversions ------------------------------------- */ | ||
351 | |||
242 | LJFOLD(TONUM KINT) | 352 | LJFOLD(TONUM KINT) |
243 | LJFOLDF(kfold_tonum) | 353 | LJFOLDF(kfold_tonum) |
244 | { | 354 | { |
@@ -308,109 +418,7 @@ LJFOLDF(kfold_strto) | |||
308 | return FAILFOLD; | 418 | return FAILFOLD; |
309 | } | 419 | } |
310 | 420 | ||
311 | LJFOLD(SNEW KPTR KINT) | 421 | /* -- Constant folding of equality checks --------------------------------- */ |
312 | LJFOLDF(kfold_snew_kptr) | ||
313 | { | ||
314 | GCstr *s = lj_str_new(J->L, (const char *)ir_kptr(fleft), (size_t)fright->i); | ||
315 | return lj_ir_kstr(J, s); | ||
316 | } | ||
317 | |||
318 | LJFOLD(SNEW any KINT) | ||
319 | LJFOLDF(kfold_snew_empty) | ||
320 | { | ||
321 | if (fright->i == 0) | ||
322 | return lj_ir_kstr(J, lj_str_new(J->L, "", 0)); | ||
323 | return NEXTFOLD; | ||
324 | } | ||
325 | |||
326 | LJFOLD(STRREF KGC KINT) | ||
327 | LJFOLDF(kfold_strref) | ||
328 | { | ||
329 | GCstr *str = ir_kstr(fleft); | ||
330 | lua_assert((MSize)fright->i < str->len); | ||
331 | return lj_ir_kptr(J, (char *)strdata(str) + fright->i); | ||
332 | } | ||
333 | |||
334 | LJFOLD(STRREF SNEW any) | ||
335 | LJFOLDF(kfold_strref_snew) | ||
336 | { | ||
337 | PHIBARRIER(fleft); | ||
338 | if (irref_isk(fins->op2) && fright->i == 0) { | ||
339 | return fleft->op1; /* strref(snew(ptr, len), 0) ==> ptr */ | ||
340 | } else { | ||
341 | /* Reassociate: strref(snew(strref(str, a), len), b) ==> strref(str, a+b) */ | ||
342 | IRIns *ir = IR(fleft->op1); | ||
343 | IRRef1 str = ir->op1; /* IRIns * is not valid across emitir. */ | ||
344 | lua_assert(ir->o == IR_STRREF); | ||
345 | PHIBARRIER(ir); | ||
346 | fins->op2 = emitir(IRTI(IR_ADD), ir->op2, fins->op2); /* Clobbers fins! */ | ||
347 | fins->op1 = str; | ||
348 | fins->ot = IRT(IR_STRREF, IRT_P32); | ||
349 | return RETRYFOLD; | ||
350 | } | ||
351 | return NEXTFOLD; | ||
352 | } | ||
353 | |||
354 | /* Must not use kfold_kref for numbers (could be NaN). */ | ||
355 | LJFOLD(EQ KNUM KNUM) | ||
356 | LJFOLD(NE KNUM KNUM) | ||
357 | LJFOLD(LT KNUM KNUM) | ||
358 | LJFOLD(GE KNUM KNUM) | ||
359 | LJFOLD(LE KNUM KNUM) | ||
360 | LJFOLD(GT KNUM KNUM) | ||
361 | LJFOLD(ULT KNUM KNUM) | ||
362 | LJFOLD(UGE KNUM KNUM) | ||
363 | LJFOLD(ULE KNUM KNUM) | ||
364 | LJFOLD(UGT KNUM KNUM) | ||
365 | LJFOLDF(kfold_numcomp) | ||
366 | { | ||
367 | return CONDFOLD(lj_ir_numcmp(knumleft, knumright, (IROp)fins->o)); | ||
368 | } | ||
369 | |||
370 | LJFOLD(LT KINT KINT) | ||
371 | LJFOLD(GE KINT KINT) | ||
372 | LJFOLD(LE KINT KINT) | ||
373 | LJFOLD(GT KINT KINT) | ||
374 | LJFOLD(ULT KINT KINT) | ||
375 | LJFOLD(UGE KINT KINT) | ||
376 | LJFOLD(ULE KINT KINT) | ||
377 | LJFOLD(UGT KINT KINT) | ||
378 | LJFOLD(ABC KINT KINT) | ||
379 | LJFOLDF(kfold_intcomp) | ||
380 | { | ||
381 | int32_t a = fleft->i, b = fright->i; | ||
382 | switch ((IROp)fins->o) { | ||
383 | case IR_LT: return CONDFOLD(a < b); | ||
384 | case IR_GE: return CONDFOLD(a >= b); | ||
385 | case IR_LE: return CONDFOLD(a <= b); | ||
386 | case IR_GT: return CONDFOLD(a > b); | ||
387 | case IR_ULT: return CONDFOLD((uint32_t)a < (uint32_t)b); | ||
388 | case IR_UGE: return CONDFOLD((uint32_t)a >= (uint32_t)b); | ||
389 | case IR_ULE: return CONDFOLD((uint32_t)a <= (uint32_t)b); | ||
390 | case IR_ABC: | ||
391 | case IR_UGT: return CONDFOLD((uint32_t)a > (uint32_t)b); | ||
392 | default: lua_assert(0); return FAILFOLD; | ||
393 | } | ||
394 | } | ||
395 | |||
396 | LJFOLD(UGE any KINT) | ||
397 | LJFOLDF(kfold_intcomp0) | ||
398 | { | ||
399 | if (fright->i == 0) | ||
400 | return DROPFOLD; | ||
401 | return NEXTFOLD; | ||
402 | } | ||
403 | |||
404 | LJFOLD(CALLN CARG IRCALL_lj_str_cmp) | ||
405 | LJFOLDF(kfold_strcmp) | ||
406 | { | ||
407 | if (irref_isk(fleft->op1) && irref_isk(fleft->op2)) { | ||
408 | GCstr *a = ir_kstr(IR(fleft->op1)); | ||
409 | GCstr *b = ir_kstr(IR(fleft->op2)); | ||
410 | return INTFOLD(lj_str_cmp(a, b)); | ||
411 | } | ||
412 | return NEXTFOLD; | ||
413 | } | ||
414 | 422 | ||
415 | /* Don't constant-fold away FLOAD checks against KNULL. */ | 423 | /* Don't constant-fold away FLOAD checks against KNULL. */ |
416 | LJFOLD(EQ FLOAD KNULL) | 424 | LJFOLD(EQ FLOAD KNULL) |