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>
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>
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);
}
/* 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
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_1 (gimple, ao_ref *);
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 void *walk_non_aliased_vuses (ao_ref *, tree,
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
memory location, then we may have found redundant store. */
if (bitmap_bit_p (dse_gd->stores, get_stmt_uid (use_stmt))
&& operand_equal_p (gimple_assign_lhs (stmt),
gimple_assign_lhs (use_stmt), 0))
&& (operand_equal_p (gimple_assign_lhs (stmt),
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
struct { ... } S a, b, *p; ...