tree-ssa-reassoc.c (eliminate_plus_minus_pair): Handle BIT_NOT_EXPR to simplify a...
authorAlexander Monakov <amonakov@ispras.ru>
Thu, 22 Apr 2010 12:44:30 +0000 (16:44 +0400)
committerAlexander Monakov <amonakov@gcc.gnu.org>
Thu, 22 Apr 2010 12:44:30 +0000 (16:44 +0400)
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.

From-SVN: r158645

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/reassoc_6.f [new file with mode: 0644]
gcc/tree-ssa-reassoc.c

index 3c765004350eeb185351c052a4f57127136295ad..5eb1b305bbfc4314a4c61c504734fa07e2fb3721 100644 (file)
@@ -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
index 4edbd72b2a030eeeac04a37de756d4eb2c96e674..6aecb02eb63d8b0b29f4f6376a973f2953825aa4 100644 (file)
@@ -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 (file)
index 0000000..cbc36f5
--- /dev/null
@@ -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" } }
index 8d1c05c86e1eb20b58855cbbee7a9c2642cb2db3..aa080855e5be3f92dbc3cf9b76084c586e39bcfb 100644 (file)
@@ -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
@@ -539,13 +541,34 @@ eliminate_plus_minus_pair (enum tree_code opcode,
          VEC_ordered_remove (operand_entry_t, *ops, currindex);
          reassociate_stats.ops_eliminated ++;
 
+         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;
 }