OSDN Git Service

gcc/
authordrow <drow@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 11 Nov 2005 23:23:15 +0000 (23:23 +0000)
committerdrow <drow@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 11 Nov 2005 23:23:15 +0000 (23:23 +0000)
* tree-ssa-dse.c (struct address_walk_data, memory_ssa_name_same)
(memory_address_same): New.
(dse_optimize_stmt): Call memory_address_same.
gcc/testsuite/
* gcc.c-torture/execute/20051110-1.c,
gcc.c-torture/execute/20051110-2.c: New tests.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@106807 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/20051110-1.c [new file with mode: 0644]
gcc/testsuite/gcc.c-torture/execute/20051110-2.c [new file with mode: 0644]
gcc/tree-ssa-dse.c

index bb8033c..5a7d54f 100644 (file)
@@ -1,3 +1,9 @@
+2005-11-11  Daniel Jacobowitz  <dan@codesourcery.com>
+
+       * tree-ssa-dse.c (struct address_walk_data, memory_ssa_name_same)
+       (memory_address_same): New.
+       (dse_optimize_stmt): Call memory_address_same.
+
 2005-11-12  Hans-Peter Nilsson  <hp@axis.com>
 
        PR middle-end/24750
 2005-11-12  Hans-Peter Nilsson  <hp@axis.com>
 
        PR middle-end/24750
index 71698c4..aebb7a1 100644 (file)
@@ -1,3 +1,8 @@
+2005-11-11  Daniel Jacobowitz  <dan@codesourcery.com>
+
+       * gcc.c-torture/execute/20051110-1.c,
+       gcc.c-torture/execute/20051110-2.c: New tests.
+
 2005-11-12  Hans-Peter Nilsson  <hp@axis.com>
 
        PR middle-end/24750
 2005-11-12  Hans-Peter Nilsson  <hp@axis.com>
 
        PR middle-end/24750
diff --git a/gcc/testsuite/gcc.c-torture/execute/20051110-1.c b/gcc/testsuite/gcc.c-torture/execute/20051110-1.c
new file mode 100644 (file)
index 0000000..9fa3df8
--- /dev/null
@@ -0,0 +1,31 @@
+void add_unwind_adjustsp (long);
+void abort (void);
+
+unsigned char bytes[5];
+
+void
+add_unwind_adjustsp (long offset)
+{
+  int n;
+  unsigned long o;
+
+  o = (long) ((offset - 0x204) >> 2);
+
+  n = 0;
+  while (o)
+    {
+      bytes[n] = o & 0x7f;
+      o >>= 7;
+      if (o)
+       bytes[n] |= 0x80;
+      n++;
+    }
+}
+
+int main(void)
+{
+  add_unwind_adjustsp (4132);
+  if (bytes[0] != 0x88 || bytes[1] != 0x07)
+    abort ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/20051110-2.c b/gcc/testsuite/gcc.c-torture/execute/20051110-2.c
new file mode 100644 (file)
index 0000000..57bfeeb
--- /dev/null
@@ -0,0 +1,39 @@
+void add_unwind_adjustsp (long);
+void abort (void);
+
+unsigned char bytes[5];
+
+int flag;
+
+void
+add_unwind_adjustsp (long offset)
+{
+  int n;
+  unsigned long o;
+
+  o = (long) ((offset - 0x204) >> 2);
+
+  n = 0;
+  do
+    {
+a:
+      bytes[n] = o & 0x7f;
+      o >>= 7;
+      if (o)
+        {
+         bytes[n] |= 0x80;
+         if (flag)
+           goto a;
+       }
+      n++;
+    }
+  while (o);
+}
+
+int main(void)
+{
+  add_unwind_adjustsp (4132);
+  if (bytes[0] != 0x88 || bytes[1] != 0x07)
+    abort ();
+  return 0;
+}
index 7087018..fa3ba96 100644 (file)
@@ -83,6 +83,13 @@ struct dse_block_local_data
   bitmap stores;
 };
 
   bitmap stores;
 };
 
+/* Basic blocks of the potentially dead store and the following
+   store, for memory_address_same.  */
+struct address_walk_data
+{
+  basic_block store1_bb, store2_bb;
+};
+
 static bool gate_dse (void);
 static void tree_ssa_dse (void);
 static void dse_initialize_block_local_data (struct dom_walk_data *,
 static bool gate_dse (void);
 static void tree_ssa_dse (void);
 static void dse_initialize_block_local_data (struct dom_walk_data *,
@@ -145,6 +152,64 @@ dse_initialize_block_local_data (struct dom_walk_data *walk_data,
     }
 }
 
     }
 }
 
+/* Helper function for memory_address_same via walk_tree.  Returns
+   non-NULL if it finds an SSA_NAME which is part of the address,
+   such that the definition of the SSA_NAME post-dominates the store
+   we want to delete but not the store that we believe makes it
+   redundant.  This indicates that the address may change between
+   the two stores.  */
+
+static tree
+memory_ssa_name_same (tree *expr_p, int *walk_subtrees ATTRIBUTE_UNUSED,
+                     void *data)
+{
+  struct address_walk_data *walk_data = data;
+  tree expr = *expr_p;
+  tree def_stmt;
+  basic_block def_bb;
+
+  if (TREE_CODE (expr) != SSA_NAME)
+    return NULL_TREE;
+
+  /* If we've found a default definition, then there's no problem.  Both
+     stores will post-dominate it.  And def_bb will be NULL.  */
+  if (expr == default_def (SSA_NAME_VAR (expr)))
+    return NULL_TREE;
+
+  def_stmt = SSA_NAME_DEF_STMT (expr);
+  def_bb = bb_for_stmt (def_stmt);
+
+  /* DEF_STMT must dominate both stores.  So if it is in the same
+     basic block as one, it does not post-dominate that store.  */
+  if (walk_data->store1_bb != def_bb
+      && dominated_by_p (CDI_POST_DOMINATORS, walk_data->store1_bb, def_bb))
+    {
+      if (walk_data->store2_bb == def_bb
+         || !dominated_by_p (CDI_POST_DOMINATORS, walk_data->store2_bb,
+                             def_bb))
+       /* Return non-NULL to stop the walk.  */
+       return def_stmt;
+    }
+
+  return NULL_TREE;
+}
+
+/* Return TRUE if the destination memory address in STORE1 and STORE2
+   might be modified after STORE1, before control reaches STORE2.  */
+
+static bool
+memory_address_same (tree store1, tree store2)
+{
+  struct address_walk_data walk_data;
+
+  walk_data.store1_bb = bb_for_stmt (store1);
+  walk_data.store2_bb = bb_for_stmt (store2);
+
+  return (walk_tree (&TREE_OPERAND (store1, 0), memory_ssa_name_same,
+                    &walk_data, NULL)
+         == NULL);
+}
+
 /* Attempt to eliminate dead stores in the statement referenced by BSI.
 
    A dead store is a store into a memory location which will later be
 /* Attempt to eliminate dead stores in the statement referenced by BSI.
 
    A dead store is a store into a memory location which will later be
@@ -251,11 +316,14 @@ dse_optimize_stmt (struct dom_walk_data *walk_data,
        }
 
       /* If we have precisely one immediate use at this point, then we may
        }
 
       /* If we have precisely one immediate use at this point, then we may
-        have found redundant store.  */
+        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 (TREE_OPERAND (stmt, 0),
       if (use_p != NULL_USE_OPERAND_P
          && bitmap_bit_p (dse_gd->stores, get_stmt_uid (use_stmt))
          && operand_equal_p (TREE_OPERAND (stmt, 0),
-                             TREE_OPERAND (use_stmt, 0), 0))
+                             TREE_OPERAND (use_stmt, 0), 0)
+         && memory_address_same (stmt, use_stmt))
        {
          /* Make sure we propagate the ABNORMAL bit setting.  */
          if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (USE_FROM_PTR (first_use_p)))
        {
          /* Make sure we propagate the ABNORMAL bit setting.  */
          if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (USE_FROM_PTR (first_use_p)))