The PR shows that the default walking limit of DSE (256) can be
insufficient for C++ code with large abstraction simply due to the
fact of hundreds of unused aggregates that are just CLOBBERed.
The remove_unused_locals phase has special code to deal with those
but it is just invoked in very few places.  The following triggers
it after DSE if DSE performed any dead store removal - maybe we
should unconditionally do so or make DSE remove such CLOBBERs
itself somehow.  Or we might want to place explicit schedules of
remove_unused_locals in the pass pipeline.

This avoids the need for increasing --param dse-max-alias-queries-per-store
to make DSE remove all dead stores for the testcase in the PR.

Any comments?

2021-04-07  Richard Biener  <rguent...@suse.de>

        PR tree-optimization/99912
        * tree-ssa-dse.c (n_stores_removed): New global.
        (delete_dead_or_redundant_assignment): Increment
        n_stores_removed.
        (pass_dse::execute): Initialize n_stores_removed, schedule
        TODO_remove_unused_locals if nonzero.  Release
        post-dominators before calling CFG cleanup.
---
 gcc/tree-ssa-dse.c | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/gcc/tree-ssa-dse.c b/gcc/tree-ssa-dse.c
index 4967a5a9927..83879688abf 100644
--- a/gcc/tree-ssa-dse.c
+++ b/gcc/tree-ssa-dse.c
@@ -85,6 +85,8 @@ static void delete_dead_or_redundant_call 
(gimple_stmt_iterator *, const char *)
    remove their dead edges eventually.  */
 static bitmap need_eh_cleanup;
 
+static unsigned n_stores_removed;
+
 /* STMT is a statement that may write into memory.  Analyze it and
    initialize WRITE to describe how STMT affects memory.
 
@@ -1031,6 +1033,8 @@ delete_dead_or_redundant_assignment (gimple_stmt_iterator 
*gsi, const char *type
   /* And release any SSA_NAMEs set in this statement back to the
      SSA_NAME manager.  */
   release_defs (stmt);
+
+  n_stores_removed++;
 }
 
 /* Attempt to eliminate dead stores in the statement referenced by BSI.
@@ -1222,6 +1226,7 @@ unsigned int
 pass_dse::execute (function *fun)
 {
   need_eh_cleanup = BITMAP_ALLOC (NULL);
+  n_stores_removed = 0;
 
   renumber_gimple_stmt_uids (cfun);
 
@@ -1236,6 +1241,9 @@ pass_dse::execute (function *fun)
      tree and a backwards walk of statements within each block.  */
   dse_dom_walker (CDI_POST_DOMINATORS).walk (fun->cfg->x_exit_block_ptr);
 
+  /* Wipe the post-dominator information.  */
+  free_dominance_info (CDI_POST_DOMINATORS);
+
   /* Removal of stores may make some EH edges dead.  Purge such edges from
      the CFG as needed.  */
   if (!bitmap_empty_p (need_eh_cleanup))
@@ -1246,9 +1254,9 @@ pass_dse::execute (function *fun)
 
   BITMAP_FREE (need_eh_cleanup);
 
-  /* For now, just wipe the post-dominator information.  */
-  free_dominance_info (CDI_POST_DOMINATORS);
-  return 0;
+  /* If we elided a store try to get rid of unused locals and in
+     particular stray CLOBBERs of otherwise unused variables.  */
+  return n_stores_removed != 0 ? TODO_remove_unused_locals : 0;
 }
 
 } // anon namespace
-- 
2.26.2

Reply via email to