re PR tree-optimization/19484 (function pointer propagation fails for noreturn functions)
PR tree-optimization/19484 * tree-cfg.c (remove_fallthru_edge): New function. (cleanup_control_flow): Remove fallthru edges from calls that are now known not to return. From-SVN: r94070
This commit is contained in:
parent
111e0c9f4b
commit
d7f3fc1990
@ -1,3 +1,10 @@
|
||||
2005-01-22 Richard Sandiford <rsandifo@redhat.com>
|
||||
|
||||
PR tree-optimization/19484
|
||||
* tree-cfg.c (remove_fallthru_edge): New function.
|
||||
(cleanup_control_flow): Remove fallthru edges from calls that are
|
||||
now known not to return.
|
||||
|
||||
2005-01-20 Daniel Berlin <dberlin@dberlin.org>
|
||||
|
||||
Fix PR tree-optimization/19038
|
||||
|
@ -1,3 +1,8 @@
|
||||
2005-01-22 Richard Sandiford <rsandifo@redhat.com>
|
||||
|
||||
PR tree-optimization/19484
|
||||
* gcc.c-torture/compile/20050122-[12].c: New tests.
|
||||
|
||||
2005-01-22 Paul Brook <paul@codesourcery.com>
|
||||
|
||||
* gfortran.dg/implicit_2.f90: New test.
|
||||
|
12
gcc/testsuite/gcc.c-torture/compile/20050122-1.c
Normal file
12
gcc/testsuite/gcc.c-torture/compile/20050122-1.c
Normal file
@ -0,0 +1,12 @@
|
||||
/* From PR 19484. */
|
||||
extern void foo (void) __attribute__((noreturn));
|
||||
int n;
|
||||
|
||||
void
|
||||
g (void)
|
||||
{
|
||||
void (*f) (void) = foo;
|
||||
if (n)
|
||||
f ();
|
||||
n = 1;
|
||||
}
|
19
gcc/testsuite/gcc.c-torture/compile/20050122-2.c
Normal file
19
gcc/testsuite/gcc.c-torture/compile/20050122-2.c
Normal file
@ -0,0 +1,19 @@
|
||||
/* Related to PR 19484. */
|
||||
extern void foo (void) __attribute__((noreturn));
|
||||
int n;
|
||||
|
||||
void
|
||||
g (void)
|
||||
{
|
||||
__label__ lab;
|
||||
void h (void) { if (n == 2) goto lab; }
|
||||
void (*f1) (void) = foo;
|
||||
void (*f2) (void) = h;
|
||||
|
||||
f2 ();
|
||||
if (n)
|
||||
f1 ();
|
||||
n = 1;
|
||||
lab:
|
||||
n++;
|
||||
}
|
@ -114,6 +114,7 @@ static void make_goto_expr_edges (basic_block);
|
||||
static edge tree_redirect_edge_and_branch (edge, basic_block);
|
||||
static edge tree_try_redirect_by_replacing_jump (edge, basic_block);
|
||||
static void split_critical_edges (void);
|
||||
static bool remove_fallthru_edge (VEC(edge) *);
|
||||
|
||||
/* Various helpers. */
|
||||
static inline bool stmt_starts_bb_p (tree, tree);
|
||||
@ -2059,7 +2060,7 @@ cleanup_control_flow (void)
|
||||
basic_block bb;
|
||||
block_stmt_iterator bsi;
|
||||
bool retval = false;
|
||||
tree stmt;
|
||||
tree stmt, call;
|
||||
|
||||
FOR_EACH_BB (bb)
|
||||
{
|
||||
@ -2072,6 +2073,17 @@ cleanup_control_flow (void)
|
||||
if (TREE_CODE (stmt) == COND_EXPR
|
||||
|| TREE_CODE (stmt) == SWITCH_EXPR)
|
||||
retval |= cleanup_control_expr_graph (bb, bsi);
|
||||
|
||||
/* Check for indirect calls that have been turned into
|
||||
noreturn calls. */
|
||||
call = get_call_expr_in (stmt);
|
||||
if (call != 0
|
||||
&& (call_expr_flags (call) & ECF_NORETURN) != 0
|
||||
&& remove_fallthru_edge (bb->succs))
|
||||
{
|
||||
free_dominance_info (CDI_DOMINATORS);
|
||||
retval = true;
|
||||
}
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
@ -2140,6 +2152,22 @@ cleanup_control_expr_graph (basic_block bb, block_stmt_iterator bsi)
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* Remove any fallthru edge from EV. Return true if an edge was removed. */
|
||||
|
||||
static bool
|
||||
remove_fallthru_edge (VEC(edge) *ev)
|
||||
{
|
||||
edge_iterator ei;
|
||||
edge e;
|
||||
|
||||
FOR_EACH_EDGE (e, ei, ev)
|
||||
if ((e->flags & EDGE_FALLTHRU) != 0)
|
||||
{
|
||||
remove_edge (e);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Given a basic block BB ending with COND_EXPR or SWITCH_EXPR, and a
|
||||
predicate VAL, return the edge that will be taken out of the block.
|
||||
|
Loading…
Reference in New Issue
Block a user