diff options
author | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-06-01 20:35:08 +0000 |
---|---|---|
committer | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-06-01 20:35:08 +0000 |
commit | 3b4fe4404cabb3a1db5cf86ab871dc86a5103725 (patch) | |
tree | 444592859a62623603f67efe10d11b809be02e54 /gcc/tree-cfgcleanup.c | |
parent | c8f0c143cfb4c6031a3935dda0121b9dd767db7f (diff) | |
download | gcc-3b4fe4404cabb3a1db5cf86ab871dc86a5103725.tar.gz |
* tree-cfgcleanup.c (fixup_noreturn_call): Break out from ...;
remove return value.
(split_bbs_on_noreturn_calls) .... here.
* tree-optimize.c (execute_fixup_cfg): Fixup noreturn calls too.
* tree-flow.h (fixup_noreturn_call): New.
* testsuite/gcc.dg/lto/noreturn-1_1.c: New testcase.
* testsuite/gcc.dg/lto/noreturn-1_0.c: New testcase.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@160122 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-cfgcleanup.c')
-rw-r--r-- | gcc/tree-cfgcleanup.c | 48 |
1 files changed, 44 insertions, 4 deletions
diff --git a/gcc/tree-cfgcleanup.c b/gcc/tree-cfgcleanup.c index b8f5a549b30..10fc7aceb64 100644 --- a/gcc/tree-cfgcleanup.c +++ b/gcc/tree-cfgcleanup.c @@ -538,6 +538,49 @@ remove_forwarder_block (basic_block bb) return true; } +/* STMT is a call that has been discovered noreturn. Fixup the CFG + and remove LHS. Return true if something changed. */ + +bool +fixup_noreturn_call (gimple stmt) +{ + basic_block bb = gimple_bb (stmt); + bool changed = false; + + if (gimple_call_builtin_p (stmt, BUILT_IN_RETURN)) + return false; + + /* First split basic block if stmt is not last. */ + if (stmt != gsi_stmt (gsi_last_bb (bb))) + split_block (bb, stmt); + + changed |= remove_fallthru_edge (bb->succs); + + /* If there is LHS, remove it. */ + if (gimple_call_lhs (stmt)) + { + tree op = gimple_call_lhs (stmt); + gimple_call_set_lhs (stmt, NULL_TREE); + /* We need to remove SSA name to avoid checking. + All uses are dominated by the noreturn and thus will + be removed afterwards. */ + if (TREE_CODE (op) == SSA_NAME) + { + use_operand_p use_p; + imm_use_iterator iter; + gimple use_stmt; + + FOR_EACH_IMM_USE_STMT (use_stmt, iter, op) + FOR_EACH_IMM_USE_ON_STMT (use_p, iter) + SET_USE (use_p, error_mark_node); + } + update_stmt (stmt); + changed = true; + } + return changed; +} + + /* Split basic blocks on calls in the middle of a basic block that are now known not to return, and remove the unreachable code. */ @@ -560,13 +603,10 @@ split_bbs_on_noreturn_calls (void) || bb->index < NUM_FIXED_BLOCKS || bb->index >= n_basic_blocks || BASIC_BLOCK (bb->index) != bb - || last_stmt (bb) == stmt || !gimple_call_noreturn_p (stmt)) continue; - changed = true; - split_block (bb, stmt); - remove_fallthru_edge (bb->succs); + changed |= fixup_noreturn_call (stmt); } return changed; |