Commit 566d09ef by Jan Hubicka Committed by Jan Hubicka

tree-cfgcleanup.c (fixup_noreturn_call): Break out from ...; remove return value.


	* 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.

From-SVN: r160122
parent fb9ef4c1
2010-06-01 Jan Hubicka <jh@suse.cz>
* 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.
2010-06-01 Jan Hubicka <jh@suse.cz>
* emit-rtl.c (remove_insn): Fix thinko in prevoius patch.
2010-06-01 Nathan Froyd <froydnj@codesourcery.com>
......
2010-05-31 Jan Hubicka <jh@suse.cz>
* testsuite/gcc.dg/lto/noreturn-1_1.c: New testcase.
* testsuite/gcc.dg/lto/noreturn-1_0.c: New testcase.
2010-05-31 Thomas Koenig <tkoenig@gcc.gnu.org>
PR fortran/36928
......
......@@ -5,17 +5,3 @@ call_me (void)
{
exit (0);
}
void exit (int);
__attribute__ ((noreturn))
int
call_me (void)
{
exit (0);
}
void exit (int);
__attribute__ ((noreturn))
int
call_me (void)
{
exit (0);
}
......@@ -7,21 +7,3 @@ main(void)
{
return call_me ();
}
/* { dg-lto-do run } */
/* { dg-lto-options {{-O2 -fwhopr} } } */
int call_me (void);
int
main(void)
{
return call_me ();
}
/* { dg-lto-do run } */
/* { dg-lto-options {{-O2 -fwhopr} } } */
int call_me (void);
int
main(void)
{
return call_me ();
}
......@@ -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;
......
......@@ -870,6 +870,7 @@ tree maybe_fold_tmr (tree);
unsigned int execute_free_datastructures (void);
unsigned int execute_fixup_cfg (void);
bool fixup_noreturn_call (gimple stmt);
#include "tree-flow-inline.h"
......
......@@ -231,7 +231,8 @@ execute_free_datastructures (void)
}
/* Pass: fixup_cfg. IPA passes, compilation of earlier functions or inlining
might have changed some properties, such as marked functions nothrow.
might have changed some properties, such as marked functions nothrow,
pure, const or noreturn.
Remove redundant edges and basic blocks, and create new ones if necessary.
This pass can't be executed as stand alone pass from pass manager, because
......@@ -267,19 +268,23 @@ execute_fixup_cfg (void)
tree decl = is_gimple_call (stmt)
? gimple_call_fndecl (stmt)
: NULL;
if (decl
&& gimple_call_flags (stmt) & (ECF_CONST
| ECF_PURE
| ECF_LOOPING_CONST_OR_PURE))
if (decl)
{
if (gimple_in_ssa_p (cfun))
int flags = gimple_call_flags (stmt);
if (flags & (ECF_CONST | ECF_PURE | ECF_LOOPING_CONST_OR_PURE))
{
todo |= TODO_update_ssa | TODO_cleanup_cfg;
mark_symbols_for_renaming (stmt);
update_stmt (stmt);
if (gimple_in_ssa_p (cfun))
{
todo |= TODO_update_ssa | TODO_cleanup_cfg;
mark_symbols_for_renaming (stmt);
update_stmt (stmt);
}
}
}
if (flags & ECF_NORETURN
&& fixup_noreturn_call (stmt))
todo |= TODO_cleanup_cfg;
}
maybe_clean_eh_stmt (stmt);
}
......@@ -293,6 +298,13 @@ execute_fixup_cfg (void)
if (count_scale != REG_BR_PROB_BASE)
compute_function_frequency ();
/* We just processed all calls. */
if (cfun->gimple_df)
{
VEC_free (gimple, gc, MODIFIED_NORETURN_CALLS (cfun));
MODIFIED_NORETURN_CALLS (cfun) = NULL;
}
/* Dump a textual representation of the flowgraph. */
if (dump_file)
gimple_dump_cfg (dump_file, dump_flags);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment