]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Extend dse
authorRevital Eres <eres@il.ibm.com>
Sun, 13 May 2007 07:49:47 +0000 (07:49 +0000)
committerRevital Eres <revitale@gcc.gnu.org>
Sun, 13 May 2007 07:49:47 +0000 (07:49 +0000)
From-SVN: r124651

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/dse.c [new file with mode: 0644]
gcc/tree-ssa-dse.c

index 8fa8e7c6c9a1c8d56dcd71e5584e3deab8ddd158..f454c193240a6bd509deb24cec05081091d901e3 100644 (file)
@@ -1,3 +1,9 @@
+2007-05-13  Revital Eres  <eres@il.ibm.com>
+
+       * tree-ssa-dse.c (get_use_of_stmt_lhs): New function
+       which walks virtual def-use chains to find redundant stores.
+       (dse_optimize_stmt): Call it.
+
 2007-05-12  Steven Bosscher  <steven@gcc.gnu.org>
 
        * gcse.c (gcse_main): Do jump bypassing in CPROP2.
index b4ad8f7384b83a417d32df6a1c0ed76e6e275b4f..586fc11de3856fbd05458c2de433469ee0a2afb0 100644 (file)
@@ -1,3 +1,7 @@
+2007-05-13  Revital Eres  <eres@il.ibm.com>
+
+       * gcc.dg/dse.c: New test.
+
 2007-05-12  Richard Guenther  <rguenther@suse.de>
 
        PR tree-optimization/31797
diff --git a/gcc/testsuite/gcc.dg/dse.c b/gcc/testsuite/gcc.dg/dse.c
new file mode 100644 (file)
index 0000000..4a859ae
--- /dev/null
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-dse-details" } */
+
+#define N 256
+
+struct
+{
+  int x;
+  int y;
+} S[100];
+
+int z[100];
+
+int
+foo (void)
+{
+  int i;
+  int x, y;
+
+  S[5].x = 0;
+  S[5].y = 0;
+
+  x = 5 + z[0];
+  y = z[0];
+
+  S[5].x = x;
+  S[5].y = y;
+}
+
+/* { dg-final { scan-tree-dump-times "Deleted dead store" 2 "dse1" } } */
+/* { dg-final { cleanup-tree-dump "dse*" } } */
+
index bb5d14d78f9731371f5881e9dd74ae019f7978cd..596d4a8ee6bc819bca218891dcb69dbeef4e6ee7 100644 (file)
@@ -237,6 +237,59 @@ memory_address_same (tree store1, tree store2)
          == NULL);
 }
 
+/* Return the use stmt for the lhs of STMT following the virtual
+   def-use chains.  Returns the MODIFY_EXPR stmt which lhs is equal to
+   the lhs of STMT or NULL_TREE if no such stmt can be found.  */
+static tree 
+get_use_of_stmt_lhs (tree stmt,
+                    use_operand_p * first_use_p,
+                    use_operand_p * use_p, tree * use_stmt)
+{
+  tree usevar, lhs;
+  def_operand_p def_p;
+
+  if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
+    return NULL_TREE;
+
+  lhs = GIMPLE_STMT_OPERAND (stmt, 0);
+
+  /* The stmt must have a single VDEF.  */
+  def_p = SINGLE_SSA_DEF_OPERAND (stmt, SSA_OP_VDEF);
+  if (def_p == NULL_DEF_OPERAND_P)
+    return NULL_TREE;
+
+  if (!has_single_use (DEF_FROM_PTR (def_p)))
+    return NULL_TREE;
+  /* Get the immediate use of the def.  */
+  single_imm_use (DEF_FROM_PTR (def_p), use_p, use_stmt);
+  gcc_assert (*use_p != NULL_USE_OPERAND_P);
+  first_use_p = use_p;
+  if (TREE_CODE (*use_stmt) != GIMPLE_MODIFY_STMT)
+    return NULL_TREE;
+
+  do
+    {
+      /* Look at the use stmt and see if it's LHS matches
+         stmt's lhs SSA_NAME.  */
+      def_p = SINGLE_SSA_DEF_OPERAND (*use_stmt, SSA_OP_VDEF);
+      if (def_p == NULL_DEF_OPERAND_P)
+       return NULL_TREE;
+
+      usevar = GIMPLE_STMT_OPERAND (*use_stmt, 0);
+      if (operand_equal_p (usevar, lhs, 0))
+       return *use_stmt;
+
+      if (!has_single_use (DEF_FROM_PTR (def_p)))
+       return NULL_TREE;
+      single_imm_use (DEF_FROM_PTR (def_p), use_p, use_stmt);
+      gcc_assert (*use_p != NULL_USE_OPERAND_P);
+      if (TREE_CODE (*use_stmt) != GIMPLE_MODIFY_STMT)
+       return NULL_TREE;
+    }
+  while (1);
+
+  return NULL_TREE;
+}
 
 /* A helper of dse_optimize_stmt.
    Given a GIMPLE_MODIFY_STMT in STMT, check that each VDEF has one
@@ -593,10 +646,29 @@ dse_optimize_stmt (struct dom_walk_data *walk_data,
       /* If this is a partial store into an aggregate, record it.  */
       dse_record_partial_aggregate_store (stmt, dse_gd);
 
-      /* If we have precisely one immediate use at this point, then we may
-        have found redundant store.  Make sure that the stores are to
-        the same memory location.  This includes checking that any
-        SSA-form variables in the address will have the same values.  */
+      if (use_p != NULL_USE_OPERAND_P
+          && bitmap_bit_p (dse_gd->stores, get_stmt_uid (use_stmt))
+          && (!operand_equal_p (GIMPLE_STMT_OPERAND (stmt, 0),
+                                GIMPLE_STMT_OPERAND (use_stmt, 0), 0)
+              && !dse_partial_kill_p (stmt, dse_gd))
+          && memory_address_same (stmt, use_stmt))
+        {
+          /* If we have precisely one immediate use at this point, but
+             the stores are not to the same memory location then walk the
+             virtual def-use chain to get the stmt which stores to that same
+             memory location.  */
+          if (get_use_of_stmt_lhs (stmt, &first_use_p, &use_p, &use_stmt) ==
+              NULL_TREE)
+            {
+              record_voperand_set (dse_gd->stores, &bd->stores, ann->uid);
+              return;
+            }
+        }
+
+      /* If we have precisely one immediate use at this point and the
+        stores are to the same memory location or there is a chain of
+        virtual uses from stmt and the stmt which stores to that same
+        memory location, then we may have found redundant store.  */
       if (use_p != NULL_USE_OPERAND_P
          && bitmap_bit_p (dse_gd->stores, get_stmt_uid (use_stmt))
          && (operand_equal_p (GIMPLE_STMT_OPERAND (stmt, 0),