diff options
| author | Mike Pall <mike> | 2010-12-11 21:20:49 +0100 |
|---|---|---|
| committer | Mike Pall <mike> | 2010-12-11 21:20:49 +0100 |
| commit | 42f9b38663bb6ae38a93c27c65ac31f79dc04123 (patch) | |
| tree | ea3a064a3daef538f10e582b98768376a2ffe8f0 /src | |
| parent | 476259e87ee2e7502f92a26e673ba5929226573c (diff) | |
| download | luajit-42f9b38663bb6ae38a93c27c65ac31f79dc04123.tar.gz luajit-42f9b38663bb6ae38a93c27c65ac31f79dc04123.tar.bz2 luajit-42f9b38663bb6ae38a93c27c65ac31f79dc04123.zip | |
Extend all FOLD rules to work on 64 bit integers.
Diffstat (limited to 'src')
| -rw-r--r-- | src/lj_iropt.h | 1 | ||||
| -rw-r--r-- | src/lj_opt_fold.c | 162 |
2 files changed, 131 insertions, 32 deletions
diff --git a/src/lj_iropt.h b/src/lj_iropt.h index f3d243e0..9e7ac9cd 100644 --- a/src/lj_iropt.h +++ b/src/lj_iropt.h | |||
| @@ -105,6 +105,7 @@ enum { | |||
| 105 | }; | 105 | }; |
| 106 | 106 | ||
| 107 | #define INTFOLD(k) ((J->fold.ins.i = (k)), (TRef)KINTFOLD) | 107 | #define INTFOLD(k) ((J->fold.ins.i = (k)), (TRef)KINTFOLD) |
| 108 | #define INT64FOLD(k) (lj_ir_kint64(J, (k))) | ||
| 108 | #define CONDFOLD(cond) ((TRef)FAILFOLD + (TRef)(cond)) | 109 | #define CONDFOLD(cond) ((TRef)FAILFOLD + (TRef)(cond)) |
| 109 | #define LEFTFOLD (J->fold.ins.op1) | 110 | #define LEFTFOLD (J->fold.ins.op1) |
| 110 | #define RIGHTFOLD (J->fold.ins.op2) | 111 | #define RIGHTFOLD (J->fold.ins.op2) |
diff --git a/src/lj_opt_fold.c b/src/lj_opt_fold.c index 74a64533..1b35f2de 100644 --- a/src/lj_opt_fold.c +++ b/src/lj_opt_fold.c | |||
| @@ -291,6 +291,98 @@ LJFOLDF(kfold_intcomp0) | |||
| 291 | return NEXTFOLD; | 291 | return NEXTFOLD; |
| 292 | } | 292 | } |
| 293 | 293 | ||
| 294 | /* -- Constant folding for 64 bit integers -------------------------------- */ | ||
| 295 | |||
| 296 | static uint64_t kfold_int64arith(uint64_t k1, uint64_t k2, IROp op) | ||
| 297 | { | ||
| 298 | switch (op) { | ||
| 299 | case IR_ADD: k1 += k2; break; | ||
| 300 | case IR_SUB: k1 -= k2; break; | ||
| 301 | case IR_MUL: k1 *= k2; break; | ||
| 302 | case IR_BAND: k1 &= k2; break; | ||
| 303 | case IR_BOR: k1 |= k2; break; | ||
| 304 | case IR_BXOR: k1 ^= k2; break; | ||
| 305 | default: lua_assert(0); break; | ||
| 306 | } | ||
| 307 | return k1; | ||
| 308 | } | ||
| 309 | |||
| 310 | LJFOLD(ADD KINT64 KINT64) | ||
| 311 | LJFOLD(SUB KINT64 KINT64) | ||
| 312 | LJFOLD(MUL KINT64 KINT64) | ||
| 313 | LJFOLD(BAND KINT64 KINT64) | ||
| 314 | LJFOLD(BOR KINT64 KINT64) | ||
| 315 | LJFOLD(BXOR KINT64 KINT64) | ||
| 316 | LJFOLDF(kfold_int64arith) | ||
| 317 | { | ||
| 318 | return INT64FOLD(kfold_int64arith(ir_k64(fleft)->u64, | ||
| 319 | ir_k64(fright)->u64, (IROp)fins->o)); | ||
| 320 | } | ||
| 321 | |||
| 322 | LJFOLD(BSHL KINT64 KINT) | ||
| 323 | LJFOLD(BSHR KINT64 KINT) | ||
| 324 | LJFOLD(BSAR KINT64 KINT) | ||
| 325 | LJFOLD(BROL KINT64 KINT) | ||
| 326 | LJFOLD(BROR KINT64 KINT) | ||
| 327 | LJFOLDF(kfold_int64shift) | ||
| 328 | { | ||
| 329 | uint64_t k = ir_k64(fleft)->u64; | ||
| 330 | int32_t sh = (fright->i & 63); | ||
| 331 | switch ((IROp)fins->o) { | ||
| 332 | case IR_BSHL: k <<= sh; break; | ||
| 333 | case IR_BSHR: k >>= sh; break; | ||
| 334 | case IR_BSAR: k = (uint64_t)((int64_t)k >> sh); break; | ||
| 335 | case IR_BROL: k = lj_rol(k, sh); break; | ||
| 336 | case IR_BROR: k = lj_ror(k, sh); break; | ||
| 337 | default: lua_assert(0); break; | ||
| 338 | } | ||
| 339 | return INT64FOLD(k); | ||
| 340 | } | ||
| 341 | |||
| 342 | LJFOLD(BNOT KINT64) | ||
| 343 | LJFOLDF(kfold_bnot64) | ||
| 344 | { | ||
| 345 | return INT64FOLD(~ir_k64(fleft)->u64); | ||
| 346 | } | ||
| 347 | |||
| 348 | LJFOLD(BSWAP KINT64) | ||
| 349 | LJFOLDF(kfold_bswap64) | ||
| 350 | { | ||
| 351 | return INT64FOLD(lj_bswap64(ir_k64(fleft)->u64)); | ||
| 352 | } | ||
| 353 | |||
| 354 | LJFOLD(LT KINT64 KINT) | ||
| 355 | LJFOLD(GE KINT64 KINT) | ||
| 356 | LJFOLD(LE KINT64 KINT) | ||
| 357 | LJFOLD(GT KINT64 KINT) | ||
| 358 | LJFOLD(ULT KINT64 KINT) | ||
| 359 | LJFOLD(UGE KINT64 KINT) | ||
| 360 | LJFOLD(ULE KINT64 KINT) | ||
| 361 | LJFOLD(UGT KINT64 KINT) | ||
| 362 | LJFOLDF(kfold_int64comp) | ||
| 363 | { | ||
| 364 | uint64_t a = ir_k64(fleft)->u64, b = ir_k64(fright)->u64; | ||
| 365 | switch ((IROp)fins->o) { | ||
| 366 | case IR_LT: return CONDFOLD(a < b); | ||
| 367 | case IR_GE: return CONDFOLD(a >= b); | ||
| 368 | case IR_LE: return CONDFOLD(a <= b); | ||
| 369 | case IR_GT: return CONDFOLD(a > b); | ||
| 370 | case IR_ULT: return CONDFOLD((uint64_t)a < (uint64_t)b); | ||
| 371 | case IR_UGE: return CONDFOLD((uint64_t)a >= (uint64_t)b); | ||
| 372 | case IR_ULE: return CONDFOLD((uint64_t)a <= (uint64_t)b); | ||
| 373 | case IR_UGT: return CONDFOLD((uint64_t)a > (uint64_t)b); | ||
| 374 | default: lua_assert(0); return FAILFOLD; | ||
| 375 | } | ||
| 376 | } | ||
| 377 | |||
| 378 | LJFOLD(UGE any KINT64) | ||
| 379 | LJFOLDF(kfold_int64comp0) | ||
| 380 | { | ||
| 381 | if (ir_k64(fright)->u64 == 0) | ||
| 382 | return DROPFOLD; | ||
| 383 | return NEXTFOLD; | ||
| 384 | } | ||
| 385 | |||
| 294 | /* -- Constant folding for strings ---------------------------------------- */ | 386 | /* -- Constant folding for strings ---------------------------------------- */ |
| 295 | 387 | ||
| 296 | LJFOLD(SNEW KPTR KINT) | 388 | LJFOLD(SNEW KPTR KINT) |
| @@ -385,16 +477,16 @@ LJFOLDF(kfold_toi64_kint) | |||
| 385 | { | 477 | { |
| 386 | lua_assert(fins->op2 == IRTOINT_ZEXT64 || fins->op2 == IRTOINT_SEXT64); | 478 | lua_assert(fins->op2 == IRTOINT_ZEXT64 || fins->op2 == IRTOINT_SEXT64); |
| 387 | if (fins->op2 == IRTOINT_ZEXT64) | 479 | if (fins->op2 == IRTOINT_ZEXT64) |
| 388 | return lj_ir_kint64(J, (int64_t)(uint32_t)fleft->i); | 480 | return INT64FOLD((uint64_t)(uint32_t)fleft->i); |
| 389 | else | 481 | else |
| 390 | return lj_ir_kint64(J, (int64_t)(int32_t)fleft->i); | 482 | return INT64FOLD((uint64_t)(int32_t)fleft->i); |
| 391 | } | 483 | } |
| 392 | 484 | ||
| 393 | LJFOLD(TOI64 KNUM any) | 485 | LJFOLD(TOI64 KNUM any) |
| 394 | LJFOLDF(kfold_toi64_knum) | 486 | LJFOLDF(kfold_toi64_knum) |
| 395 | { | 487 | { |
| 396 | lua_assert(fins->op2 == IRTOINT_TRUNCI64); | 488 | lua_assert(fins->op2 == IRTOINT_TRUNCI64); |
| 397 | return lj_ir_kint64(J, (int64_t)knumleft); | 489 | return INT64FOLD((uint64_t)(int64_t)knumleft); |
| 398 | } | 490 | } |
| 399 | 491 | ||
| 400 | LJFOLD(TOSTR KNUM) | 492 | LJFOLD(TOSTR KNUM) |
| @@ -432,6 +524,8 @@ LJFOLD(EQ KNULL any) | |||
| 432 | LJFOLD(NE KNULL any) | 524 | LJFOLD(NE KNULL any) |
| 433 | LJFOLD(EQ KINT KINT) /* Constants are unique, so same refs <==> same value. */ | 525 | LJFOLD(EQ KINT KINT) /* Constants are unique, so same refs <==> same value. */ |
| 434 | LJFOLD(NE KINT KINT) | 526 | LJFOLD(NE KINT KINT) |
| 527 | LJFOLD(EQ KINT64 KINT64) | ||
| 528 | LJFOLD(NE KINT64 KINT64) | ||
| 435 | LJFOLD(EQ KGC KGC) | 529 | LJFOLD(EQ KGC KGC) |
| 436 | LJFOLD(NE KGC KGC) | 530 | LJFOLD(NE KGC KGC) |
| 437 | LJFOLDF(kfold_kref) | 531 | LJFOLDF(kfold_kref) |
| @@ -790,7 +884,7 @@ LJFOLDF(simplify_intmul_k64) | |||
| 790 | 884 | ||
| 791 | { | 885 | { |
| 792 | if (ir_kint64(fright)->u64 == 0) /* i * 0 ==> 0 */ | 886 | if (ir_kint64(fright)->u64 == 0) /* i * 0 ==> 0 */ |
| 793 | return lj_ir_kint64(J, 0); | 887 | return INT64FOLD(0); |
| 794 | else if (ir_kint64(fright)->u64 < 0x80000000u) | 888 | else if (ir_kint64(fright)->u64 < 0x80000000u) |
| 795 | return simplify_intmul_k(J, (int32_t)ir_kint64(fright)->u64); | 889 | return simplify_intmul_k(J, (int32_t)ir_kint64(fright)->u64); |
| 796 | return NEXTFOLD; | 890 | return NEXTFOLD; |
| @@ -893,31 +987,40 @@ LJFOLDF(simplify_intsubaddadd_cancel) | |||
| 893 | } | 987 | } |
| 894 | 988 | ||
| 895 | LJFOLD(BAND any KINT) | 989 | LJFOLD(BAND any KINT) |
| 990 | LJFOLD(BAND any KINT64) | ||
| 896 | LJFOLDF(simplify_band_k) | 991 | LJFOLDF(simplify_band_k) |
| 897 | { | 992 | { |
| 898 | if (fright->i == 0) /* i & 0 ==> 0 */ | 993 | int64_t k = fright->o == IR_KINT ? (int64_t)fright->i : |
| 994 | (int64_t)ir_k64(fright)->u64; | ||
| 995 | if (k == 0) /* i & 0 ==> 0 */ | ||
| 899 | return RIGHTFOLD; | 996 | return RIGHTFOLD; |
| 900 | if (fright->i == -1) /* i & -1 ==> i */ | 997 | if (k == -1) /* i & -1 ==> i */ |
| 901 | return LEFTFOLD; | 998 | return LEFTFOLD; |
| 902 | return NEXTFOLD; | 999 | return NEXTFOLD; |
| 903 | } | 1000 | } |
| 904 | 1001 | ||
| 905 | LJFOLD(BOR any KINT) | 1002 | LJFOLD(BOR any KINT) |
| 1003 | LJFOLD(BOR any KINT64) | ||
| 906 | LJFOLDF(simplify_bor_k) | 1004 | LJFOLDF(simplify_bor_k) |
| 907 | { | 1005 | { |
| 908 | if (fright->i == 0) /* i | 0 ==> i */ | 1006 | int64_t k = fright->o == IR_KINT ? (int64_t)fright->i : |
| 1007 | (int64_t)ir_k64(fright)->u64; | ||
| 1008 | if (k == 0) /* i | 0 ==> i */ | ||
| 909 | return LEFTFOLD; | 1009 | return LEFTFOLD; |
| 910 | if (fright->i == -1) /* i | -1 ==> -1 */ | 1010 | if (k == -1) /* i | -1 ==> -1 */ |
| 911 | return RIGHTFOLD; | 1011 | return RIGHTFOLD; |
| 912 | return NEXTFOLD; | 1012 | return NEXTFOLD; |
| 913 | } | 1013 | } |
| 914 | 1014 | ||
| 915 | LJFOLD(BXOR any KINT) | 1015 | LJFOLD(BXOR any KINT) |
| 1016 | LJFOLD(BXOR any KINT64) | ||
| 916 | LJFOLDF(simplify_bxor_k) | 1017 | LJFOLDF(simplify_bxor_k) |
| 917 | { | 1018 | { |
| 918 | if (fright->i == 0) /* i xor 0 ==> i */ | 1019 | int64_t k = fright->o == IR_KINT ? (int64_t)fright->i : |
| 1020 | (int64_t)ir_k64(fright)->u64; | ||
| 1021 | if (k == 0) /* i xor 0 ==> i */ | ||
| 919 | return LEFTFOLD; | 1022 | return LEFTFOLD; |
| 920 | if (fright->i == -1) { /* i xor -1 ==> ~i */ | 1023 | if (k == -1) { /* i xor -1 ==> ~i */ |
| 921 | fins->o = IR_BNOT; | 1024 | fins->o = IR_BNOT; |
| 922 | fins->op2 = 0; | 1025 | fins->op2 = 0; |
| 923 | return RETRYFOLD; | 1026 | return RETRYFOLD; |
| @@ -976,9 +1079,13 @@ LJFOLDF(simplify_shift_andk) | |||
| 976 | 1079 | ||
| 977 | LJFOLD(BSHL KINT any) | 1080 | LJFOLD(BSHL KINT any) |
| 978 | LJFOLD(BSHR KINT any) | 1081 | LJFOLD(BSHR KINT any) |
| 1082 | LJFOLD(BSHL KINT64 any) | ||
| 1083 | LJFOLD(BSHR KINT64 any) | ||
| 979 | LJFOLDF(simplify_shift1_ki) | 1084 | LJFOLDF(simplify_shift1_ki) |
| 980 | { | 1085 | { |
| 981 | if (fleft->i == 0) /* 0 o i ==> 0 */ | 1086 | int64_t k = fleft->o == IR_KINT ? (int64_t)fleft->i : |
| 1087 | (int64_t)ir_k64(fleft)->u64; | ||
| 1088 | if (k == 0) /* 0 o i ==> 0 */ | ||
| 982 | return LEFTFOLD; | 1089 | return LEFTFOLD; |
| 983 | return NEXTFOLD; | 1090 | return NEXTFOLD; |
| 984 | } | 1091 | } |
| @@ -986,29 +1093,15 @@ LJFOLDF(simplify_shift1_ki) | |||
| 986 | LJFOLD(BSAR KINT any) | 1093 | LJFOLD(BSAR KINT any) |
| 987 | LJFOLD(BROL KINT any) | 1094 | LJFOLD(BROL KINT any) |
| 988 | LJFOLD(BROR KINT any) | 1095 | LJFOLD(BROR KINT any) |
| 989 | LJFOLDF(simplify_shift2_ki) | ||
| 990 | { | ||
| 991 | if (fleft->i == 0 || fleft->i == -1) /* 0 o i ==> 0; -1 o i ==> -1 */ | ||
| 992 | return LEFTFOLD; | ||
| 993 | return NEXTFOLD; | ||
| 994 | } | ||
| 995 | |||
| 996 | LJFOLD(BSHL KINT64 any) | ||
| 997 | LJFOLD(BSHR KINT64 any) | ||
| 998 | LJFOLDF(simplify_shift1_ki64) | ||
| 999 | { | ||
| 1000 | if (ir_kint64(fleft)->u64 == 0) /* 0 o i ==> 0 */ | ||
| 1001 | return LEFTFOLD; | ||
| 1002 | return NEXTFOLD; | ||
| 1003 | } | ||
| 1004 | |||
| 1005 | LJFOLD(BSAR KINT64 any) | 1096 | LJFOLD(BSAR KINT64 any) |
| 1006 | LJFOLD(BROL KINT64 any) | 1097 | LJFOLD(BROL KINT64 any) |
| 1007 | LJFOLD(BROR KINT64 any) | 1098 | LJFOLD(BROR KINT64 any) |
| 1008 | LJFOLDF(simplify_shift2_ki64) | 1099 | LJFOLDF(simplify_shift2_ki) |
| 1009 | { | 1100 | { |
| 1010 | if (ir_kint64(fleft)->u64 == 0 || (int64_t)ir_kint64(fleft)->u64 == -1) | 1101 | int64_t k = fleft->o == IR_KINT ? (int64_t)fleft->i : |
| 1011 | return LEFTFOLD; /* 0 o i ==> 0; -1 o i ==> -1 */ | 1102 | (int64_t)ir_k64(fleft)->u64; |
| 1103 | if (k == 0 || k == -1) /* 0 o i ==> 0; -1 o i ==> -1 */ | ||
| 1104 | return LEFTFOLD; | ||
| 1012 | return NEXTFOLD; | 1105 | return NEXTFOLD; |
| 1013 | } | 1106 | } |
| 1014 | 1107 | ||
| @@ -1035,11 +1128,16 @@ LJFOLDF(reassoc_intarith_k) | |||
| 1035 | } | 1128 | } |
| 1036 | 1129 | ||
| 1037 | LJFOLD(ADD ADD KINT64) | 1130 | LJFOLD(ADD ADD KINT64) |
| 1131 | LJFOLD(MUL MUL KINT64) | ||
| 1132 | LJFOLD(BAND BAND KINT64) | ||
| 1133 | LJFOLD(BOR BOR KINT64) | ||
| 1134 | LJFOLD(BXOR BXOR KINT64) | ||
| 1038 | LJFOLDF(reassoc_intarith_k64) | 1135 | LJFOLDF(reassoc_intarith_k64) |
| 1039 | { | 1136 | { |
| 1040 | IRIns *irk = IR(fleft->op2); | 1137 | IRIns *irk = IR(fleft->op2); |
| 1041 | if (irk->o == IR_KINT64) { | 1138 | if (irk->o == IR_KINT64) { |
| 1042 | uint64_t k = ir_kint64(irk)->u64 + ir_kint64(fright)->u64; | 1139 | uint64_t k = kfold_int64arith(ir_k64(irk)->u64, |
| 1140 | ir_k64(fright)->u64, (IROp)fins->o); | ||
| 1043 | PHIBARRIER(fleft); | 1141 | PHIBARRIER(fleft); |
| 1044 | fins->op1 = fleft->op1; | 1142 | fins->op1 = fleft->op1; |
| 1045 | fins->op2 = (IRRef1)lj_ir_kint64(J, k); | 1143 | fins->op2 = (IRRef1)lj_ir_kint64(J, k); |
| @@ -1085,7 +1183,7 @@ LJFOLDF(reassoc_shift) | |||
| 1085 | int32_t k = (irk->i & mask) + (fright->i & mask); | 1183 | int32_t k = (irk->i & mask) + (fright->i & mask); |
| 1086 | if (k > mask) { /* Combined shift too wide? */ | 1184 | if (k > mask) { /* Combined shift too wide? */ |
| 1087 | if (fins->o == IR_BSHL || fins->o == IR_BSHR) | 1185 | if (fins->o == IR_BSHL || fins->o == IR_BSHR) |
| 1088 | return mask == 31 ? INTFOLD(0) : lj_ir_kint64(J, 0); | 1186 | return mask == 31 ? INTFOLD(0) : INT64FOLD(0); |
| 1089 | else if (fins->o == IR_BSAR) | 1187 | else if (fins->o == IR_BSAR) |
| 1090 | k = mask; | 1188 | k = mask; |
| 1091 | else | 1189 | else |
