Commit a28fee03 by Steven Bosscher Committed by Steven Bosscher

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
parent 103a83e0
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> 2005-01-14 Kazu Hirata <kazu@cs.umass.edu>
* c-tree.h, coverage.h, langhooks-def.h, optabs.h, output.h, * c-tree.h, coverage.h, langhooks-def.h, optabs.h, output.h,
......
...@@ -93,6 +93,10 @@ static sbitmap last_stmt_necessary; ...@@ -93,6 +93,10 @@ static sbitmap last_stmt_necessary;
on the Ith edge. */ on the Ith edge. */
bitmap *control_dependence_map; 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) /* Execute CODE for each edge (given number EDGE_NUMBER within the CODE)
for which the block with index N is control dependent. */ for which the block with index N is control dependent. */
#define EXECUTE_IF_CONTROL_DEPENDENT(N, EDGE_NUMBER, CODE) \ #define EXECUTE_IF_CONTROL_DEPENDENT(N, EDGE_NUMBER, CODE) \
...@@ -482,11 +486,6 @@ find_obviously_necessary_stmts (struct edge_list *el) ...@@ -482,11 +486,6 @@ find_obviously_necessary_stmts (struct edge_list *el)
NECESSARY (stmt) = 0; NECESSARY (stmt) = 0;
mark_stmt_if_obviously_necessary (stmt, el != NULL); 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) if (el)
...@@ -565,9 +564,10 @@ propagate_necessity (struct edge_list *el) ...@@ -565,9 +564,10 @@ propagate_necessity (struct edge_list *el)
containing `i' is control dependent on, but only if we haven't containing `i' is control dependent on, but only if we haven't
already done so. */ already done so. */
basic_block bb = bb_for_stmt (i); 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); mark_control_dependent_edges_necessary (bb, el);
} }
} }
...@@ -593,9 +593,10 @@ propagate_necessity (struct edge_list *el) ...@@ -593,9 +593,10 @@ propagate_necessity (struct edge_list *el)
for (k = 0; k < PHI_NUM_ARGS (i); k++) for (k = 0; k < PHI_NUM_ARGS (i); k++)
{ {
basic_block arg_bb = PHI_ARG_EDGE (i, k)->src; 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); mark_control_dependent_edges_necessary (arg_bb, el);
} }
} }
...@@ -903,6 +904,7 @@ tree_dce_done (bool aggressive) ...@@ -903,6 +904,7 @@ tree_dce_done (bool aggressive)
BITMAP_XFREE (control_dependence_map[i]); BITMAP_XFREE (control_dependence_map[i]);
free (control_dependence_map); free (control_dependence_map);
sbitmap_free (visited_control_parents);
sbitmap_free (last_stmt_necessary); sbitmap_free (last_stmt_necessary);
} }
...@@ -939,6 +941,9 @@ perform_tree_ssa_dce (bool aggressive) ...@@ -939,6 +941,9 @@ perform_tree_ssa_dce (bool aggressive)
find_all_control_dependences (el); find_all_control_dependences (el);
timevar_pop (TV_CONTROL_DEPENDENCES); timevar_pop (TV_CONTROL_DEPENDENCES);
visited_control_parents = sbitmap_alloc (last_basic_block);
sbitmap_zero (visited_control_parents);
mark_dfs_back_edges (); mark_dfs_back_edges ();
} }
......
...@@ -1113,52 +1113,32 @@ DEF_VEC_MALLOC_P (basic_block); ...@@ -1113,52 +1113,32 @@ DEF_VEC_MALLOC_P (basic_block);
ANTIC_IN[BLOCK] = clean(ANTIC_OUT[BLOCK] U EXP_GEN[BLOCK] - TMP_GEN[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 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 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 of this routine, so that the pool can hand the same memory back out
again for the next ANTIC_OUT. */ again for the next ANTIC_OUT. */
static bool 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; bool changed = false;
value_set_t S, old, ANTIC_OUT; value_set_t S, old, ANTIC_OUT;
value_set_node_t node; value_set_node_t node;
ANTIC_OUT = S = NULL; 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 /* If any edges from predecessors are abnormal, antic_in is empty,
setting the BB_VISITED flag. */ so do nothing. */
if (! (block->flags & BB_VISITED)) if (block_has_abnormal_pred_edge)
{ goto maybe_dump_sets;
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;
}
old = set_new (false); old = set_new (false);
set_copy (old, ANTIC_IN (block)); set_copy (old, ANTIC_IN (block));
ANTIC_OUT = set_new (true); ANTIC_OUT = set_new (true);
/* If the block has no successors, ANTIC_OUT is empty, because it is /* If the block has no successors, ANTIC_OUT is empty. */
the exit block. */ if (EDGE_COUNT (block->succs) == 0)
if (EDGE_COUNT (block->succs) == 0); ;
/* If we have one successor, we could have some phi nodes to /* If we have one successor, we could have some phi nodes to
translate through. */ translate through. */
else if (EDGE_COUNT (block->succs) == 1) else if (EDGE_COUNT (block->succs) == 1)
...@@ -1206,21 +1186,16 @@ compute_antic_aux (basic_block block) ...@@ -1206,21 +1186,16 @@ compute_antic_aux (basic_block block)
TMP_GEN (block), TMP_GEN (block),
true); true);
/* Then union in the ANTIC_OUT - TMP_GEN values, to get ANTIC_OUT U /* Then union in the ANTIC_OUT - TMP_GEN values,
EXP_GEN - TMP_GEN */ to get ANTIC_OUT U EXP_GEN - TMP_GEN */
for (node = S->head; for (node = S->head; node; node = node->next)
node; value_insert_into_set (ANTIC_IN (block), node->expr);
node = node->next)
{
value_insert_into_set (ANTIC_IN (block), node->expr);
}
clean (ANTIC_IN (block));
clean (ANTIC_IN (block));
if (!set_equal (old, ANTIC_IN (block))) if (!set_equal (old, ANTIC_IN (block)))
changed = true; changed = true;
visit_sons: maybe_dump_sets:
if (dump_file && (dump_flags & TDF_DETAILS)) if (dump_file && (dump_flags & TDF_DETAILS))
{ {
if (ANTIC_OUT) if (ANTIC_OUT)
...@@ -1228,43 +1203,82 @@ compute_antic_aux (basic_block block) ...@@ -1228,43 +1203,82 @@ compute_antic_aux (basic_block block)
print_value_set (dump_file, ANTIC_IN (block), "ANTIC_IN", block->index); print_value_set (dump_file, ANTIC_IN (block), "ANTIC_IN", block->index);
if (S) if (S)
print_value_set (dump_file, S, "S", block->index); 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; return changed;
} }
/* Compute ANTIC sets. */ /* Compute ANTIC sets. Iterates until fixpointed. */
static void static void
compute_antic (void) compute_antic (void)
{ {
bool changed = true; bool changed= true;
basic_block bb;
int num_iterations = 0; int num_iterations = 0;
FOR_ALL_BB (bb) 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)
{ {
ANTIC_IN (bb) = set_new (true); edge_iterator ei;
gcc_assert (!(bb->flags & BB_VISITED)); 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) while (changed)
{ {
num_iterations++; basic_block son, bb;
changed = false; changed = false;
changed = compute_antic_aux (EXIT_BLOCK_PTR); num_iterations++;
}
FOR_ALL_BB (bb) /* Seed the algorithm by putting post-dominator children of
{ the exit block in the worklist. */
bb->flags &= ~BB_VISITED; 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;
}
} }
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); fprintf (dump_file, "compute_antic required %d iterations\n", num_iterations);
} }
......
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