summaryrefslogtreecommitdiff
path: root/src/lj_opt_fold.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lj_opt_fold.c')
-rw-r--r--src/lj_opt_fold.c67
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*/
956LJFOLD(ABC any ADD) 959LJFOLD(ABC any ADD)
957LJFOLDF(reassoc_abc) 960LJFOLDF(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*/
986LJFOLD(ABC any KINT)
987LJFOLDF(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. */
1008LJFOLD(ABC any any)
1009LJFOLDF(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.