diff options
| author | Mike Pall <mike> | 2010-12-11 20:08:07 +0100 |
|---|---|---|
| committer | Mike Pall <mike> | 2010-12-11 20:08:07 +0100 |
| commit | 5f7e9173db0497f2037c31081379cf3b8890830c (patch) | |
| tree | 905b56655d7c668a4acda26347356b9bf3f54fe4 /src | |
| parent | 44101c64e86d5e3835dd11cf7a7b9d3e40ba3171 (diff) | |
| download | luajit-5f7e9173db0497f2037c31081379cf3b8890830c.tar.gz luajit-5f7e9173db0497f2037c31081379cf3b8890830c.tar.bz2 luajit-5f7e9173db0497f2037c31081379cf3b8890830c.zip | |
Regroup FOLD rules for constant folding.
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) |
