re PR tree-optimization/45970 (tree DSE misses many obvious dead stores)

2010-10-13  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/45970
	* tree-ssa-alias.h (stmt_kills_ref_p): Declare.
	* tree-ssa-alias.c (stmt_kills_ref_p_1): New function.
	(stmt_kills_ref_p): Likewise.
	* tree-ssa-dse.c (dse_optimize_stmt): Use it.

	* gcc.dg/tree-ssa/ssa-dse-13.c: New testcase.

From-SVN: r165422
This commit is contained in:
Richard Guenther 2010-10-13 13:03:31 +00:00 committed by Richard Biener
parent 9827eb57a3
commit 71d6134802
6 changed files with 77 additions and 2 deletions

View File

@ -1,3 +1,11 @@
2010-10-13 Richard Guenther <rguenther@suse.de>
PR tree-optimization/45970
* tree-ssa-alias.h (stmt_kills_ref_p): Declare.
* tree-ssa-alias.c (stmt_kills_ref_p_1): New function.
(stmt_kills_ref_p): Likewise.
* tree-ssa-dse.c (dse_optimize_stmt): Use it.
2010-10-13 Richard Guenther <rguenther@suse.de> 2010-10-13 Richard Guenther <rguenther@suse.de>
PR tree-optimization/45982 PR tree-optimization/45982

View File

@ -1,3 +1,8 @@
2010-10-13 Richard Guenther <rguenther@suse.de>
PR tree-optimization/45970
* gcc.dg/tree-ssa/ssa-dse-13.c: New testcase.
2010-10-13 Richard Guenther <rguenther@suse.de> 2010-10-13 Richard Guenther <rguenther@suse.de>
PR tree-optimization/45982 PR tree-optimization/45982

View File

@ -0,0 +1,21 @@
/* { dg-do compile } */
/* { dg-options "-O -fdump-tree-dse1-details" } */
struct A { char c[4]; } a, b;
void
f1 (void)
{
__builtin_memcpy (&a.c[0], "a", 1);
a = b;
}
void
f2 (void)
{
__builtin_memcpy (&a.c[0], "a", 1);
__builtin_memcpy (&a.c[0], "cdef", 4);
}
/* { dg-final { scan-tree-dump-times "Deleted dead store" 2 "dse1" } } */
/* { dg-final { cleanup-tree-dump "dse1" } } */

View File

@ -1522,6 +1522,45 @@ stmt_may_clobber_ref_p (gimple stmt, tree ref)
return stmt_may_clobber_ref_p_1 (stmt, &r); return stmt_may_clobber_ref_p_1 (stmt, &r);
} }
/* If STMT kills the memory reference REF return true, otherwise
return false. */
static bool
stmt_kills_ref_p_1 (gimple stmt, ao_ref *ref)
{
if (gimple_has_lhs (stmt)
&& TREE_CODE (gimple_get_lhs (stmt)) != SSA_NAME)
{
tree base, lhs = gimple_get_lhs (stmt);
HOST_WIDE_INT size, offset, max_size;
ao_ref_base (ref);
base = get_ref_base_and_extent (lhs, &offset, &size, &max_size);
/* We can get MEM[symbol: sZ, index: D.8862_1] here,
so base == ref->base does not always hold. */
if (base == ref->base)
{
/* For a must-alias check we need to be able to constrain
the accesses properly. */
if (size != -1 && size == max_size
&& ref->max_size != -1)
{
if (offset <= ref->offset
&& offset + size >= ref->offset + ref->max_size)
return true;
}
}
}
return false;
}
bool
stmt_kills_ref_p (gimple stmt, tree ref)
{
ao_ref r;
ao_ref_init (&r, ref);
return stmt_kills_ref_p_1 (stmt, &r);
}
/* Walk the virtual use-def chain of VUSE until hitting the virtual operand /* Walk the virtual use-def chain of VUSE until hitting the virtual operand
TARGET or a statement clobbering the memory reference REF in which TARGET or a statement clobbering the memory reference REF in which

View File

@ -105,6 +105,7 @@ extern bool ref_maybe_used_by_stmt_p (gimple, tree);
extern bool stmt_may_clobber_ref_p (gimple, tree); extern bool stmt_may_clobber_ref_p (gimple, tree);
extern bool stmt_may_clobber_ref_p_1 (gimple, ao_ref *); extern bool stmt_may_clobber_ref_p_1 (gimple, ao_ref *);
extern bool call_may_clobber_ref_p (gimple, tree); extern bool call_may_clobber_ref_p (gimple, tree);
extern bool stmt_kills_ref_p (gimple, tree);
extern tree get_continuation_for_phi (gimple, ao_ref *, bitmap *); extern tree get_continuation_for_phi (gimple, ao_ref *, bitmap *);
extern void *walk_non_aliased_vuses (ao_ref *, tree, extern void *walk_non_aliased_vuses (ao_ref *, tree,
void *(*)(ao_ref *, tree, void *), void *(*)(ao_ref *, tree, void *),

View File

@ -301,8 +301,9 @@ dse_optimize_stmt (struct dse_global_data *dse_gd,
virtual uses from stmt and the stmt which stores to that same virtual uses from stmt and the stmt which stores to that same
memory location, then we may have found redundant store. */ memory location, then we may have found redundant store. */
if (bitmap_bit_p (dse_gd->stores, get_stmt_uid (use_stmt)) if (bitmap_bit_p (dse_gd->stores, get_stmt_uid (use_stmt))
&& operand_equal_p (gimple_assign_lhs (stmt), && (operand_equal_p (gimple_assign_lhs (stmt),
gimple_assign_lhs (use_stmt), 0)) gimple_assign_lhs (use_stmt), 0)
|| stmt_kills_ref_p (use_stmt, gimple_assign_lhs (stmt))))
{ {
/* If use_stmt is or might be a nop assignment, e.g. for /* If use_stmt is or might be a nop assignment, e.g. for
struct { ... } S a, b, *p; ... struct { ... } S a, b, *p; ...