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