summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoramonakov <amonakov@138bc75d-0d04-0410-961f-82ee72b054a4>2010-04-22 12:44:30 +0000
committeramonakov <amonakov@138bc75d-0d04-0410-961f-82ee72b054a4>2010-04-22 12:44:30 +0000
commit50fa62c69940ddea294ac7656ec7c04ffa990221 (patch)
treece9c97c82ea82bb23402a8499498721b5b7857e5
parent1e33ad50b5d37f30af9e92c75a3d30f5d5b2d312 (diff)
downloadgcc-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/ChangeLog5
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gfortran.dg/reassoc_6.f20
-rw-r--r--gcc/tree-ssa-reassoc.c37
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;
}