Commit df648b94 by Jan Hubicka Committed by Jan Hubicka

domwalk.c (walk_dominator_tree): Reorganize to non-recursive implementation.

	* domwalk.c (walk_dominator_tree): Reorganize to non-recursive
	implementation.

From-SVN: r115912
parent d508327c
2006-08-03 Jan Hubicka <jh@suse.cz>
* domwalk.c (walk_dominator_tree): Reorganize to non-recursive
implementation.
2006-08-03 Dorit Nuzman <dorit@il.ibm.com> 2006-08-03 Dorit Nuzman <dorit@il.ibm.com>
PR tree-optimization/27770 PR tree-optimization/27770
......
...@@ -146,13 +146,20 @@ walk_dominator_tree (struct dom_walk_data *walk_data, basic_block bb) ...@@ -146,13 +146,20 @@ walk_dominator_tree (struct dom_walk_data *walk_data, basic_block bb)
basic_block dest; basic_block dest;
block_stmt_iterator bsi; block_stmt_iterator bsi;
bool is_interesting; bool is_interesting;
basic_block *worklist = XNEWVEC (basic_block, n_basic_blocks * 2);
int sp = 0;
while (true)
{
/* Don't worry about unreachable blocks. */
if (EDGE_COUNT (bb->preds) > 0 || bb == ENTRY_BLOCK_PTR)
{
/* If block BB is not interesting to the caller, then none of the /* If block BB is not interesting to the caller, then none of the
callbacks that walk the statements in BB are going to be callbacks that walk the statements in BB are going to be
executed. */ executed. */
is_interesting = bb->index < 0 is_interesting = walk_data->interesting_blocks == NULL
|| walk_data->interesting_blocks == NULL || TEST_BIT (walk_data->interesting_blocks,
|| TEST_BIT (walk_data->interesting_blocks, bb->index); bb->index);
/* Callback to initialize the local data structure. */ /* Callback to initialize the local data structure. */
if (walk_data->initialize_block_local_data) if (walk_data->initialize_block_local_data)
...@@ -176,7 +183,8 @@ walk_dominator_tree (struct dom_walk_data *walk_data, basic_block bb) ...@@ -176,7 +183,8 @@ walk_dominator_tree (struct dom_walk_data *walk_data, basic_block bb)
VEC_safe_push (void_p, heap, walk_data->block_data_stack, bd); VEC_safe_push (void_p, heap, walk_data->block_data_stack, bd);
/* Call the initializer. */ /* Call the initializer. */
walk_data->initialize_block_local_data (walk_data, bb, recycled); walk_data->initialize_block_local_data (walk_data, bb,
recycled);
} }
...@@ -190,10 +198,12 @@ walk_dominator_tree (struct dom_walk_data *walk_data, basic_block bb) ...@@ -190,10 +198,12 @@ walk_dominator_tree (struct dom_walk_data *walk_data, basic_block bb)
{ {
if (walk_data->walk_stmts_backward) if (walk_data->walk_stmts_backward)
for (bsi = bsi_last (bb); !bsi_end_p (bsi); bsi_prev (&bsi)) for (bsi = bsi_last (bb); !bsi_end_p (bsi); bsi_prev (&bsi))
(*walk_data->before_dom_children_walk_stmts) (walk_data, bb, bsi); (*walk_data->before_dom_children_walk_stmts) (walk_data, bb,
bsi);
else else
for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi)) for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
(*walk_data->before_dom_children_walk_stmts) (walk_data, bb, bsi); (*walk_data->before_dom_children_walk_stmts) (walk_data, bb,
bsi);
} }
/* Callback for operations to execute before we have walked the /* Callback for operations to execute before we have walked the
...@@ -201,17 +211,23 @@ walk_dominator_tree (struct dom_walk_data *walk_data, basic_block bb) ...@@ -201,17 +211,23 @@ walk_dominator_tree (struct dom_walk_data *walk_data, basic_block bb)
if (walk_data->before_dom_children_after_stmts) if (walk_data->before_dom_children_after_stmts)
(*walk_data->before_dom_children_after_stmts) (walk_data, bb); (*walk_data->before_dom_children_after_stmts) (walk_data, bb);
/* Recursively call ourselves on the dominator children of BB. */ /* Mark the current BB to be popped out of the recursion stack
once childs are processed. */
worklist[sp++] = bb;
worklist[sp++] = NULL;
for (dest = first_dom_son (walk_data->dom_direction, bb); for (dest = first_dom_son (walk_data->dom_direction, bb);
dest; dest; dest = next_dom_son (walk_data->dom_direction, dest))
dest = next_dom_son (walk_data->dom_direction, dest)) worklist[sp++] = dest;
{
/* The destination block may have become unreachable, in
which case there's no point in optimizing it. */
if (EDGE_COUNT (dest->preds) > 0)
walk_dominator_tree (walk_data, dest);
} }
/* NULL is used to signalize pop operation in recursion stack. */
while (sp > 0 && !worklist[sp - 1])
{
--sp;
bb = worklist[--sp];
is_interesting = walk_data->interesting_blocks == NULL
|| TEST_BIT (walk_data->interesting_blocks,
bb->index);
/* Callback for operations to execute after we have walked the /* Callback for operations to execute after we have walked the
dominator children, but before we walk statements. */ dominator children, but before we walk statements. */
if (walk_data->after_dom_children_before_stmts) if (walk_data->after_dom_children_before_stmts)
...@@ -222,10 +238,12 @@ walk_dominator_tree (struct dom_walk_data *walk_data, basic_block bb) ...@@ -222,10 +238,12 @@ walk_dominator_tree (struct dom_walk_data *walk_data, basic_block bb)
{ {
if (walk_data->walk_stmts_backward) if (walk_data->walk_stmts_backward)
for (bsi = bsi_last (bb); !bsi_end_p (bsi); bsi_prev (&bsi)) for (bsi = bsi_last (bb); !bsi_end_p (bsi); bsi_prev (&bsi))
(*walk_data->after_dom_children_walk_stmts) (walk_data, bb, bsi); (*walk_data->after_dom_children_walk_stmts) (walk_data, bb,
bsi);
else else
for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi)) for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
(*walk_data->after_dom_children_walk_stmts) (walk_data, bb, bsi); (*walk_data->after_dom_children_walk_stmts) (walk_data, bb,
bsi);
} }
/* Callback for operations to execute after we have walked the /* Callback for operations to execute after we have walked the
...@@ -235,12 +253,18 @@ walk_dominator_tree (struct dom_walk_data *walk_data, basic_block bb) ...@@ -235,12 +253,18 @@ walk_dominator_tree (struct dom_walk_data *walk_data, basic_block bb)
if (walk_data->initialize_block_local_data) if (walk_data->initialize_block_local_data)
{ {
/* And finally pop the record off the block local data stack. */
bd = VEC_pop (void_p, walk_data->block_data_stack);
/* And save the block data so that we can re-use it. */ /* And save the block data so that we can re-use it. */
VEC_safe_push (void_p, heap, walk_data->free_block_data, bd); VEC_safe_push (void_p, heap, walk_data->free_block_data, bd);
/* And finally pop the record off the block local data stack. */
VEC_pop (void_p, walk_data->block_data_stack);
} }
}
if (sp)
bb = worklist[--sp];
else
break;
}
free (worklist);
} }
void void
......
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