Commit 672987e8 by Zdenek Dvorak Committed by Zdenek Dvorak

tree-cfgcleanup.c (cfgcleanup_altered_bbs): New global variable.

	* tree-cfgcleanup.c (cfgcleanup_altered_bbs): New global variable.
	(remove_fallthru_edge): Use remove_edge_and_dominated_blocks.
	(cleanup_control_expr_graph): Do not invalidate dominance info.
	Record altered blocks.
	(cleanup_control_flow, cleanup_forwarder_blocks): Removed.
	(cleanup_control_flow_bb, split_bbs_on_noreturn_calls,
	cleanup_tree_cfg_bb): New functions.
	(remove_forwarder_block): Do not maintain the worklist of blocks.
	Record altered blocks.
	(cleanup_tree_cfg_1): Iterate over cfgcleanup_altered_bbs,
	not over whole cfg.
	(cleanup_tree_cfg): Do not iterate cleanup_tree_cfg_1.  Only call
	delete_unreachable_blocks if dominators are not available.
	* tree-inline.c (optimize_inline_calls): Free dominance information
	earlier.
	* tree-flow.h (remove_edge_and_dominated_blocks,
	cfgcleanup_altered_bbs): Altered.
	* tree-cfg.c (replace_uses_by, tree_merge_blocks): Record altered
	blocks.
	(get_all_dominated_blocks, remove_edge_and_dominated_blocks): New
	functions.
	(tree_purge_dead_eh_edges): Use remove_edge_and_dominated_blocks,
	do not invalidate dominators.

From-SVN: r124203
parent 468a823b
2007-04-27 Zdenek Dvorak <dvorakz@suse.cz>
* tree-cfgcleanup.c (cfgcleanup_altered_bbs): New global variable.
(remove_fallthru_edge): Use remove_edge_and_dominated_blocks.
(cleanup_control_expr_graph): Do not invalidate dominance info.
Record altered blocks.
(cleanup_control_flow, cleanup_forwarder_blocks): Removed.
(cleanup_control_flow_bb, split_bbs_on_noreturn_calls,
cleanup_tree_cfg_bb): New functions.
(remove_forwarder_block): Do not maintain the worklist of blocks.
Record altered blocks.
(cleanup_tree_cfg_1): Iterate over cfgcleanup_altered_bbs,
not over whole cfg.
(cleanup_tree_cfg): Do not iterate cleanup_tree_cfg_1. Only call
delete_unreachable_blocks if dominators are not available.
* tree-inline.c (optimize_inline_calls): Free dominance information
earlier.
* tree-flow.h (remove_edge_and_dominated_blocks,
cfgcleanup_altered_bbs): Altered.
* tree-cfg.c (replace_uses_by, tree_merge_blocks): Record altered
blocks.
(get_all_dominated_blocks, remove_edge_and_dominated_blocks): New
functions.
(tree_purge_dead_eh_edges): Use remove_edge_and_dominated_blocks,
do not invalidate dominators.
2007-04-26 Anatoly Sokolov <aesok@post.ru> 2007-04-26 Anatoly Sokolov <aesok@post.ru>
* config/avr/avr.c (avr_mcu_types): Add support for ATmega8HVA and * config/avr/avr.c (avr_mcu_types): Add support for ATmega8HVA and
......
...@@ -1199,6 +1199,8 @@ replace_uses_by (tree name, tree val) ...@@ -1199,6 +1199,8 @@ replace_uses_by (tree name, tree val)
tree rhs; tree rhs;
fold_stmt_inplace (stmt); fold_stmt_inplace (stmt);
if (cfgcleanup_altered_bbs)
bitmap_set_bit (cfgcleanup_altered_bbs, bb_for_stmt (stmt)->index);
/* FIXME. This should go in pop_stmt_changes. */ /* FIXME. This should go in pop_stmt_changes. */
rhs = get_rhs (stmt); rhs = get_rhs (stmt);
...@@ -1312,6 +1314,9 @@ tree_merge_blocks (basic_block a, basic_block b) ...@@ -1312,6 +1314,9 @@ tree_merge_blocks (basic_block a, basic_block b)
last = tsi_last (bb_stmt_list (a)); last = tsi_last (bb_stmt_list (a));
tsi_link_after (&last, bb_stmt_list (b), TSI_NEW_STMT); tsi_link_after (&last, bb_stmt_list (b), TSI_NEW_STMT);
set_bb_stmt_list (b, NULL_TREE); set_bb_stmt_list (b, NULL_TREE);
if (cfgcleanup_altered_bbs)
bitmap_set_bit (cfgcleanup_altered_bbs, a->index);
} }
...@@ -5429,6 +5434,144 @@ tree_purge_dead_abnormal_call_edges (basic_block bb) ...@@ -5429,6 +5434,144 @@ tree_purge_dead_abnormal_call_edges (basic_block bb)
return changed; return changed;
} }
/* Stores all basic blocks dominated by BB to DOM_BBS. */
static void
get_all_dominated_blocks (basic_block bb, VEC (basic_block, heap) **dom_bbs)
{
basic_block son;
VEC_safe_push (basic_block, heap, *dom_bbs, bb);
for (son = first_dom_son (CDI_DOMINATORS, bb);
son;
son = next_dom_son (CDI_DOMINATORS, son))
get_all_dominated_blocks (son, dom_bbs);
}
/* 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.*/
void
remove_edge_and_dominated_blocks (edge e)
{
VEC (basic_block, heap) *bbs_to_remove = NULL;
VEC (basic_block, heap) *bbs_to_fix_dom = NULL;
bitmap df, df_idom;
edge f;
edge_iterator ei;
bool none_removed = false;
unsigned i;
basic_block bb, dbb;
bitmap_iterator bi;
if (!dom_computed[CDI_DOMINATORS])
{
remove_edge (e);
return;
}
/* No updating is needed for edges to exit. */
if (e->dest == EXIT_BLOCK_PTR)
{
if (cfgcleanup_altered_bbs)
bitmap_set_bit (cfgcleanup_altered_bbs, e->src->index);
remove_edge (e);
return;
}
/* First, we find the basic blocks to remove. If E->dest has a predecessor
that is not dominated by E->dest, then this set is empty. Otherwise,
all the basic blocks dominated by E->dest are removed.
Also, to DF_IDOM we store the immediate dominators of the blocks in
the dominance frontier of E (i.e., of the successors of the
removed blocks, if there are any, and of E->dest otherwise). */
FOR_EACH_EDGE (f, ei, e->dest->preds)
{
if (f == e)
continue;
if (!dominated_by_p (CDI_DOMINATORS, f->src, e->dest))
{
none_removed = true;
break;
}
}
df = BITMAP_ALLOC (NULL);
df_idom = BITMAP_ALLOC (NULL);
if (none_removed)
bitmap_set_bit (df_idom,
get_immediate_dominator (CDI_DOMINATORS, e->dest)->index);
else
{
get_all_dominated_blocks (e->dest, &bbs_to_remove);
for (i = 0; VEC_iterate (basic_block, bbs_to_remove, i, bb); i++)
{
FOR_EACH_EDGE (f, ei, bb->succs)
{
if (f->dest != EXIT_BLOCK_PTR)
bitmap_set_bit (df, f->dest->index);
}
}
for (i = 0; VEC_iterate (basic_block, bbs_to_remove, i, bb); i++)
bitmap_clear_bit (df, bb->index);
EXECUTE_IF_SET_IN_BITMAP (df, 0, i, bi)
{
bb = BASIC_BLOCK (i);
bitmap_set_bit (df_idom,
get_immediate_dominator (CDI_DOMINATORS, bb)->index);
}
}
if (cfgcleanup_altered_bbs)
{
/* Record the set of the altered basic blocks. */
bitmap_set_bit (cfgcleanup_altered_bbs, e->src->index);
bitmap_ior_into (cfgcleanup_altered_bbs, df);
}
/* Remove E and the cancelled blocks. */
if (none_removed)
remove_edge (e);
else
{
for (i = 0; VEC_iterate (basic_block, bbs_to_remove, i, bb); i++)
delete_basic_block (bb);
}
/* Update the dominance information. The immediate dominator may change only
for blocks whose immediate dominator belongs to DF_IDOM:
Suppose that idom(X) = Y before removal of E and idom(X) != Y after the
removal. Let Z the arbitrary block such that idom(Z) = Y and
Z dominates X after the removal. Before removal, there exists a path P
from Y to X that avoids Z. Let F be the last edge on P that is
removed, and let W = F->dest. Before removal, idom(W) = Y (since Y
dominates W, and because of P, Z does not dominate W), and W belongs to
the dominance frontier of E. Therefore, Y belongs to DF_IDOM. */
EXECUTE_IF_SET_IN_BITMAP (df_idom, 0, i, bi)
{
bb = BASIC_BLOCK (i);
for (dbb = first_dom_son (CDI_DOMINATORS, bb);
dbb;
dbb = next_dom_son (CDI_DOMINATORS, dbb))
VEC_safe_push (basic_block, heap, bbs_to_fix_dom, dbb);
}
iterate_fix_dominators (CDI_DOMINATORS,
VEC_address (basic_block, bbs_to_fix_dom),
VEC_length (basic_block, bbs_to_fix_dom));
BITMAP_FREE (df);
BITMAP_FREE (df_idom);
VEC_free (basic_block, heap, bbs_to_remove);
VEC_free (basic_block, heap, bbs_to_fix_dom);
}
/* Purge dead EH edges from basic block BB. */ /* Purge dead EH edges from basic block BB. */
bool bool
...@@ -5446,33 +5589,13 @@ tree_purge_dead_eh_edges (basic_block bb) ...@@ -5446,33 +5589,13 @@ tree_purge_dead_eh_edges (basic_block bb)
{ {
if (e->flags & EDGE_EH) if (e->flags & EDGE_EH)
{ {
remove_edge (e); remove_edge_and_dominated_blocks (e);
changed = true; changed = true;
} }
else else
ei_next (&ei); ei_next (&ei);
} }
/* Removal of dead EH edges might change dominators of not
just immediate successors. E.g. when bb1 is changed so that
it no longer can throw and bb1->bb3 and bb1->bb4 are dead
eh edges purged by this function in:
0
/ \
v v
1-->2
/ \ |
v v |
3-->4 |
\ v
--->5
|
-
idom(bb5) must be recomputed. For now just free the dominance
info. */
if (changed)
free_dominance_info (CDI_DOMINATORS);
return changed; return changed;
} }
......
...@@ -778,8 +778,10 @@ extern void start_recording_case_labels (void); ...@@ -778,8 +778,10 @@ extern void start_recording_case_labels (void);
extern void end_recording_case_labels (void); extern void end_recording_case_labels (void);
extern basic_block move_sese_region_to_fn (struct function *, basic_block, extern basic_block move_sese_region_to_fn (struct function *, basic_block,
basic_block); basic_block);
void remove_edge_and_dominated_blocks (edge);
/* In tree-cfgcleanup.c */ /* In tree-cfgcleanup.c */
extern bitmap cfgcleanup_altered_bbs;
extern bool cleanup_tree_cfg (void); extern bool cleanup_tree_cfg (void);
extern bool cleanup_tree_cfg_loop (void); extern bool cleanup_tree_cfg_loop (void);
......
...@@ -2804,6 +2804,10 @@ optimize_inline_calls (tree fn) ...@@ -2804,6 +2804,10 @@ optimize_inline_calls (tree fn)
push_gimplify_context (); push_gimplify_context ();
/* We make no attempts to keep dominance info up-to-date. */
free_dominance_info (CDI_DOMINATORS);
free_dominance_info (CDI_POST_DOMINATORS);
/* Reach the trees by walking over the CFG, and note the /* Reach the trees by walking over the CFG, and note the
enclosing basic-blocks in the call edges. */ enclosing basic-blocks in the call edges. */
/* We walk the blocks going forward, because inlined function bodies /* We walk the blocks going forward, because inlined function bodies
...@@ -2840,9 +2844,6 @@ optimize_inline_calls (tree fn) ...@@ -2840,9 +2844,6 @@ optimize_inline_calls (tree fn)
fold_cond_expr_cond (); fold_cond_expr_cond ();
if (current_function_has_nonlocal_label) if (current_function_has_nonlocal_label)
make_nonlocal_label_edges (); make_nonlocal_label_edges ();
/* We make no attempts to keep dominance info up-to-date. */
free_dominance_info (CDI_DOMINATORS);
free_dominance_info (CDI_POST_DOMINATORS);
/* It would be nice to check SSA/CFG/statement consistency here, but it is /* It would be nice to check SSA/CFG/statement consistency here, but it is
not possible yet - the IPA passes might make various functions to not not possible yet - the IPA passes might make various functions to not
throw and they don't care to proactively update local EH info. This is throw and they don't care to proactively update local EH info. This is
......
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