aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lj_opt_fold.c216
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
160LJFOLD(ADD KNUM KNUM) 160LJFOLD(ADD KNUM KNUM)
161LJFOLD(SUB KNUM KNUM) 161LJFOLD(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). */
196LJFOLD(EQ KNUM KNUM)
197LJFOLD(NE KNUM KNUM)
198LJFOLD(LT KNUM KNUM)
199LJFOLD(GE KNUM KNUM)
200LJFOLD(LE KNUM KNUM)
201LJFOLD(GT KNUM KNUM)
202LJFOLD(ULT KNUM KNUM)
203LJFOLD(UGE KNUM KNUM)
204LJFOLD(ULE KNUM KNUM)
205LJFOLD(UGT KNUM KNUM)
206LJFOLDF(kfold_numcomp)
207{
208 return CONDFOLD(lj_ir_numcmp(knumleft, knumright, (IROp)fins->o));
209}
210
211/* -- Constant folding for 32 bit integers -------------------------------- */
212
195static int32_t kfold_intop(int32_t k1, int32_t k2, IROp op) 213static 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
260LJFOLD(LT KINT KINT)
261LJFOLD(GE KINT KINT)
262LJFOLD(LE KINT KINT)
263LJFOLD(GT KINT KINT)
264LJFOLD(ULT KINT KINT)
265LJFOLD(UGE KINT KINT)
266LJFOLD(ULE KINT KINT)
267LJFOLD(UGT KINT KINT)
268LJFOLD(ABC KINT KINT)
269LJFOLDF(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
286LJFOLD(UGE any KINT)
287LJFOLDF(kfold_intcomp0)
288{
289 if (fright->i == 0)
290 return DROPFOLD;
291 return NEXTFOLD;
292}
293
294/* -- Constant folding for strings ---------------------------------------- */
295
296LJFOLD(SNEW KPTR KINT)
297LJFOLDF(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
303LJFOLD(SNEW any KINT)
304LJFOLDF(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
311LJFOLD(STRREF KGC KINT)
312LJFOLDF(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
319LJFOLD(STRREF SNEW any)
320LJFOLDF(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
339LJFOLD(CALLN CARG IRCALL_lj_str_cmp)
340LJFOLDF(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
242LJFOLD(TONUM KINT) 352LJFOLD(TONUM KINT)
243LJFOLDF(kfold_tonum) 353LJFOLDF(kfold_tonum)
244{ 354{
@@ -308,109 +418,7 @@ LJFOLDF(kfold_strto)
308 return FAILFOLD; 418 return FAILFOLD;
309} 419}
310 420
311LJFOLD(SNEW KPTR KINT) 421/* -- Constant folding of equality checks --------------------------------- */
312LJFOLDF(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
318LJFOLD(SNEW any KINT)
319LJFOLDF(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
326LJFOLD(STRREF KGC KINT)
327LJFOLDF(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
334LJFOLD(STRREF SNEW any)
335LJFOLDF(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). */
355LJFOLD(EQ KNUM KNUM)
356LJFOLD(NE KNUM KNUM)
357LJFOLD(LT KNUM KNUM)
358LJFOLD(GE KNUM KNUM)
359LJFOLD(LE KNUM KNUM)
360LJFOLD(GT KNUM KNUM)
361LJFOLD(ULT KNUM KNUM)
362LJFOLD(UGE KNUM KNUM)
363LJFOLD(ULE KNUM KNUM)
364LJFOLD(UGT KNUM KNUM)
365LJFOLDF(kfold_numcomp)
366{
367 return CONDFOLD(lj_ir_numcmp(knumleft, knumright, (IROp)fins->o));
368}
369
370LJFOLD(LT KINT KINT)
371LJFOLD(GE KINT KINT)
372LJFOLD(LE KINT KINT)
373LJFOLD(GT KINT KINT)
374LJFOLD(ULT KINT KINT)
375LJFOLD(UGE KINT KINT)
376LJFOLD(ULE KINT KINT)
377LJFOLD(UGT KINT KINT)
378LJFOLD(ABC KINT KINT)
379LJFOLDF(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
396LJFOLD(UGE any KINT)
397LJFOLDF(kfold_intcomp0)
398{
399 if (fright->i == 0)
400 return DROPFOLD;
401 return NEXTFOLD;
402}
403
404LJFOLD(CALLN CARG IRCALL_lj_str_cmp)
405LJFOLDF(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. */
416LJFOLD(EQ FLOAD KNULL) 424LJFOLD(EQ FLOAD KNULL)