diff options
Diffstat (limited to 'src/lj_opt_fold.c')
-rw-r--r-- | src/lj_opt_fold.c | 67 |
1 files changed, 53 insertions, 14 deletions
diff --git a/src/lj_opt_fold.c b/src/lj_opt_fold.c index a85b49bc..5eeffae3 100644 --- a/src/lj_opt_fold.c +++ b/src/lj_opt_fold.c | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | ** FOLD: Constant Folding, Algebraic Simplifications and Reassociation. | 2 | ** FOLD: Constant Folding, Algebraic Simplifications and Reassociation. |
3 | ** ABCelim: Array Bounds Check Elimination. | ||
3 | ** CSE: Common-Subexpression Elimination. | 4 | ** CSE: Common-Subexpression Elimination. |
4 | ** Copyright (C) 2005-2010 Mike Pall. See Copyright Notice in luajit.h | 5 | ** Copyright (C) 2005-2010 Mike Pall. See Copyright Notice in luajit.h |
5 | */ | 6 | */ |
@@ -949,31 +950,69 @@ LJFOLDF(reassoc_minmax_right) | |||
949 | return NEXTFOLD; | 950 | return NEXTFOLD; |
950 | } | 951 | } |
951 | 952 | ||
953 | /* -- Array bounds check elimination -------------------------------------- */ | ||
954 | |||
952 | /* Eliminate ABC across PHIs to handle t[i-1] forwarding case. | 955 | /* Eliminate ABC across PHIs to handle t[i-1] forwarding case. |
953 | ** ABC(asize, (i+k)+(-k)) ==> ABC(asize, i), but only if it already exists. | 956 | ** ABC(asize, (i+k)+(-k)) ==> ABC(asize, i), but only if it already exists. |
954 | ** Could be generalized to (i+k1)+k2 ==> i+(k1+k2), but needs better disambig. | 957 | ** Could be generalized to (i+k1)+k2 ==> i+(k1+k2), but needs better disambig. |
955 | */ | 958 | */ |
956 | LJFOLD(ABC any ADD) | 959 | LJFOLD(ABC any ADD) |
957 | LJFOLDF(reassoc_abc) | 960 | LJFOLDF(abc_fwd) |
958 | { | 961 | { |
959 | if (irref_isk(fright->op2)) { | 962 | if (LJ_LIKELY(J->flags & JIT_F_OPT_ABC)) { |
960 | IRIns *add2 = IR(fright->op1); | 963 | if (irref_isk(fright->op2)) { |
961 | if (add2->o == IR_ADD && irref_isk(add2->op2) && | 964 | IRIns *add2 = IR(fright->op1); |
962 | IR(fright->op2)->i == -IR(add2->op2)->i) { | 965 | if (add2->o == IR_ADD && irref_isk(add2->op2) && |
963 | IRRef ref = J->chain[IR_ABC]; | 966 | IR(fright->op2)->i == -IR(add2->op2)->i) { |
964 | IRRef lim = add2->op1; | 967 | IRRef ref = J->chain[IR_ABC]; |
965 | if (fins->op1 > lim) lim = fins->op1; | 968 | IRRef lim = add2->op1; |
966 | while (ref > lim) { | 969 | if (fins->op1 > lim) lim = fins->op1; |
967 | IRIns *ir = IR(ref); | 970 | while (ref > lim) { |
968 | if (ir->op1 == fins->op1 && ir->op2 == add2->op1) | 971 | IRIns *ir = IR(ref); |
969 | return DROPFOLD; | 972 | if (ir->op1 == fins->op1 && ir->op2 == add2->op1) |
970 | ref = ir->prev; | 973 | return DROPFOLD; |
974 | ref = ir->prev; | ||
975 | } | ||
971 | } | 976 | } |
972 | } | 977 | } |
973 | } | 978 | } |
974 | return NEXTFOLD; | 979 | return NEXTFOLD; |
975 | } | 980 | } |
976 | 981 | ||
982 | /* Eliminate ABC for constants. | ||
983 | ** ABC(asize, k1), ABC(asize k2) ==> ABC(asize, max(k1, k2)) | ||
984 | ** Drop second ABC if k2 is lower. Otherwise patch first ABC with k2. | ||
985 | */ | ||
986 | LJFOLD(ABC any KINT) | ||
987 | LJFOLDF(abc_k) | ||
988 | { | ||
989 | if (LJ_LIKELY(J->flags & JIT_F_OPT_ABC)) { | ||
990 | IRRef ref = J->chain[IR_ABC]; | ||
991 | IRRef asize = fins->op1; | ||
992 | while (ref > asize) { | ||
993 | IRIns *ir = IR(ref); | ||
994 | if (ir->op1 == asize && irref_isk(ir->op2)) { | ||
995 | int32_t k = IR(ir->op2)->i; | ||
996 | if (fright->i > k) | ||
997 | ir->op2 = fins->op2; | ||
998 | return DROPFOLD; | ||
999 | } | ||
1000 | ref = ir->prev; | ||
1001 | } | ||
1002 | return EMITFOLD; /* Already performed CSE. */ | ||
1003 | } | ||
1004 | return NEXTFOLD; | ||
1005 | } | ||
1006 | |||
1007 | /* Eliminate invariant ABC inside loop. */ | ||
1008 | LJFOLD(ABC any any) | ||
1009 | LJFOLDF(abc_invar) | ||
1010 | { | ||
1011 | if (!irt_isint(fins->t) && J->chain[IR_LOOP]) /* Currently marked as PTR. */ | ||
1012 | return DROPFOLD; | ||
1013 | return NEXTFOLD; | ||
1014 | } | ||
1015 | |||
977 | /* -- Commutativity ------------------------------------------------------- */ | 1016 | /* -- Commutativity ------------------------------------------------------- */ |
978 | 1017 | ||
979 | /* The refs of commutative ops are canonicalized. Lower refs go to the right. | 1018 | /* The refs of commutative ops are canonicalized. Lower refs go to the right. |