From: Richard Biener Date: Wed, 27 Nov 2019 08:52:17 +0000 (+0000) Subject: re PR lto/92674 (ICE in gimple_phi_arg, at gimple.h:4406 since r240291) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=cd3f923b0d5c2cb087840db55a7578c9b363276b;p=gcc.git re PR lto/92674 (ICE in gimple_phi_arg, at gimple.h:4406 since r240291) 2019-11-27 Richard Biener PR middle-end/92674 * tree-inline.c (expand_call_inline): Delay purging EH/abnormal edges and instead record blocks in bitmap. (gimple_expand_calls_inline): Adjust. (fold_marked_statements): Delay EH cleanup until all folding is done. (optimize_inline_calls): Do EH/abnormal cleanup for calls after inlining finished. From-SVN: r278757 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 358602d744e..1235b4411c2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2019-11-27 Richard Biener + + PR middle-end/92674 + * tree-inline.c (expand_call_inline): Delay purging EH/abnormal + edges and instead record blocks in bitmap. + (gimple_expand_calls_inline): Adjust. + (fold_marked_statements): Delay EH cleanup until all folding is + done. + (optimize_inline_calls): Do EH/abnormal cleanup for calls after + inlining finished. + 2019-11-27 Bernd Schmidt * auto-inc-dec.c (merge_in_block): Allow autoinc in jumps unless diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index bdc332dcc23..eecf5c6cf1c 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -4623,7 +4623,8 @@ reset_debug_bindings (copy_body_data *id, gimple_stmt_iterator gsi) /* If STMT is a GIMPLE_CALL, replace it with its inline expansion. */ static bool -expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id) +expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id, + bitmap to_purge) { tree use_retvar; tree fn; @@ -4768,7 +4769,7 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id) gimple_call_set_fndecl (stmt, edge->callee->decl); update_stmt (stmt); id->src_node->remove (); - expand_call_inline (bb, stmt, id); + expand_call_inline (bb, stmt, id, to_purge); maybe_remove_unused_call_args (cfun, stmt); return true; } @@ -5156,10 +5157,7 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id) } if (purge_dead_abnormal_edges) - { - gimple_purge_dead_eh_edges (return_block); - gimple_purge_dead_abnormal_call_edges (return_block); - } + bitmap_set_bit (to_purge, return_block->index); /* If the value of the new expression is ignored, that's OK. We don't warn about this for CALL_EXPRs, so we shouldn't warn about @@ -5197,7 +5195,8 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id) in a MODIFY_EXPR. */ static bool -gimple_expand_calls_inline (basic_block bb, copy_body_data *id) +gimple_expand_calls_inline (basic_block bb, copy_body_data *id, + bitmap to_purge) { gimple_stmt_iterator gsi; bool inlined = false; @@ -5209,7 +5208,7 @@ gimple_expand_calls_inline (basic_block bb, copy_body_data *id) if (is_gimple_call (stmt) && !gimple_call_internal_p (stmt)) - inlined |= expand_call_inline (bb, stmt, id); + inlined |= expand_call_inline (bb, stmt, id, to_purge); } return inlined; @@ -5222,6 +5221,7 @@ gimple_expand_calls_inline (basic_block bb, copy_body_data *id) static void fold_marked_statements (int first, hash_set *statements) { + auto_bitmap to_purge; for (; first < last_basic_block_for_fn (cfun); first++) if (BASIC_BLOCK_FOR_FN (cfun, first)) { @@ -5233,7 +5233,8 @@ fold_marked_statements (int first, hash_set *statements) if (statements->contains (gsi_stmt (gsi))) { gimple *old_stmt = gsi_stmt (gsi); - tree old_decl = is_gimple_call (old_stmt) ? gimple_call_fndecl (old_stmt) : 0; + tree old_decl + = is_gimple_call (old_stmt) ? gimple_call_fndecl (old_stmt) : 0; if (old_decl && fndecl_built_in_p (old_decl)) { @@ -5277,8 +5278,7 @@ fold_marked_statements (int first, hash_set *statements) is mood anyway. */ if (maybe_clean_or_replace_eh_stmt (old_stmt, new_stmt)) - gimple_purge_dead_eh_edges ( - BASIC_BLOCK_FOR_FN (cfun, first)); + bitmap_set_bit (to_purge, first); break; } gsi_next (&i2); @@ -5298,11 +5298,11 @@ fold_marked_statements (int first, hash_set *statements) new_stmt); if (maybe_clean_or_replace_eh_stmt (old_stmt, new_stmt)) - gimple_purge_dead_eh_edges (BASIC_BLOCK_FOR_FN (cfun, - first)); + bitmap_set_bit (to_purge, first); } } } + gimple_purge_all_dead_eh_edges (to_purge); } /* Expand calls to inline functions in the body of FN. */ @@ -5348,8 +5348,9 @@ optimize_inline_calls (tree fn) will split id->current_basic_block, and the new blocks will follow it; we'll trudge through them, processing their CALL_EXPRs along the way. */ + auto_bitmap to_purge; FOR_EACH_BB_FN (bb, cfun) - inlined_p |= gimple_expand_calls_inline (bb, &id); + inlined_p |= gimple_expand_calls_inline (bb, &id, to_purge); pop_gimplify_context (NULL); @@ -5369,6 +5370,21 @@ optimize_inline_calls (tree fn) fold_marked_statements (last, id.statements_to_fold); delete id.statements_to_fold; + /* Finally purge EH and abnormal edges from the call stmts we inlined. + We need to do this after fold_marked_statements since that may walk + the SSA use-def chain. */ + unsigned i; + bitmap_iterator bi; + EXECUTE_IF_SET_IN_BITMAP (to_purge, 0, i, bi) + { + basic_block bb = BASIC_BLOCK_FOR_FN (cfun, i); + if (bb) + { + gimple_purge_dead_eh_edges (bb); + gimple_purge_dead_abnormal_call_edges (bb); + } + } + gcc_assert (!id.debug_stmts.exists ()); /* If we didn't inline into the function there is nothing to do. */