diff options
author | Daniel Jacobowitz <dan@codesourcery.com> | 2005-11-11 23:23:15 +0000 |
---|---|---|
committer | Daniel Jacobowitz <drow@gcc.gnu.org> | 2005-11-11 23:23:15 +0000 |
commit | 6c14b137a907a5eda102567d6fac239aec447c8c (patch) | |
tree | f2c1d5283c34ae068914def3e26a1ccec575de71 | |
parent | 44087d555cb9baf64a5a7dde3f46653a971b8e89 (diff) | |
download | gcc-6c14b137a907a5eda102567d6fac239aec447c8c.zip gcc-6c14b137a907a5eda102567d6fac239aec447c8c.tar.gz gcc-6c14b137a907a5eda102567d6fac239aec447c8c.tar.bz2 |
gcc/
* 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.
From-SVN: r106807
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/20051110-1.c | 31 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/20051110-2.c | 39 | ||||
-rw-r--r-- | gcc/tree-ssa-dse.c | 72 |
5 files changed, 151 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index bb8033c..5a7d54f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 71698c4..aebb7a1 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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 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 index 0000000..9fa3df8 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/20051110-1.c @@ -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 index 0000000..57bfeeb --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/20051110-2.c @@ -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; +} diff --git a/gcc/tree-ssa-dse.c b/gcc/tree-ssa-dse.c index 7087018..fa3ba96 100644 --- a/gcc/tree-ssa-dse.c +++ b/gcc/tree-ssa-dse.c @@ -83,6 +83,13 @@ struct dse_block_local_data 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 *, @@ -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 @@ -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 - 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), - 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))) |