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