Commit 6be34936 by Richard Guenther Committed by Richard Biener

re PR middle-end/35204 (crash by too deep recursion in DFS tree-ssa-sccvn.c:1898)

2008-05-20  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/35204
	* tree-ssa-sccvn.c (extract_and_process_scc_for_name): New
	helper, split out from ...
	(DFS): ... here.  Make the DFS walk non-recursive.

From-SVN: r135676
parent e4ae405a
2008-05-20 Richard Guenther <rguenther@suse.de>
PR tree-optimization/35204
* tree-ssa-sccvn.c (extract_and_process_scc_for_name): New
helper, split out from ...
(DFS): ... here. Make the DFS walk non-recursive.
2008-05-20 Sebastian Pop <sebastian.pop@amd.com> 2008-05-20 Sebastian Pop <sebastian.pop@amd.com>
Jan Sjodin <jan.sjodin@amd.com> Jan Sjodin <jan.sjodin@amd.com>
......
...@@ -1956,6 +1956,53 @@ process_scc (VEC (tree, heap) *scc) ...@@ -1956,6 +1956,53 @@ process_scc (VEC (tree, heap) *scc)
} }
} }
DEF_VEC_O(ssa_op_iter);
DEF_VEC_ALLOC_O(ssa_op_iter,heap);
/* Pop the components of the found SCC for NAME off the SCC stack
and process them. Returns true if all went well, false if
we run into resource limits. */
static bool
extract_and_process_scc_for_name (tree name)
{
VEC (tree, heap) *scc = NULL;
tree x;
/* Found an SCC, pop the components off the SCC stack and
process them. */
do
{
x = VEC_pop (tree, sccstack);
VN_INFO (x)->on_sccstack = false;
VEC_safe_push (tree, heap, scc, x);
} while (x != name);
/* Bail out of SCCVN in case a SCC turns out to be incredibly large. */
if (VEC_length (tree, scc)
> (unsigned)PARAM_VALUE (PARAM_SCCVN_MAX_SCC_SIZE))
{
if (dump_file)
fprintf (dump_file, "WARNING: Giving up with SCCVN due to "
"SCC size %u exceeding %u\n", VEC_length (tree, scc),
(unsigned)PARAM_VALUE (PARAM_SCCVN_MAX_SCC_SIZE));
return false;
}
if (VEC_length (tree, scc) > 1)
sort_scc (scc);
if (dump_file && (dump_flags & TDF_DETAILS))
print_scc (dump_file, scc);
process_scc (scc);
VEC_free (tree, heap, scc);
return true;
}
/* Depth first search on NAME to discover and process SCC's in the SSA /* Depth first search on NAME to discover and process SCC's in the SSA
graph. graph.
Execution of this algorithm relies on the fact that the SCC's are Execution of this algorithm relies on the fact that the SCC's are
...@@ -1966,10 +2013,13 @@ process_scc (VEC (tree, heap) *scc) ...@@ -1966,10 +2013,13 @@ process_scc (VEC (tree, heap) *scc)
static bool static bool
DFS (tree name) DFS (tree name)
{ {
VEC(ssa_op_iter, heap) *itervec = NULL;
VEC(tree, heap) *namevec = NULL;
use_operand_p usep = NULL;
tree defstmt, use;
ssa_op_iter iter; ssa_op_iter iter;
use_operand_p usep;
tree defstmt;
start_over:
/* SCC info */ /* SCC info */
VN_INFO (name)->dfsnum = next_dfs_num++; VN_INFO (name)->dfsnum = next_dfs_num++;
VN_INFO (name)->visited = true; VN_INFO (name)->visited = true;
...@@ -1982,20 +2032,63 @@ DFS (tree name) ...@@ -1982,20 +2032,63 @@ DFS (tree name)
/* Recursively DFS on our operands, looking for SCC's. */ /* Recursively DFS on our operands, looking for SCC's. */
if (!IS_EMPTY_STMT (defstmt)) if (!IS_EMPTY_STMT (defstmt))
{ {
FOR_EACH_PHI_OR_STMT_USE (usep, SSA_NAME_DEF_STMT (name), iter, /* Push a new iterator. */
SSA_OP_ALL_USES) if (TREE_CODE (defstmt) == PHI_NODE)
usep = op_iter_init_phiuse (&iter, defstmt, SSA_OP_ALL_USES);
else
usep = op_iter_init_use (&iter, defstmt, SSA_OP_ALL_USES);
}
else
iter.done = true;
while (1)
{
/* If we are done processing uses of a name, go up the stack
of iterators and process SCCs as we found them. */
if (op_iter_done (&iter))
{ {
tree use = USE_FROM_PTR (usep); /* See if we found an SCC. */
if (VN_INFO (name)->low == VN_INFO (name)->dfsnum)
if (!extract_and_process_scc_for_name (name))
{
VEC_free (tree, heap, namevec);
VEC_free (ssa_op_iter, heap, itervec);
return false;
}
/* Since we handle phi nodes, we will sometimes get /* Check if we are done. */
invariants in the use expression. */ if (VEC_empty (tree, namevec))
if (TREE_CODE (use) != SSA_NAME) {
continue; VEC_free (tree, heap, namevec);
VEC_free (ssa_op_iter, heap, itervec);
return true;
}
/* Restore the last use walker and continue walking there. */
use = name;
name = VEC_pop (tree, namevec);
memcpy (&iter, VEC_last (ssa_op_iter, itervec),
sizeof (ssa_op_iter));
VEC_pop (ssa_op_iter, itervec);
goto continue_walking;
}
use = USE_FROM_PTR (usep);
/* Since we handle phi nodes, we will sometimes get
invariants in the use expression. */
if (TREE_CODE (use) == SSA_NAME)
{
if (! (VN_INFO (use)->visited)) if (! (VN_INFO (use)->visited))
{ {
if (!DFS (use)) /* Recurse by pushing the current use walking state on
return false; the stack and starting over. */
VEC_safe_push(ssa_op_iter, heap, itervec, &iter);
VEC_safe_push(tree, heap, namevec, name);
name = use;
goto start_over;
continue_walking:
VN_INFO (name)->low = MIN (VN_INFO (name)->low, VN_INFO (name)->low = MIN (VN_INFO (name)->low,
VN_INFO (use)->low); VN_INFO (use)->low);
} }
...@@ -2006,47 +2099,9 @@ DFS (tree name) ...@@ -2006,47 +2099,9 @@ DFS (tree name)
VN_INFO (name)->low); VN_INFO (name)->low);
} }
} }
}
/* See if we found an SCC. */
if (VN_INFO (name)->low == VN_INFO (name)->dfsnum)
{
VEC (tree, heap) *scc = NULL;
tree x;
/* Found an SCC, pop the components off the SCC stack and
process them. */
do
{
x = VEC_pop (tree, sccstack);
VN_INFO (x)->on_sccstack = false;
VEC_safe_push (tree, heap, scc, x);
} while (x != name);
/* Bail out of SCCVN in case a SCC turns out to be incredibly large. */
if (VEC_length (tree, scc)
> (unsigned)PARAM_VALUE (PARAM_SCCVN_MAX_SCC_SIZE))
{
if (dump_file)
fprintf (dump_file, "WARNING: Giving up with SCCVN due to "
"SCC size %u exceeding %u\n", VEC_length (tree, scc),
(unsigned)PARAM_VALUE (PARAM_SCCVN_MAX_SCC_SIZE));
return false;
}
if (VEC_length (tree, scc) > 1) usep = op_iter_next_use (&iter);
sort_scc (scc);
if (dump_file && (dump_flags & TDF_DETAILS))
print_scc (dump_file, scc);
process_scc (scc);
VEC_free (tree, heap, scc);
} }
return true;
} }
/* Allocate a value number table. */ /* Allocate a value number table. */
......
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