Commit 92261ce0 by Jakub Jelinek Committed by Jakub Jelinek

re PR tree-optimization/56490 (-Wall triggering infinite loop)

	PR tree-optimization/56490
	* params.def (PARAM_UNINIT_CONTROL_DEP_ATTEMPTS): New param.
	* tree-ssa-uninit.c: Include params.h.
	(compute_control_dep_chain): Add num_calls argument, return false
	if it exceed PARAM_UNINIT_CONTROL_DEP_ATTEMPTS param, pass
	num_calls to recursive call.
	(find_predicates): Change dep_chain into normal array,
	cur_chain into auto_vec<edge, MAX_CHAIN_LEN + 1>, add num_calls
	variable and adjust compute_control_dep_chain caller.
	(find_def_preds): Likewise.

From-SVN: r207988
parent aa6ef874
2014-02-21 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/56490
* params.def (PARAM_UNINIT_CONTROL_DEP_ATTEMPTS): New param.
* tree-ssa-uninit.c: Include params.h.
(compute_control_dep_chain): Add num_calls argument, return false
if it exceed PARAM_UNINIT_CONTROL_DEP_ATTEMPTS param, pass
num_calls to recursive call.
(find_predicates): Change dep_chain into normal array,
cur_chain into auto_vec<edge, MAX_CHAIN_LEN + 1>, add num_calls
variable and adjust compute_control_dep_chain caller.
(find_def_preds): Likewise.
2014-02-21 Thomas Schwinge <thomas@codesourcery.com> 2014-02-21 Thomas Schwinge <thomas@codesourcery.com>
* gimple-pretty-print.c (dump_gimple_omp_for) [flags & TDF_RAW] * gimple-pretty-print.c (dump_gimple_omp_for) [flags & TDF_RAW]
......
...@@ -1078,6 +1078,12 @@ DEFPARAM (PARAM_ASAN_USE_AFTER_RETURN, ...@@ -1078,6 +1078,12 @@ DEFPARAM (PARAM_ASAN_USE_AFTER_RETURN,
"asan-use-after-return", "asan-use-after-return",
"Enable asan builtin functions protection", "Enable asan builtin functions protection",
1, 0, 1) 1, 0, 1)
DEFPARAM (PARAM_UNINIT_CONTROL_DEP_ATTEMPTS,
"uninit-control-dep-attempts",
"Maximum number of nested calls to search for control dependencies "
"during uninitialized variable analysis",
1000, 1, 0)
/* /*
Local variables: Local variables:
......
...@@ -44,6 +44,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -44,6 +44,7 @@ along with GCC; see the file COPYING3. If not see
#include "hashtab.h" #include "hashtab.h"
#include "tree-pass.h" #include "tree-pass.h"
#include "diagnostic-core.h" #include "diagnostic-core.h"
#include "params.h"
/* This implements the pass that does predicate aware warning on uses of /* This implements the pass that does predicate aware warning on uses of
possibly uninitialized variables. The pass first collects the set of possibly uninitialized variables. The pass first collects the set of
...@@ -390,8 +391,8 @@ find_control_equiv_block (basic_block bb) ...@@ -390,8 +391,8 @@ find_control_equiv_block (basic_block bb)
/* Computes the control dependence chains (paths of edges) /* Computes the control dependence chains (paths of edges)
for DEP_BB up to the dominating basic block BB (the head node of a for DEP_BB up to the dominating basic block BB (the head node of a
chain should be dominated by it). CD_CHAINS is pointer to a chain should be dominated by it). CD_CHAINS is pointer to an
dynamic array holding the result chains. CUR_CD_CHAIN is the current array holding the result chains. CUR_CD_CHAIN is the current
chain being computed. *NUM_CHAINS is total number of chains. The chain being computed. *NUM_CHAINS is total number of chains. The
function returns true if the information is successfully computed, function returns true if the information is successfully computed,
return false if there is no control dependence or not computed. */ return false if there is no control dependence or not computed. */
...@@ -400,7 +401,8 @@ static bool ...@@ -400,7 +401,8 @@ static bool
compute_control_dep_chain (basic_block bb, basic_block dep_bb, compute_control_dep_chain (basic_block bb, basic_block dep_bb,
vec<edge> *cd_chains, vec<edge> *cd_chains,
size_t *num_chains, size_t *num_chains,
vec<edge> *cur_cd_chain) vec<edge> *cur_cd_chain,
int *num_calls)
{ {
edge_iterator ei; edge_iterator ei;
edge e; edge e;
...@@ -411,6 +413,10 @@ compute_control_dep_chain (basic_block bb, basic_block dep_bb, ...@@ -411,6 +413,10 @@ compute_control_dep_chain (basic_block bb, basic_block dep_bb,
if (EDGE_COUNT (bb->succs) < 2) if (EDGE_COUNT (bb->succs) < 2)
return false; return false;
if (*num_calls > PARAM_VALUE (PARAM_UNINIT_CONTROL_DEP_ATTEMPTS))
return false;
++*num_calls;
/* Could use a set instead. */ /* Could use a set instead. */
cur_chain_len = cur_cd_chain->length (); cur_chain_len = cur_cd_chain->length ();
if (cur_chain_len > MAX_CHAIN_LEN) if (cur_chain_len > MAX_CHAIN_LEN)
...@@ -450,7 +456,7 @@ compute_control_dep_chain (basic_block bb, basic_block dep_bb, ...@@ -450,7 +456,7 @@ compute_control_dep_chain (basic_block bb, basic_block dep_bb,
/* Now check if DEP_BB is indirectly control dependent on BB. */ /* Now check if DEP_BB is indirectly control dependent on BB. */
if (compute_control_dep_chain (cd_bb, dep_bb, cd_chains, if (compute_control_dep_chain (cd_bb, dep_bb, cd_chains,
num_chains, cur_cd_chain)) num_chains, cur_cd_chain, num_calls))
{ {
found_cd_chain = true; found_cd_chain = true;
break; break;
...@@ -595,14 +601,12 @@ find_predicates (pred_chain_union *preds, ...@@ -595,14 +601,12 @@ find_predicates (pred_chain_union *preds,
basic_block use_bb) basic_block use_bb)
{ {
size_t num_chains = 0, i; size_t num_chains = 0, i;
vec<edge> *dep_chains = 0; int num_calls = 0;
vec<edge> cur_chain = vNULL; vec<edge> dep_chains[MAX_NUM_CHAINS];
auto_vec<edge, MAX_CHAIN_LEN + 1> cur_chain;
bool has_valid_pred = false; bool has_valid_pred = false;
basic_block cd_root = 0; basic_block cd_root = 0;
typedef vec<edge> vec_edge_heap;
dep_chains = XCNEWVEC (vec_edge_heap, MAX_NUM_CHAINS);
/* First find the closest bb that is control equivalent to PHI_BB /* First find the closest bb that is control equivalent to PHI_BB
that also dominates USE_BB. */ that also dominates USE_BB. */
cd_root = phi_bb; cd_root = phi_bb;
...@@ -615,19 +619,13 @@ find_predicates (pred_chain_union *preds, ...@@ -615,19 +619,13 @@ find_predicates (pred_chain_union *preds,
break; break;
} }
compute_control_dep_chain (cd_root, use_bb, compute_control_dep_chain (cd_root, use_bb, dep_chains, &num_chains,
dep_chains, &num_chains, &cur_chain, &num_calls);
&cur_chain);
has_valid_pred has_valid_pred
= convert_control_dep_chain_into_preds (dep_chains, = convert_control_dep_chain_into_preds (dep_chains, num_chains, preds);
num_chains,
preds);
/* Free individual chain */
cur_chain.release ();
for (i = 0; i < num_chains; i++) for (i = 0; i < num_chains; i++)
dep_chains[i].release (); dep_chains[i].release ();
free (dep_chains);
return has_valid_pred; return has_valid_pred;
} }
...@@ -694,16 +692,13 @@ static bool ...@@ -694,16 +692,13 @@ static bool
find_def_preds (pred_chain_union *preds, gimple phi) find_def_preds (pred_chain_union *preds, gimple phi)
{ {
size_t num_chains = 0, i, n; size_t num_chains = 0, i, n;
vec<edge> *dep_chains = 0; vec<edge> dep_chains[MAX_NUM_CHAINS];
vec<edge> cur_chain = vNULL; auto_vec<edge, MAX_CHAIN_LEN + 1> cur_chain;
vec<edge> def_edges = vNULL; vec<edge> def_edges = vNULL;
bool has_valid_pred = false; bool has_valid_pred = false;
basic_block phi_bb, cd_root = 0; basic_block phi_bb, cd_root = 0;
pointer_set_t *visited_phis; pointer_set_t *visited_phis;
typedef vec<edge> vec_edge_heap;
dep_chains = XCNEWVEC (vec_edge_heap, MAX_NUM_CHAINS);
phi_bb = gimple_bb (phi); phi_bb = gimple_bb (phi);
/* First find the closest dominating bb to be /* First find the closest dominating bb to be
the control dependence root */ the control dependence root */
...@@ -722,37 +717,29 @@ find_def_preds (pred_chain_union *preds, gimple phi) ...@@ -722,37 +717,29 @@ find_def_preds (pred_chain_union *preds, gimple phi)
for (i = 0; i < n; i++) for (i = 0; i < n; i++)
{ {
size_t prev_nc, j; size_t prev_nc, j;
int num_calls = 0;
edge opnd_edge; edge opnd_edge;
opnd_edge = def_edges[i]; opnd_edge = def_edges[i];
prev_nc = num_chains; prev_nc = num_chains;
compute_control_dep_chain (cd_root, opnd_edge->src, compute_control_dep_chain (cd_root, opnd_edge->src, dep_chains,
dep_chains, &num_chains, &num_chains, &cur_chain, &num_calls);
&cur_chain);
/* Free individual chain */
cur_chain.release ();
/* Now update the newly added chains with /* Now update the newly added chains with
the phi operand edge: */ the phi operand edge: */
if (EDGE_COUNT (opnd_edge->src->succs) > 1) if (EDGE_COUNT (opnd_edge->src->succs) > 1)
{ {
if (prev_nc == num_chains if (prev_nc == num_chains && num_chains < MAX_NUM_CHAINS)
&& num_chains < MAX_NUM_CHAINS) dep_chains[num_chains++] = vNULL;
num_chains++;
for (j = prev_nc; j < num_chains; j++) for (j = prev_nc; j < num_chains; j++)
{ dep_chains[j].safe_push (opnd_edge);
dep_chains[j].safe_push (opnd_edge);
}
} }
} }
has_valid_pred has_valid_pred
= convert_control_dep_chain_into_preds (dep_chains, = convert_control_dep_chain_into_preds (dep_chains, num_chains, preds);
num_chains,
preds);
for (i = 0; i < num_chains; i++) for (i = 0; i < num_chains; i++)
dep_chains[i].release (); dep_chains[i].release ();
free (dep_chains);
return has_valid_pred; return has_valid_pred;
} }
......
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