From 0ea48022b83f9f960724dab8fd75a4dc9d6e2269 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Wed, 4 Jun 2014 11:56:34 +0000 Subject: [PATCH] re PR tree-optimization/60098 (DSE fails to DSE errno settings) 2014-06-04 Richard Biener PR tree-optimization/60098 * tree-ssa-dse.c (dse_possible_dead_store_p): Walk until we hit a kill. (dse_optimize_stmt): Simplify, now that we found a kill earlier. * gcc.dg/tree-ssa/ssa-dse-15.c: New testcase. From-SVN: r211224 --- gcc/ChangeLog | 8 +++ gcc/testsuite/ChangeLog | 5 ++ gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-15.c | 24 +++++++ gcc/tree-ssa-dse.c | 84 ++++++++++------------ 4 files changed, 74 insertions(+), 47 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-15.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d82234cf2b1..645dc0b4cc0 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2014-06-04 Richard Biener + + PR tree-optimization/60098 + * tree-ssa-dse.c (dse_possible_dead_store_p): Walk until + we hit a kill. + (dse_optimize_stmt): Simplify, now that we found a kill + earlier. + 2014-06-04 Richard Biener * tree-ssa-alias.c (stmt_may_clobber_ref_p): Improve handling diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b3e39d37df6..883a2bd43b2 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2014-06-04 Richard Biener + + PR tree-optimization/60098 + * gcc.dg/tree-ssa/ssa-dse-15.c: New testcase. + 2014-06-04 Richard Biener * gcc.dg/tree-ssa/ssa-dse-16.c: New testcase. diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-15.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-15.c new file mode 100644 index 00000000000..cfddb30e4fa --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-15.c @@ -0,0 +1,24 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-dse1-details" } */ + +void *foo (int *p) +{ + void *q; + /* We should be able to DSE this store (p may point to errno). */ + *p = 0; + q = __builtin_malloc (4); + *p = 0; + return q; +} + +int j; +void bar (int *i) +{ + /* This store is dead as well. */ + j = 1; + *i = 0; + j = 2; +} + +/* { dg-final { scan-tree-dump-times "Deleted dead store" 2 "dse1" } } */ +/* { dg-final { cleanup-tree-dump "dse1" } } */ diff --git a/gcc/tree-ssa-dse.c b/gcc/tree-ssa-dse.c index 4632adde9c9..1d752e378a2 100644 --- a/gcc/tree-ssa-dse.c +++ b/gcc/tree-ssa-dse.c @@ -198,10 +198,8 @@ dse_possible_dead_store_p (gimple stmt, gimple *use_stmt) break; } } - /* We deliberately stop on clobbering statements and not only on - killing ones to make walking cheaper. Otherwise we can just - continue walking until both stores have equal reference trees. */ - while (!stmt_may_clobber_ref_p (temp, gimple_assign_lhs (stmt))); + /* Continue walking until we reach a kill. */ + while (!stmt_kills_ref_p (temp, gimple_assign_lhs (stmt))); *use_stmt = temp; @@ -248,57 +246,49 @@ dse_optimize_stmt (gimple_stmt_iterator *gsi) if (!dse_possible_dead_store_p (stmt, &use_stmt)) return; + /* Now we know that use_stmt kills the LHS of stmt. */ + /* But only remove *this_2(D) ={v} {CLOBBER} if killed by another clobber stmt. */ if (gimple_clobber_p (stmt) && !gimple_clobber_p (use_stmt)) return; - /* If we have precisely one immediate use at this point and the - stores are to the same memory location or there is a chain of - virtual uses from stmt and the stmt which stores to that same - memory location, then we may have found redundant store. */ - if ((gimple_has_lhs (use_stmt) - && (operand_equal_p (gimple_assign_lhs (stmt), - gimple_get_lhs (use_stmt), 0))) - || stmt_kills_ref_p (use_stmt, gimple_assign_lhs (stmt))) + basic_block bb; + + /* If use_stmt is or might be a nop assignment, e.g. for + struct { ... } S a, b, *p; ... + b = a; b = b; + or + b = a; b = *p; where p might be &b, + or + *p = a; *p = b; where p might be &b, + or + *p = *u; *p = *v; where p might be v, then USE_STMT + acts as a use as well as definition, so store in STMT + is not dead. */ + if (stmt != use_stmt + && ref_maybe_used_by_stmt_p (use_stmt, gimple_assign_lhs (stmt))) + return; + + if (dump_file && (dump_flags & TDF_DETAILS)) { - basic_block bb; - - /* If use_stmt is or might be a nop assignment, e.g. for - struct { ... } S a, b, *p; ... - b = a; b = b; - or - b = a; b = *p; where p might be &b, - or - *p = a; *p = b; where p might be &b, - or - *p = *u; *p = *v; where p might be v, then USE_STMT - acts as a use as well as definition, so store in STMT - is not dead. */ - if (stmt != use_stmt - && ref_maybe_used_by_stmt_p (use_stmt, gimple_assign_lhs (stmt))) - return; - - if (dump_file && (dump_flags & TDF_DETAILS)) - { - fprintf (dump_file, " Deleted dead store '"); - print_gimple_stmt (dump_file, gsi_stmt (*gsi), dump_flags, 0); - fprintf (dump_file, "'\n"); - } - - /* Then we need to fix the operand of the consuming stmt. */ - unlink_stmt_vdef (stmt); - - /* Remove the dead store. */ - bb = gimple_bb (stmt); - if (gsi_remove (gsi, true)) - bitmap_set_bit (need_eh_cleanup, bb->index); - - /* And release any SSA_NAMEs set in this statement back to the - SSA_NAME manager. */ - release_defs (stmt); + fprintf (dump_file, " Deleted dead store '"); + print_gimple_stmt (dump_file, gsi_stmt (*gsi), dump_flags, 0); + fprintf (dump_file, "'\n"); } + + /* Then we need to fix the operand of the consuming stmt. */ + unlink_stmt_vdef (stmt); + + /* Remove the dead store. */ + bb = gimple_bb (stmt); + if (gsi_remove (gsi, true)) + bitmap_set_bit (need_eh_cleanup, bb->index); + + /* And release any SSA_NAMEs set in this statement back to the + SSA_NAME manager. */ + release_defs (stmt); } }