From patchwork Tue Jun 22 09:52:32 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: Fix bug with noreturn call Date: Mon, 21 Jun 2010 23:52:32 -0000 From: Eric Botcazou X-Patchwork-Id: 56447 Message-Id: <201006221152.32983.ebotcazou@adacore.com> To: Richard Guenther Cc: Jan Hubicka , gcc-patches@gcc.gnu.org > A patch to do so is pre-approved if it passes bootstrap & regtest. Here is the patch that I've been playing with this morning. * cgraphunit.c (cgraph_redirect_edge_call_stmt_to_callee): Chain the new statement and adjust VDEF only if necessary. Remove superfluous call to maybe_clean_or_replace_eh_stmt. * gimple.c (gimple_call_copy_skip_args): Use gimple_call_copy_flags to copy the flags. * gimple-iterator.c (gsi_replace): Clear BB of old statement here. * tree-inline.c (copy_bb): Do not clear BB of old statement here. Index: cgraphunit.c =================================================================== --- cgraphunit.c (revision 161023) +++ cgraphunit.c (working copy) @@ -2345,7 +2345,6 @@ cgraph_redirect_edge_call_stmt_to_callee { tree decl = gimple_call_fndecl (e->call_stmt); gimple new_stmt; - gimple_stmt_iterator gsi; #ifdef ENABLE_CHECKING struct cgraph_node *node; #endif @@ -2367,29 +2366,34 @@ cgraph_redirect_edge_call_stmt_to_callee cgraph_node_name (e->callee), e->callee->uid); print_gimple_stmt (cgraph_dump_file, e->call_stmt, 0, dump_flags); if (e->callee->clone.combined_args_to_skip) - { - fprintf (cgraph_dump_file, " combined args to skip: "); - dump_bitmap (cgraph_dump_file, e->callee->clone.combined_args_to_skip); + { + fprintf (cgraph_dump_file, " combined args to skip: "); + dump_bitmap (cgraph_dump_file, + e->callee->clone.combined_args_to_skip); } } if (e->callee->clone.combined_args_to_skip) - new_stmt = gimple_call_copy_skip_args (e->call_stmt, - e->callee->clone.combined_args_to_skip); + { + gimple_stmt_iterator gsi; + + new_stmt + = gimple_call_copy_skip_args (e->call_stmt, + e->callee->clone.combined_args_to_skip); + + if (gimple_vdef (new_stmt) + && TREE_CODE (gimple_vdef (new_stmt)) == SSA_NAME) + SSA_NAME_DEF_STMT (gimple_vdef (new_stmt)) = new_stmt; + + gsi = gsi_for_stmt (e->call_stmt); + gsi_replace (&gsi, new_stmt, true); + } else new_stmt = e->call_stmt; - if (gimple_vdef (new_stmt) - && TREE_CODE (gimple_vdef (new_stmt)) == SSA_NAME) - SSA_NAME_DEF_STMT (gimple_vdef (new_stmt)) = new_stmt; - gimple_call_set_fndecl (new_stmt, e->callee->decl); - gsi = gsi_for_stmt (e->call_stmt); - gsi_replace (&gsi, new_stmt, true); + gimple_call_set_fndecl (new_stmt, e->callee->decl); update_stmt (new_stmt); - /* Update EH information too, just in case. */ - maybe_clean_or_replace_eh_stmt (e->call_stmt, new_stmt); - cgraph_set_call_stmt_including_clones (e->caller, e->call_stmt, new_stmt); if (cgraph_dump_file) Index: gimple.c =================================================================== --- gimple.c (revision 161023) +++ gimple.c (working copy) @@ -3085,14 +3085,8 @@ gimple_call_copy_skip_args (gimple stmt, gimple_set_block (new_stmt, gimple_block (stmt)); if (gimple_has_location (stmt)) gimple_set_location (new_stmt, gimple_location (stmt)); - - /* Carry all the flags to the new GIMPLE_CALL. */ + gimple_call_copy_flags (new_stmt, stmt); gimple_call_set_chain (new_stmt, gimple_call_chain (stmt)); - gimple_call_set_tail (new_stmt, gimple_call_tail_p (stmt)); - gimple_call_set_cannot_inline (new_stmt, gimple_call_cannot_inline_p (stmt)); - gimple_call_set_return_slot_opt (new_stmt, gimple_call_return_slot_opt_p (stmt)); - gimple_call_set_from_thunk (new_stmt, gimple_call_from_thunk_p (stmt)); - gimple_call_set_va_arg_pack (new_stmt, gimple_call_va_arg_pack_p (stmt)); gimple_set_modified (new_stmt, true); Index: gimple-iterator.c =================================================================== --- gimple-iterator.c (revision 161023) +++ gimple-iterator.c (working copy) @@ -381,8 +381,12 @@ gsi_replace (gimple_stmt_iterator *gsi, maybe_clean_or_replace_eh_stmt (orig_stmt, stmt); gimple_duplicate_stmt_histograms (cfun, stmt, cfun, orig_stmt); + + /* Free all the data flow information for OLD_STMT. */ + gimple_set_bb (orig_stmt, NULL); gimple_remove_stmt_histograms (cfun, orig_stmt); delink_stmt_imm_use (orig_stmt); + *gsi_stmt_ptr (gsi) = stmt; gimple_set_modified (stmt, true); update_modified_stmt (stmt); Index: tree-inline.c =================================================================== --- tree-inline.c (revision 161023) +++ tree-inline.c (working copy) @@ -1604,7 +1604,6 @@ copy_bb (copy_body_data *id, basic_block gimple_call_set_lhs (new_call, gimple_call_lhs (stmt)); gsi_replace (©_gsi, new_call, false); - gimple_set_bb (stmt, NULL); stmt = new_call; } else if (is_gimple_call (stmt)