https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91164
Jakub Jelinek <jakub at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |jakub at gcc dot gnu.org
--- Comment #4 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
The problem is that DSE removes some trapping insns, we then
3621 if ((locally_deleted || globally_deleted)
3622 && cfun->can_throw_non_call_exceptions
3623 && purge_all_dead_edges ())
3624 cleanup_cfg (0);
and cleanup_cfg does:
if (delete_unreachable_blocks ())
{
changed = true;
...
but doesn't actually free_dominance_info (CDI_DOMINATORS);
Shall we call that in cleanup_cfg if changed before returning?
If there are loops and there is no dbg_cnt early out, we actually do:
timevar_push (TV_REPAIR_LOOPS);
/* The above doesn't preserve dominance info if available. */
gcc_assert (!dom_info_available_p (CDI_DOMINATORS));
calculate_dominance_info (CDI_DOMINATORS);
fix_loop_structure (NULL);
free_dominance_info (CDI_DOMINATORS);
timevar_pop (TV_REPAIR_LOOPS);
but not for the case where there are no loops or dbg_cnt early out.
Untested patch fixes it:
--- gcc/cfgcleanup.c.jj 2019-07-10 15:52:56.801588077 +0200
+++ gcc/cfgcleanup.c 2019-07-15 11:39:31.661694659 +0200
@@ -3170,7 +3170,11 @@ cleanup_cfg (int mode)
add_noreturn_fake_exit_edges ();
if (!dbg_cnt (cfg_cleanup))
- return changed;
+ {
+ if (changed)
+ free_dominance_info (CDI_DOMINATORS);
+ return changed;
+ }
while (try_optimize_cfg (mode))
{
@@ -3213,8 +3217,7 @@ cleanup_cfg (int mode)
/* ??? We probably do this way too often. */
if (current_loops
- && (changed
- || (mode & CLEANUP_CFG_CHANGED)))
+ && (changed || (mode & CLEANUP_CFG_CHANGED)))
{
timevar_push (TV_REPAIR_LOOPS);
/* The above doesn't preserve dominance info if available. */
@@ -3224,6 +3227,8 @@ cleanup_cfg (int mode)
free_dominance_info (CDI_DOMINATORS);
timevar_pop (TV_REPAIR_LOOPS);
}
+ else if (changed)
+ free_dominance_info (CDI_DOMINATORS);
timevar_pop (TV_CLEANUP_CFG);
Or is there some less expensive way of getting it recomputed, just around the
blocks we've removed as unreachable?