aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-chrec.c
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2019-06-04 09:05:10 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2019-06-04 09:05:10 +0000
commit5fd8a9cb5b0e95af7f833f8dfe62ce5b9d435846 (patch)
tree3b5d284dec65e1db933d98245b02d38df7414bff /gcc/tree-chrec.c
parentd62887a42bc49963179b0429f6914b050dd2517c (diff)
downloadgcc-5fd8a9cb5b0e95af7f833f8dfe62ce5b9d435846.zip
gcc-5fd8a9cb5b0e95af7f833f8dfe62ce5b9d435846.tar.gz
gcc-5fd8a9cb5b0e95af7f833f8dfe62ce5b9d435846.tar.bz2
re PR middle-end/90726 (exponential behavior on SCEV results everywhere)
2019-06-04 Richard Biener <rguenther@suse.de> PR middle-end/90726 * tree-chrec.c (chrec_contains_symbols): Add to visited. (tree_contains_chrecs): Likewise. (chrec_contains_symbols_defined_in_loop): Move here and avoid exponential behaivor from ... * tree-scalar-evolution.c (chrec_contains_symbols_defined_in_loop): ... here. (expression_expensive_p): Avoid exponential behavior and compute expanded size, rejecting any expansion. * tree-ssa-loop-ivopts.c (abnormal_ssa_name_p): Remove. (idx_contains_abnormal_ssa_name_p): Likewise. (contains_abnormal_ssa_name_p_1): New helper for walk_tree. (contains_abnormal_ssa_name_p): Simplify and use walk_tree_without_duplicates. * gcc.dg/pr90726.c: New testcase. From-SVN: r271903
Diffstat (limited to 'gcc/tree-chrec.c')
-rw-r--r--gcc/tree-chrec.c65
1 files changed, 65 insertions, 0 deletions
diff --git a/gcc/tree-chrec.c b/gcc/tree-chrec.c
index 813b87f..f50fd20 100644
--- a/gcc/tree-chrec.c
+++ b/gcc/tree-chrec.c
@@ -35,6 +35,8 @@ along with GCC; see the file COPYING3. If not see
#include "tree-ssa-loop-ivopts.h"
#include "tree-ssa-loop-niter.h"
#include "tree-chrec.h"
+#include "gimple.h"
+#include "tree-ssa-loop.h"
#include "dumpfile.h"
#include "params.h"
#include "tree-scalar-evolution.h"
@@ -959,6 +961,9 @@ chrec_contains_symbols (const_tree chrec, hash_set<const_tree> &visited,
&& flow_loop_nested_p (get_chrec_loop (chrec), loop))
return true;
+ if (visited.add (chrec))
+ return false;
+
n = TREE_OPERAND_LENGTH (chrec);
for (i = 0; i < n; i++)
if (chrec_contains_symbols (TREE_OPERAND (chrec, i), visited, loop))
@@ -978,6 +983,63 @@ chrec_contains_symbols (const_tree chrec, struct loop* loop)
return chrec_contains_symbols (chrec, visited, loop);
}
+/* Return true when CHREC contains symbolic names defined in
+ LOOP_NB. */
+
+static bool
+chrec_contains_symbols_defined_in_loop (const_tree chrec, unsigned loop_nb,
+ hash_set<const_tree> &visited)
+{
+ int i, n;
+
+ if (chrec == NULL_TREE)
+ return false;
+
+ if (is_gimple_min_invariant (chrec))
+ return false;
+
+ if (TREE_CODE (chrec) == SSA_NAME)
+ {
+ gimple *def;
+ loop_p def_loop, loop;
+
+ if (SSA_NAME_IS_DEFAULT_DEF (chrec))
+ return false;
+
+ def = SSA_NAME_DEF_STMT (chrec);
+ def_loop = loop_containing_stmt (def);
+ loop = get_loop (cfun, loop_nb);
+
+ if (def_loop == NULL)
+ return false;
+
+ if (loop == def_loop || flow_loop_nested_p (loop, def_loop))
+ return true;
+
+ return false;
+ }
+
+ if (visited.add (chrec))
+ return false;
+
+ n = TREE_OPERAND_LENGTH (chrec);
+ for (i = 0; i < n; i++)
+ if (chrec_contains_symbols_defined_in_loop (TREE_OPERAND (chrec, i),
+ loop_nb, visited))
+ return true;
+ return false;
+}
+
+/* Return true when CHREC contains symbolic names defined in
+ LOOP_NB. */
+
+bool
+chrec_contains_symbols_defined_in_loop (const_tree chrec, unsigned loop_nb)
+{
+ hash_set<const_tree> visited;
+ return chrec_contains_symbols_defined_in_loop (chrec, loop_nb, visited);
+}
+
/* Determines whether the chrec contains undetermined coefficients. */
static bool
@@ -1026,6 +1088,9 @@ tree_contains_chrecs (const_tree expr, int *size, hash_set<const_tree> &visited)
if (tree_is_chrec (expr))
return true;
+ if (visited.add (expr))
+ return false;
+
n = TREE_OPERAND_LENGTH (expr);
for (i = 0; i < n; i++)
if (tree_contains_chrecs (TREE_OPERAND (expr, i), size, visited))