tree-flow.h (gimple_purge_all_dead_abnormal_call_edges): Declare.

* tree-flow.h (gimple_purge_all_dead_abnormal_call_edges): Declare.
	* tree-cfg.c (gimple_purge_dead_abnormal_call_edges): Move around and
	rewrite modelled on gimple_purge_dead_eh_edges.
	(gimple_purge_all_dead_abnormal_call_edges): New function.
	* tree-inline.c (expand_call_inline): Call gimple_purge_dead_eh_edges
	directly instead of through gimple_purge_dead_abnormal_call_edges.
	* tree-ssa-pre.c (need_ab_cleanup): New static variable.
	(eliminate): Set bit in need_ab_cleanup for the basic block if we have
	removed AB side-effects from one of its statements.
	(init_pre): Initialize need_ab_cleanup.
	(fini_pre): Purge dead abnormal call edges and clean up the CFG if bits
	are set in need_ab_cleanup.  Free need_ab_cleanup afterward.

From-SVN: r165646
This commit is contained in:
Eric Botcazou 2010-10-18 16:44:38 +00:00 committed by Eric Botcazou
parent 84628aa836
commit 30fd588162
5 changed files with 123 additions and 41 deletions

View File

@ -1,3 +1,18 @@
2010-10-18 Eric Botcazou <ebotcazou@adacore.com>
* tree-flow.h (gimple_purge_all_dead_abnormal_call_edges): Declare.
* tree-cfg.c (gimple_purge_dead_abnormal_call_edges): Move around and
rewrite modelled on gimple_purge_dead_eh_edges.
(gimple_purge_all_dead_abnormal_call_edges): New function.
* tree-inline.c (expand_call_inline): Call gimple_purge_dead_eh_edges
directly instead of through gimple_purge_dead_abnormal_call_edges.
* tree-ssa-pre.c (need_ab_cleanup): New static variable.
(eliminate): Set bit in need_ab_cleanup for the basic block if we have
removed AB side-effects from one of its statements.
(init_pre): Initialize need_ab_cleanup.
(fini_pre): Purge dead abnormal call edges and clean up the CFG if bits
are set in need_ab_cleanup. Free need_ab_cleanup afterward.
2010-10-18 Jakub Jelinek <jakub@redhat.com>
PR c/46015

View File

@ -6824,39 +6824,6 @@ gimple_flow_call_edges_add (sbitmap blocks)
return blocks_split;
}
/* Purge dead abnormal call edges from basic block BB. */
bool
gimple_purge_dead_abnormal_call_edges (basic_block bb)
{
bool changed = gimple_purge_dead_eh_edges (bb);
if (cfun->has_nonlocal_label)
{
gimple stmt = last_stmt (bb);
edge_iterator ei;
edge e;
if (!(stmt && stmt_can_make_abnormal_goto (stmt)))
for (ei = ei_start (bb->succs); (e = ei_safe_edge (ei)); )
{
if (e->flags & EDGE_ABNORMAL)
{
remove_edge (e);
changed = true;
}
else
ei_next (&ei);
}
/* See gimple_purge_dead_eh_edges below. */
if (changed)
free_dominance_info (CDI_DOMINATORS);
}
return changed;
}
/* Removes edge E and all the blocks dominated by it, and updates dominance
information. The IL in E->src needs to be updated separately.
If dominance info is not available, only the edge E is removed.*/
@ -7010,6 +6977,8 @@ gimple_purge_dead_eh_edges (basic_block bb)
return changed;
}
/* Purge dead EH edges from basic block listed in BLOCKS. */
bool
gimple_purge_all_dead_eh_edges (const_bitmap blocks)
{
@ -7031,6 +7000,59 @@ gimple_purge_all_dead_eh_edges (const_bitmap blocks)
return changed;
}
/* Purge dead abnormal call edges from basic block BB. */
bool
gimple_purge_dead_abnormal_call_edges (basic_block bb)
{
bool changed = false;
edge e;
edge_iterator ei;
gimple stmt = last_stmt (bb);
if (!cfun->has_nonlocal_label)
return false;
if (stmt && stmt_can_make_abnormal_goto (stmt))
return false;
for (ei = ei_start (bb->succs); (e = ei_safe_edge (ei)); )
{
if (e->flags & EDGE_ABNORMAL)
{
remove_edge_and_dominated_blocks (e);
changed = true;
}
else
ei_next (&ei);
}
return changed;
}
/* Purge dead abnormal call edges from basic block listed in BLOCKS. */
bool
gimple_purge_all_dead_abnormal_call_edges (const_bitmap blocks)
{
bool changed = false;
unsigned i;
bitmap_iterator bi;
EXECUTE_IF_SET_IN_BITMAP (blocks, 0, i, bi)
{
basic_block bb = BASIC_BLOCK (i);
/* Earlier gimple_purge_dead_abnormal_call_edges could have removed
this basic block already. */
gcc_assert (bb || changed);
if (bb != NULL)
changed |= gimple_purge_dead_abnormal_call_edges (bb);
}
return changed;
}
/* This function is called whenever a new edge is created or
redirected. */

View File

@ -450,9 +450,10 @@ extern void gather_blocks_in_sese_region (basic_block entry, basic_block exit,
VEC(basic_block,heap) **bbs_p);
extern void add_phi_args_after_copy_bb (basic_block);
extern void add_phi_args_after_copy (basic_block *, unsigned, edge);
extern bool gimple_purge_dead_abnormal_call_edges (basic_block);
extern bool gimple_purge_dead_eh_edges (basic_block);
extern bool gimple_purge_all_dead_eh_edges (const_bitmap);
extern bool gimple_purge_dead_abnormal_call_edges (basic_block);
extern bool gimple_purge_all_dead_abnormal_call_edges (const_bitmap);
extern tree gimplify_build1 (gimple_stmt_iterator *, enum tree_code,
tree, tree);
extern tree gimplify_build2 (gimple_stmt_iterator *, enum tree_code,

View File

@ -4010,7 +4010,10 @@ expand_call_inline (basic_block bb, gimple stmt, copy_body_data *id)
}
if (purge_dead_abnormal_edges)
gimple_purge_dead_abnormal_call_edges (return_block);
{
gimple_purge_dead_eh_edges (return_block);
gimple_purge_dead_abnormal_call_edges (return_block);
}
/* If the value of the new expression is ignored, that's OK. We
don't warn about this for CALL_EXPRs, so we shouldn't warn about

View File

@ -484,10 +484,12 @@ static tree pretemp;
static tree storetemp;
static tree prephitemp;
/* Set of blocks with statements that have had its EH information
cleaned up. */
/* Set of blocks with statements that have had their EH properties changed. */
static bitmap need_eh_cleanup;
/* Set of blocks with statements that have had their AB properties changed. */
static bitmap need_ab_cleanup;
/* The phi_translate_table caches phi translations for a given
expression and predecessor. */
@ -4253,6 +4255,10 @@ eliminate (void)
|| TREE_CODE (rhs) != SSA_NAME
|| may_propagate_copy (rhs, sprime)))
{
bool can_make_abnormal_goto
= is_gimple_call (stmt)
&& stmt_can_make_abnormal_goto (stmt);
gcc_assert (sprime != rhs);
if (dump_file && (dump_flags & TDF_DETAILS))
@ -4281,14 +4287,24 @@ eliminate (void)
stmt = gsi_stmt (gsi);
update_stmt (stmt);
/* If we removed EH side effects from the statement, clean
/* If we removed EH side-effects from the statement, clean
its EH information. */
if (maybe_clean_or_replace_eh_stmt (stmt, stmt))
{
bitmap_set_bit (need_eh_cleanup,
gimple_bb (stmt)->index);
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, " Removed EH side effects.\n");
fprintf (dump_file, " Removed EH side-effects.\n");
}
/* Likewise for AB side-effects. */
if (can_make_abnormal_goto
&& !stmt_can_make_abnormal_goto (stmt))
{
bitmap_set_bit (need_ab_cleanup,
gimple_bb (stmt)->index);
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, " Removed AB side-effects.\n");
}
}
}
@ -4345,13 +4361,16 @@ eliminate (void)
}
/* Visit indirect calls and turn them into direct calls if
possible. */
if (gimple_code (stmt) == GIMPLE_CALL
if (is_gimple_call (stmt)
&& TREE_CODE (gimple_call_fn (stmt)) == SSA_NAME)
{
tree fn = VN_INFO (gimple_call_fn (stmt))->valnum;
if (TREE_CODE (fn) == ADDR_EXPR
&& TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL)
{
bool can_make_abnormal_goto
= stmt_can_make_abnormal_goto (stmt);
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Replacing call target with ");
@ -4362,12 +4381,25 @@ eliminate (void)
gimple_call_set_fn (stmt, fn);
update_stmt (stmt);
/* If we removed EH side-effects from the statement, clean
its EH information. */
if (maybe_clean_or_replace_eh_stmt (stmt, stmt))
{
bitmap_set_bit (need_eh_cleanup,
gimple_bb (stmt)->index);
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, " Removed EH side effects.\n");
fprintf (dump_file, " Removed EH side-effects.\n");
}
/* Likewise for AB side-effects. */
if (can_make_abnormal_goto
&& !stmt_can_make_abnormal_goto (stmt))
{
bitmap_set_bit (need_ab_cleanup,
gimple_bb (stmt)->index);
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, " Removed AB side-effects.\n");
}
/* Changing an indirect call to a direct call may
@ -4746,6 +4778,7 @@ init_pre (bool do_fre)
}
need_eh_cleanup = BITMAP_ALLOC (NULL);
need_ab_cleanup = BITMAP_ALLOC (NULL);
}
@ -4777,6 +4810,14 @@ fini_pre (bool do_fre)
BITMAP_FREE (need_eh_cleanup);
if (!bitmap_empty_p (need_ab_cleanup))
{
gimple_purge_all_dead_abnormal_call_edges (need_ab_cleanup);
cleanup_tree_cfg ();
}
BITMAP_FREE (need_ab_cleanup);
if (!do_fre)
loop_optimizer_finalize ();
}