On Thu, Mar 14, 2019 at 03:10:59PM +0100, Richard Biener wrote:
> I've added a testcase.
> 
> Bootstrapped and tested on x86_64-unknown-linux-gnu, OK for trunk
> or should it wait for GCC10?

I meant something like following where we'd clean it up everything right
away after we DCE some returns_twice calls.

Except that doesn't work well, because the temporary
  cfun->calls_setjmp = true;
hack not only allows gimple_purge_dead_abnormal_call_edges through the
condition your patch was removing, but also makes then 
call_can_make_abnormal_goto
and stmt_can_make_abnormal_goto to return true.  So, maybe on top of this
patch add a bool force argument to gimple_purge_dead_abnormal_call_edges
and gimple_purge_all_dead_abnormal_call_edges and instead of the temporary
cfun->calls_setjmp = true;
in this patch pass true as force.  Plus, if we lost the last returns_twice
call and cfun->has_nonlocal_decl isn't set either, instead of calling
gimple_purge_all_dead_abnormal_call_edges just on the selected bbs call
gimple_purge_dead_abnormal_call_edges with force on on all the bbs
because if there are no nonlocal labels and no cfun->calls_setjmp used to be
set and is no longer set, then we don't need any AB edges from any calls?

--- gcc/tree-ssa-dce.c.jj       2019-01-10 11:43:17.044334047 +0100
+++ gcc/tree-ssa-dce.c  2019-03-14 17:35:47.158038514 +0100
@@ -1201,6 +1201,8 @@ eliminate_unnecessary_stmts (void)
   gimple *stmt;
   tree call;
   vec<basic_block> h;
+  bool calls_setjmp = cfun->calls_setjmp;
+  bitmap need_ab_cleanup = NULL;
 
   if (dump_file && (dump_flags & TDF_DETAILS))
     fprintf (dump_file, "\nEliminating unnecessary statements:\n");
@@ -1287,6 +1289,14 @@ eliminate_unnecessary_stmts (void)
                }
              if (!is_gimple_debug (stmt))
                something_changed = true;
+             if (calls_setjmp
+                 && is_gimple_call (stmt)
+                 && (gimple_call_flags (stmt) & ECF_RETURNS_TWICE))
+               {
+                 if (need_ab_cleanup == NULL)
+                   need_ab_cleanup = BITMAP_ALLOC (NULL);
+                 bitmap_set_bit (need_ab_cleanup, bb->index);
+               }
              remove_dead_stmt (&gsi, bb);
            }
          else if (is_gimple_call (stmt))
@@ -1358,6 +1368,17 @@ eliminate_unnecessary_stmts (void)
 
   h.release ();
 
+  if (need_ab_cleanup)
+    {
+      bool saved_calls_setjmp = cfun->calls_setjmp;
+      cfun->calls_setjmp = true;
+      if (gimple_purge_all_dead_abnormal_call_edges (need_ab_cleanup))
+       cfg_altered = true;
+      cfun->calls_setjmp = saved_calls_setjmp;
+
+      BITMAP_FREE (need_ab_cleanup);
+    }
+
   /* Since we don't track liveness of virtual PHI nodes, it is possible that we
      rendered some PHI nodes unreachable while they are still in use.
      Mark them for renaming.  */


        Jakub

Reply via email to