tree-ssa-dce.c (visited_control_parents): New sbitmap to replace BB_VISITED uses.

* tree-ssa-dce.c (visited_control_parents): New sbitmap to
	replace BB_VISITED uses.
	(find_obviously_necessary_stmts): Don't clear BB_VISITED.
	(propagate_necessity): Check the bitmap instead of BB_VISITED.
	(tree_dce_done): Free visited_control_parents.
	(perform_tree_ssa_dce): Allocate and clear it.
	* tree-ssa-pre.c (compute_antic_aux): Make non-recursive.
	(compute_antic): Iterate from here using a DFS.  Use an sbitmap
	instead of BB_VISITED.

From-SVN: r93654
This commit is contained in:
Steven Bosscher 2005-01-14 18:40:30 +00:00 committed by Steven Bosscher
parent 103a83e0fa
commit a28fee0388
3 changed files with 103 additions and 72 deletions

View file

@ -1,3 +1,15 @@
2005-01-14 Steven Bosscher <stevenb@suse.de>
* tree-ssa-dce.c (visited_control_parents): New sbitmap to
replace BB_VISITED uses.
(find_obviously_necessary_stmts): Don't clear BB_VISITED.
(propagate_necessity): Check the bitmap instead of BB_VISITED.
(tree_dce_done): Free visited_control_parents.
(perform_tree_ssa_dce): Allocate and clear it.
* tree-ssa-pre.c (compute_antic_aux): Make non-recursive.
(compute_antic): Iterate from here using a DFS. Use an sbitmap
instead of BB_VISITED.
2005-01-14 Kazu Hirata <kazu@cs.umass.edu>
* c-tree.h, coverage.h, langhooks-def.h, optabs.h, output.h,

View file

@ -93,6 +93,10 @@ static sbitmap last_stmt_necessary;
on the Ith edge. */
bitmap *control_dependence_map;
/* Vector indicating that a basic block has already had all the edges
processed that it is control dependent on. */
sbitmap visited_control_parents;
/* Execute CODE for each edge (given number EDGE_NUMBER within the CODE)
for which the block with index N is control dependent. */
#define EXECUTE_IF_CONTROL_DEPENDENT(N, EDGE_NUMBER, CODE) \
@ -482,11 +486,6 @@ find_obviously_necessary_stmts (struct edge_list *el)
NECESSARY (stmt) = 0;
mark_stmt_if_obviously_necessary (stmt, el != NULL);
}
/* Mark this basic block as `not visited'. A block will be marked
visited when the edges that it is control dependent on have been
marked. */
bb->flags &= ~BB_VISITED;
}
if (el)
@ -565,9 +564,10 @@ propagate_necessity (struct edge_list *el)
containing `i' is control dependent on, but only if we haven't
already done so. */
basic_block bb = bb_for_stmt (i);
if (! (bb->flags & BB_VISITED))
if (bb != ENTRY_BLOCK_PTR
&& ! TEST_BIT (visited_control_parents, bb->index))
{
bb->flags |= BB_VISITED;
SET_BIT (visited_control_parents, bb->index);
mark_control_dependent_edges_necessary (bb, el);
}
}
@ -593,9 +593,10 @@ propagate_necessity (struct edge_list *el)
for (k = 0; k < PHI_NUM_ARGS (i); k++)
{
basic_block arg_bb = PHI_ARG_EDGE (i, k)->src;
if (! (arg_bb->flags & BB_VISITED))
if (arg_bb != ENTRY_BLOCK_PTR
&& ! TEST_BIT (visited_control_parents, arg_bb->index))
{
arg_bb->flags |= BB_VISITED;
SET_BIT (visited_control_parents, arg_bb->index);
mark_control_dependent_edges_necessary (arg_bb, el);
}
}
@ -903,6 +904,7 @@ tree_dce_done (bool aggressive)
BITMAP_XFREE (control_dependence_map[i]);
free (control_dependence_map);
sbitmap_free (visited_control_parents);
sbitmap_free (last_stmt_necessary);
}
@ -939,6 +941,9 @@ perform_tree_ssa_dce (bool aggressive)
find_all_control_dependences (el);
timevar_pop (TV_CONTROL_DEPENDENCES);
visited_control_parents = sbitmap_alloc (last_basic_block);
sbitmap_zero (visited_control_parents);
mark_dfs_back_edges ();
}

View file

@ -1113,52 +1113,32 @@ DEF_VEC_MALLOC_P (basic_block);
ANTIC_IN[BLOCK] = clean(ANTIC_OUT[BLOCK] U EXP_GEN[BLOCK] - TMP_GEN[BLOCK])
Iterate until fixpointed.
XXX: It would be nice to either write a set_clear, and use it for
ANTIC_OUT, or to mark the antic_out set as deleted at the end
of this routine, so that the pool can hand the same memory back out
again for the next ANTIC_OUT. */
static bool
compute_antic_aux (basic_block block)
compute_antic_aux (basic_block block, bool block_has_abnormal_pred_edge)
{
basic_block son;
edge e;
bool changed = false;
value_set_t S, old, ANTIC_OUT;
value_set_node_t node;
ANTIC_OUT = S = NULL;
/* If any edges from predecessors are abnormal, antic_in is empty, so
punt. Remember that the block has an incoming abnormal edge by
setting the BB_VISITED flag. */
if (! (block->flags & BB_VISITED))
{
edge_iterator ei;
FOR_EACH_EDGE (e, ei, block->preds)
if (e->flags & EDGE_ABNORMAL)
{
block->flags |= BB_VISITED;
break;
}
}
if (block->flags & BB_VISITED)
{
S = NULL;
goto visit_sons;
}
/* If any edges from predecessors are abnormal, antic_in is empty,
so do nothing. */
if (block_has_abnormal_pred_edge)
goto maybe_dump_sets;
old = set_new (false);
set_copy (old, ANTIC_IN (block));
ANTIC_OUT = set_new (true);
/* If the block has no successors, ANTIC_OUT is empty, because it is
the exit block. */
if (EDGE_COUNT (block->succs) == 0);
/* If the block has no successors, ANTIC_OUT is empty. */
if (EDGE_COUNT (block->succs) == 0)
;
/* If we have one successor, we could have some phi nodes to
translate through. */
else if (EDGE_COUNT (block->succs) == 1)
@ -1206,21 +1186,16 @@ compute_antic_aux (basic_block block)
TMP_GEN (block),
true);
/* Then union in the ANTIC_OUT - TMP_GEN values, to get ANTIC_OUT U
EXP_GEN - TMP_GEN */
for (node = S->head;
node;
node = node->next)
{
value_insert_into_set (ANTIC_IN (block), node->expr);
}
clean (ANTIC_IN (block));
/* Then union in the ANTIC_OUT - TMP_GEN values,
to get ANTIC_OUT U EXP_GEN - TMP_GEN */
for (node = S->head; node; node = node->next)
value_insert_into_set (ANTIC_IN (block), node->expr);
clean (ANTIC_IN (block));
if (!set_equal (old, ANTIC_IN (block)))
changed = true;
visit_sons:
maybe_dump_sets:
if (dump_file && (dump_flags & TDF_DETAILS))
{
if (ANTIC_OUT)
@ -1228,43 +1203,82 @@ compute_antic_aux (basic_block block)
print_value_set (dump_file, ANTIC_IN (block), "ANTIC_IN", block->index);
if (S)
print_value_set (dump_file, S, "S", block->index);
}
for (son = first_dom_son (CDI_POST_DOMINATORS, block);
son;
son = next_dom_son (CDI_POST_DOMINATORS, son))
{
changed |= compute_antic_aux (son);
}
return changed;
}
/* Compute ANTIC sets. */
/* Compute ANTIC sets. Iterates until fixpointed. */
static void
compute_antic (void)
{
bool changed = true;
basic_block bb;
bool changed= true;
int num_iterations = 0;
FOR_ALL_BB (bb)
{
ANTIC_IN (bb) = set_new (true);
gcc_assert (!(bb->flags & BB_VISITED));
}
basic_block block, *worklist;
size_t sp = 0;
sbitmap has_abnormal_preds;
/* If any predecessor edges are abnormal, we punt, so antic_in is empty.
We pre-build the map of blocks with incoming abnormal edges here. */
has_abnormal_preds = sbitmap_alloc (last_basic_block);
sbitmap_zero (has_abnormal_preds);
FOR_EACH_BB (block)
{
edge_iterator ei;
edge e;
FOR_EACH_EDGE (e, ei, block->preds)
if (e->flags & EDGE_ABNORMAL)
{
SET_BIT (has_abnormal_preds, block->index);
break;
}
/* While we are here, give empty ANTIC_IN sets to each block. */
ANTIC_IN (block) = set_new (true);
}
/* At the exit block we anticipate nothing. */
ANTIC_IN (EXIT_BLOCK_PTR) = set_new (true);
/* Allocate the worklist. */
worklist = xmalloc (sizeof (basic_block) * n_basic_blocks);
/* Loop until fixpointed. */
while (changed)
{
num_iterations++;
basic_block son, bb;
changed = false;
changed = compute_antic_aux (EXIT_BLOCK_PTR);
num_iterations++;
/* Seed the algorithm by putting post-dominator children of
the exit block in the worklist. */
for (son = first_dom_son (CDI_POST_DOMINATORS, EXIT_BLOCK_PTR);
son;
son = next_dom_son (CDI_POST_DOMINATORS, son))
worklist[sp++] = son;
/* Now visit all blocks in a DFS of the post dominator tree. */
while (sp)
{
bool bb_has_abnormal_pred;
bb = worklist[--sp];
bb_has_abnormal_pred = TEST_BIT (has_abnormal_preds, bb->index);
changed |= compute_antic_aux (bb, bb_has_abnormal_pred);
for (son = first_dom_son (CDI_POST_DOMINATORS, bb);
son;
son = next_dom_son (CDI_POST_DOMINATORS, son))
worklist[sp++] = son;
}
}
FOR_ALL_BB (bb)
{
bb->flags &= ~BB_VISITED;
}
if (num_iterations > 2 && dump_file && (dump_flags & TDF_STATS))
free (worklist);
sbitmap_free (has_abnormal_preds);
if (dump_file && (dump_flags & TDF_STATS))
fprintf (dump_file, "compute_antic required %d iterations\n", num_iterations);
}