Commit 076b4605 by Richard Biener Committed by Richard Biener

re PR c/56113 (out of memory when compiling a function with many goto labels (50k > ))

2013-03-18  Richard Biener  <rguenther@suse.de>

	PR middle-end/56113
	* domwalk.c (bb_postorder): New global static.
	(cmp_bb_postorder): New function.
	(walk_dominator_tree): Replace scheme imposing an order for
	visiting dominator sons by one sorting them at the time they
	are pushed on the stack.

From-SVN: r196769
parent bdb01696
2013-03-18 Richard Biener <rguenther@suse.de> 2013-03-18 Richard Biener <rguenther@suse.de>
PR middle-end/56113
* domwalk.c (bb_postorder): New global static.
(cmp_bb_postorder): New function.
(walk_dominator_tree): Replace scheme imposing an order for
visiting dominator sons by one sorting them at the time they
are pushed on the stack.
2013-03-18 Richard Biener <rguenther@suse.de>
PR tree-optimization/39326 PR tree-optimization/39326
* tree-ssa-loop-im.c (refs_independent_p): Exploit symmetry. * tree-ssa-loop-im.c (refs_independent_p): Exploit symmetry.
(struct mem_ref): Replace mem member with ao_ref typed member. (struct mem_ref): Replace mem member with ao_ref typed member.
......
...@@ -128,6 +128,21 @@ along with GCC; see the file COPYING3. If not see ...@@ -128,6 +128,21 @@ along with GCC; see the file COPYING3. If not see
which is currently an abstraction over walking tree statements. Thus which is currently an abstraction over walking tree statements. Thus
the dominator walker is currently only useful for trees. */ the dominator walker is currently only useful for trees. */
static int *bb_postorder;
static int
cmp_bb_postorder (const void *a, const void *b)
{
basic_block bb1 = *(basic_block *)const_cast<void *>(a);
basic_block bb2 = *(basic_block *)const_cast<void *>(b);
if (bb1->index == bb2->index)
return 0;
/* Place higher completion number first (pop off lower number first). */
if (bb_postorder[bb1->index] > bb_postorder[bb2->index])
return -1;
return 1;
}
/* Recursively walk the dominator tree. /* Recursively walk the dominator tree.
WALK_DATA contains a set of callbacks to perform pass-specific WALK_DATA contains a set of callbacks to perform pass-specific
...@@ -143,9 +158,17 @@ walk_dominator_tree (struct dom_walk_data *walk_data, basic_block bb) ...@@ -143,9 +158,17 @@ walk_dominator_tree (struct dom_walk_data *walk_data, basic_block bb)
basic_block dest; basic_block dest;
basic_block *worklist = XNEWVEC (basic_block, n_basic_blocks * 2); basic_block *worklist = XNEWVEC (basic_block, n_basic_blocks * 2);
int sp = 0; int sp = 0;
sbitmap visited = sbitmap_alloc (last_basic_block + 1); int *postorder, postorder_num;
bitmap_clear (visited);
bitmap_set_bit (visited, ENTRY_BLOCK_PTR->index); if (walk_data->dom_direction == CDI_DOMINATORS)
{
postorder = XNEWVEC (int, n_basic_blocks);
postorder_num = inverted_post_order_compute (postorder);
bb_postorder = XNEWVEC (int, last_basic_block);
for (int i = 0; i < postorder_num; ++i)
bb_postorder[postorder[i]] = i;
free (postorder);
}
while (true) while (true)
{ {
...@@ -186,16 +209,25 @@ walk_dominator_tree (struct dom_walk_data *walk_data, basic_block bb) ...@@ -186,16 +209,25 @@ walk_dominator_tree (struct dom_walk_data *walk_data, basic_block bb)
if (walk_data->before_dom_children) if (walk_data->before_dom_children)
(*walk_data->before_dom_children) (walk_data, bb); (*walk_data->before_dom_children) (walk_data, bb);
bitmap_set_bit (visited, bb->index);
/* Mark the current BB to be popped out of the recursion stack /* Mark the current BB to be popped out of the recursion stack
once children are processed. */ once children are processed. */
worklist[sp++] = bb; worklist[sp++] = bb;
worklist[sp++] = NULL; worklist[sp++] = NULL;
int saved_sp = sp;
for (dest = first_dom_son (walk_data->dom_direction, bb); for (dest = first_dom_son (walk_data->dom_direction, bb);
dest; dest = next_dom_son (walk_data->dom_direction, dest)) dest; dest = next_dom_son (walk_data->dom_direction, dest))
worklist[sp++] = dest; worklist[sp++] = dest;
if (walk_data->dom_direction == CDI_DOMINATORS)
switch (sp - saved_sp)
{
case 0:
case 1:
break;
default:
qsort (&worklist[saved_sp], sp - saved_sp,
sizeof (basic_block), cmp_bb_postorder);
}
} }
/* NULL is used to mark pop operations in the recursion stack. */ /* NULL is used to mark pop operations in the recursion stack. */
while (sp > 0 && !worklist[sp - 1]) while (sp > 0 && !worklist[sp - 1])
...@@ -217,44 +249,16 @@ walk_dominator_tree (struct dom_walk_data *walk_data, basic_block bb) ...@@ -217,44 +249,16 @@ walk_dominator_tree (struct dom_walk_data *walk_data, basic_block bb)
} }
} }
if (sp) if (sp)
{ bb = worklist[--sp];
int spp;
spp = sp - 1;
if (walk_data->dom_direction == CDI_DOMINATORS)
/* Find the dominator son that has all its predecessors
visited and continue with that. */
while (1)
{
edge_iterator ei;
edge e;
bool found = true;
bb = worklist[spp];
FOR_EACH_EDGE (e, ei, bb->preds)
{
if (!dominated_by_p (CDI_DOMINATORS, e->src, e->dest)
&& !bitmap_bit_p (visited, e->src->index))
{
found = false;
break;
}
}
if (found)
break;
/* If we didn't find a dom child with all visited
predecessors just use the candidate we were checking.
This happens for candidates in irreducible loops. */
if (!worklist[spp - 1])
break;
--spp;
}
bb = worklist[spp];
worklist[spp] = worklist[--sp];
}
else else
break; break;
} }
if (walk_data->dom_direction == CDI_DOMINATORS)
{
free (bb_postorder);
bb_postorder = NULL;
}
free (worklist); free (worklist);
sbitmap_free (visited);
} }
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