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?

Reply via email to