From 71d61348020eedc3d89e4c877ad714cbb2954792 Mon Sep 17 00:00:00 2001 From: Richard Guenther Date: Wed, 13 Oct 2010 13:03:31 +0000 Subject: [PATCH] re PR tree-optimization/45970 (tree DSE misses many obvious dead stores) 2010-10-13 Richard Guenther 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 --- gcc/ChangeLog | 8 +++++ gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-13.c | 21 ++++++++++++ gcc/tree-ssa-alias.c | 39 ++++++++++++++++++++++ gcc/tree-ssa-alias.h | 1 + gcc/tree-ssa-dse.c | 5 +-- 6 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-13.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ee15bde78943..5a705fb68a64 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2010-10-13 Richard Guenther + + 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 PR tree-optimization/45982 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index cd166147c0fd..65ca05c9df64 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2010-10-13 Richard Guenther + + PR tree-optimization/45970 + * gcc.dg/tree-ssa/ssa-dse-13.c: New testcase. + 2010-10-13 Richard Guenther PR tree-optimization/45982 diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-13.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-13.c new file mode 100644 index 000000000000..92e0f2b53599 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-13.c @@ -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" } } */ diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c index e00c50a2ef96..afd5e0852cc8 100644 --- a/gcc/tree-ssa-alias.c +++ b/gcc/tree-ssa-alias.c @@ -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 diff --git a/gcc/tree-ssa-alias.h b/gcc/tree-ssa-alias.h index 499559d07e8e..1f2207657819 100644 --- a/gcc/tree-ssa-alias.h +++ b/gcc/tree-ssa-alias.h @@ -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 *), diff --git a/gcc/tree-ssa-dse.c b/gcc/tree-ssa-dse.c index be440c9b6570..80c2622c9dc6 100644 --- a/gcc/tree-ssa-dse.c +++ b/gcc/tree-ssa-dse.c @@ -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; ...