summaryrefslogtreecommitdiff
path: root/gcc/tree-cfgcleanup.c
diff options
context:
space:
mode:
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2010-06-01 20:35:08 +0000
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2010-06-01 20:35:08 +0000
commit3b4fe4404cabb3a1db5cf86ab871dc86a5103725 (patch)
tree444592859a62623603f67efe10d11b809be02e54 /gcc/tree-cfgcleanup.c
parentc8f0c143cfb4c6031a3935dda0121b9dd767db7f (diff)
downloadgcc-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.c48
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;