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