diff options
author | amonakov <amonakov@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-04-22 12:44:30 +0000 |
---|---|---|
committer | amonakov <amonakov@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-04-22 12:44:30 +0000 |
commit | 50fa62c69940ddea294ac7656ec7c04ffa990221 (patch) | |
tree | ce9c97c82ea82bb23402a8499498721b5b7857e5 | |
parent | 1e33ad50b5d37f30af9e92c75a3d30f5d5b2d312 (diff) | |
download | gcc-50fa62c69940ddea294ac7656ec7c04ffa990221.tar.gz |
2010-04-22 Alexander Monakov <amonakov@ispras.ru>
* tree-ssa-reassoc.c (eliminate_plus_minus_pair): Handle BIT_NOT_EXPR
to simplify a + ~a.
* gfortran.dg/reassoc_6.f: New testcase.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@158645 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gfortran.dg/reassoc_6.f | 20 | ||||
-rw-r--r-- | gcc/tree-ssa-reassoc.c | 37 |
4 files changed, 59 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3c765004350..5eb1b305bbf 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2010-04-22 Alexander Monakov <amonakov@ispras.ru> + + * tree-ssa-reassoc.c (eliminate_plus_minus_pair): Handle BIT_NOT_EXPR + to simplify a + ~a. + 2010-04-22 Laurynas Biveinis <laurynas.biveinis@gmail.com> * tree-parloops.c (loop_parallel_p): New argument diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 4edbd72b2a0..6aecb02eb63 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2010-04-22 Alexander Monakov <amonakov@ispras.ru> + + * gfortran.dg/reassoc_6.f: New testcase. + 2010-04-22 Bernd Schmidt <bernds@codesourcery.com> PR middle-end/29274 diff --git a/gcc/testsuite/gfortran.dg/reassoc_6.f b/gcc/testsuite/gfortran.dg/reassoc_6.f new file mode 100644 index 00000000000..cbc36f5675b --- /dev/null +++ b/gcc/testsuite/gfortran.dg/reassoc_6.f @@ -0,0 +1,20 @@ +! { dg-do compile } +! { dg-options "-O2 -fdump-tree-optimized" } + + subroutine test(nb,nx,r2) + implicit none + integer nb,nx,i,l + real*8 r2(nb,nx) + + + do i=1,nx + do l=1,nb + r2(l,i)=0.0d0 + enddo + enddo + + return + end +! Verify that offset of the first element is simplified +! { dg-final { scan-tree-dump-not "~" "optimized" } } +! { dg-final { cleanup-tree-dump "optimized" } } diff --git a/gcc/tree-ssa-reassoc.c b/gcc/tree-ssa-reassoc.c index 8d1c05c86e1..aa080855e5b 100644 --- a/gcc/tree-ssa-reassoc.c +++ b/gcc/tree-ssa-reassoc.c @@ -489,11 +489,11 @@ eliminate_duplicate_pair (enum tree_code opcode, static VEC(tree, heap) *plus_negates; -/* If OPCODE is PLUS_EXPR, CURR->OP is really a negate expression, - look in OPS for a corresponding positive operation to cancel it - out. If we find one, remove the other from OPS, replace - OPS[CURRINDEX] with 0, and return true. Otherwise, return - false. */ +/* If OPCODE is PLUS_EXPR, CURR->OP is a negate expression or a bitwise not + expression, look in OPS for a corresponding positive operation to cancel + it out. If we find one, remove the other from OPS, replace + OPS[CURRINDEX] with 0 or -1, respectively, and return true. Otherwise, + return false. */ static bool eliminate_plus_minus_pair (enum tree_code opcode, @@ -502,6 +502,7 @@ eliminate_plus_minus_pair (enum tree_code opcode, operand_entry_t curr) { tree negateop; + tree notop; unsigned int i; operand_entry_t oe; @@ -509,7 +510,8 @@ eliminate_plus_minus_pair (enum tree_code opcode, return false; negateop = get_unary_op (curr->op, NEGATE_EXPR); - if (negateop == NULL_TREE) + notop = get_unary_op (curr->op, BIT_NOT_EXPR); + if (negateop == NULL_TREE && notop == NULL_TREE) return false; /* Any non-negated version will have a rank that is one less than @@ -541,11 +543,32 @@ eliminate_plus_minus_pair (enum tree_code opcode, return true; } + else if (oe->op == notop) + { + tree op_type = TREE_TYPE (oe->op); + + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, "Equivalence: "); + print_generic_expr (dump_file, notop, 0); + fprintf (dump_file, " + ~"); + print_generic_expr (dump_file, oe->op, 0); + fprintf (dump_file, " -> -1\n"); + } + + VEC_ordered_remove (operand_entry_t, *ops, i); + add_to_ops_vec (ops, build_int_cst_type (op_type, -1)); + VEC_ordered_remove (operand_entry_t, *ops, currindex); + reassociate_stats.ops_eliminated ++; + + return true; + } } /* CURR->OP is a negate expr in a plus expr: save it for later inspection in repropagate_negates(). */ - VEC_safe_push (tree, heap, plus_negates, curr->op); + if (negateop != NULL_TREE) + VEC_safe_push (tree, heap, plus_negates, curr->op); return false; } |