Commit e2e79a18 by Richard Guenther Committed by Richard Biener

re PR tree-optimization/33563 (DSE removes non-dead store)

2007-09-26  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/33563
	* tree-ssa-dse.c (get_use_of_stmt_lhs): Rename to ...
	(get_kill_of_stmt_lhs): ... this.  Re-structure.  Handle
	aggregate stores.
	(dse_optimize_stmt): Call get_kill_of_stmt_lhs instead of
	get_use_of_stmt_lhs.

	* gcc.dg/torture/pr33563.c: New testcase.

From-SVN: r128815
parent 68b72a44
2007-09-26 Richard Guenther <rguenther@suse.de>
PR tree-optimization/33563
* tree-ssa-dse.c (get_use_of_stmt_lhs): Rename to ...
(get_kill_of_stmt_lhs): ... this. Re-structure. Handle
aggregate stores.
(dse_optimize_stmt): Call get_kill_of_stmt_lhs instead of
get_use_of_stmt_lhs.
2007-09-26 Joseph Myers <joseph@codesourcery.com> 2007-09-26 Joseph Myers <joseph@codesourcery.com>
PR c/25309 PR c/25309
2007-09-26 Richard Guenther <rguenther@suse.de>
PR tree-optimization/33563
* gcc.dg/torture/pr33563.c: New testcase.
2007-09-26 Joseph Myers <joseph@codesourcery.com> 2007-09-26 Joseph Myers <joseph@codesourcery.com>
PR c/25309 PR c/25309
/* { dg-do run } */
/* { dg-options "--param max-aliased-vops=0" } */
struct T
{
int a, b;
} t, q;
int main (void)
{
struct T *p;
t.a = 1;
t.b = 2;
q = t;
t.a = 3;
if (q.a != 1)
__builtin_abort ();
return 0;
}
...@@ -210,62 +210,62 @@ memory_address_same (tree store1, tree store2) ...@@ -210,62 +210,62 @@ memory_address_same (tree store1, tree store2)
== NULL); == NULL);
} }
/* Return the use stmt for the lhs of STMT following the virtual /* Return true if there is a stmt that kills the lhs of STMT and is in the
def-use chains. Returns the MODIFY_EXPR stmt which lhs is equal to virtual def-use chain of STMT without a use inbetween the kill and STMT.
the lhs of STMT or NULL_TREE if no such stmt can be found. */ Returns false if no such stmt is found.
static tree *FIRST_USE_P is set to the first use of the single virtual def of
get_use_of_stmt_lhs (tree stmt, STMT. *USE_P is set to the vop killed by *USE_STMT. */
use_operand_p * first_use_p,
use_operand_p * use_p, tree * use_stmt) static bool
get_kill_of_stmt_lhs (tree stmt,
use_operand_p * first_use_p,
use_operand_p * use_p, tree * use_stmt)
{ {
tree usevar, lhs; tree lhs;
def_operand_p def_p;
if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT) gcc_assert (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT);
return NULL_TREE;
lhs = GIMPLE_STMT_OPERAND (stmt, 0); lhs = GIMPLE_STMT_OPERAND (stmt, 0);
/* The stmt must have a single VDEF. */ /* We now walk the chain of single uses of the single VDEFs.
def_p = SINGLE_SSA_DEF_OPERAND (stmt, SSA_OP_VDEF); We succeeded finding a kill if the lhs of the use stmt is
if (def_p == NULL_DEF_OPERAND_P) equal to the original lhs. We can keep walking to the next
return NULL_TREE; use if there are no possible uses of the original lhs in
the stmt. */
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 the use is not simple, give up. */
if (TREE_CODE (*use_stmt) != GIMPLE_MODIFY_STMT
|| get_call_expr_in (*use_stmt))
return NULL_TREE;
do do
{ {
/* Look at the use stmt and see if it's LHS matches tree use_lhs, use_rhs;
stmt's lhs SSA_NAME. */ def_operand_p def_p;
def_p = SINGLE_SSA_DEF_OPERAND (*use_stmt, SSA_OP_VDEF);
/* The stmt must have a single VDEF. */
def_p = SINGLE_SSA_DEF_OPERAND (stmt, SSA_OP_VDEF);
if (def_p == NULL_DEF_OPERAND_P) if (def_p == NULL_DEF_OPERAND_P)
return NULL_TREE; return false;
usevar = GIMPLE_STMT_OPERAND (*use_stmt, 0); /* Get the single immediate use of the def. */
if (operand_equal_p (usevar, lhs, 0)) if (!single_imm_use (DEF_FROM_PTR (def_p), first_use_p, &stmt))
return *use_stmt; return false;
first_use_p = use_p;
if (!has_single_use (DEF_FROM_PTR (def_p))) /* If there are possible hidden uses, give up. */
return NULL_TREE; if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
single_imm_use (DEF_FROM_PTR (def_p), use_p, use_stmt); return false;
gcc_assert (*use_p != NULL_USE_OPERAND_P); use_rhs = GIMPLE_STMT_OPERAND (stmt, 1);
if (TREE_CODE (*use_stmt) != GIMPLE_MODIFY_STMT if (TREE_CODE (use_rhs) == CALL_EXPR
|| get_call_expr_in (*use_stmt)) || (!is_gimple_min_invariant (use_rhs)
return NULL_TREE; && TREE_CODE (use_rhs) != SSA_NAME))
return false;
/* If the use stmts lhs matches the original lhs we have
found the kill, otherwise continue walking. */
use_lhs = GIMPLE_STMT_OPERAND (stmt, 0);
if (operand_equal_p (use_lhs, lhs, 0))
{
*use_stmt = stmt;
return true;
}
} }
while (1); while (1);
return NULL_TREE;
} }
/* A helper of dse_optimize_stmt. /* A helper of dse_optimize_stmt.
...@@ -448,8 +448,7 @@ dse_optimize_stmt (struct dom_walk_data *walk_data, ...@@ -448,8 +448,7 @@ dse_optimize_stmt (struct dom_walk_data *walk_data,
the stores are not to the same memory location then walk the 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 virtual def-use chain to get the stmt which stores to that same
memory location. */ memory location. */
if (get_use_of_stmt_lhs (stmt, &first_use_p, &use_p, &use_stmt) == if (!get_kill_of_stmt_lhs (stmt, &first_use_p, &use_p, &use_stmt))
NULL_TREE)
{ {
record_voperand_set (dse_gd->stores, &bd->stores, ann->uid); record_voperand_set (dse_gd->stores, &bd->stores, ann->uid);
return; return;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment