aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-loop-ivopts.c
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2013-04-11 11:21:18 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2013-04-11 11:21:18 +0000
commit4ba5ea117ac17ad00bb26b2cb64588ae345a6491 (patch)
tree7131ce4ad93149ef59b657a80ec5ada7b65d7fb4 /gcc/tree-ssa-loop-ivopts.c
parent983a3d80db525e9d7fbba6f222d3030bfc0a68ac (diff)
downloadgcc-4ba5ea117ac17ad00bb26b2cb64588ae345a6491.zip
gcc-4ba5ea117ac17ad00bb26b2cb64588ae345a6491.tar.gz
gcc-4ba5ea117ac17ad00bb26b2cb64588ae345a6491.tar.bz2
re PR tree-optimization/56878 (Issue with candidate choice in vect_gen_niters_for_prolog_loop.)
2013-04-11 Richard Biener <rguenther@suse.de> PR tree-optimization/56878 * tree-flow.h (outermost_invariant_loop_for_expr): Declare. * tree-ssa-loop-ivopts.c (outermost_invariant_loop_for_expr): New function. * tree-vect-data-refs.c (vect_enhance_data_refs_alignment): Prefer to align the DR with the most invariant base address. From-SVN: r197769
Diffstat (limited to 'gcc/tree-ssa-loop-ivopts.c')
-rw-r--r--gcc/tree-ssa-loop-ivopts.c48
1 files changed, 48 insertions, 0 deletions
diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c
index 2940bf1..0099275 100644
--- a/gcc/tree-ssa-loop-ivopts.c
+++ b/gcc/tree-ssa-loop-ivopts.c
@@ -1367,6 +1367,54 @@ find_interesting_uses_cond (struct ivopts_data *data, gimple stmt)
record_use (data, NULL, civ, stmt, USE_COMPARE);
}
+/* Returns the outermost loop EXPR is obviously invariant in
+ relative to the loop LOOP, i.e. if all its operands are defined
+ outside of the returned loop. Returns NULL if EXPR is not
+ even obviously invariant in LOOP. */
+
+struct loop *
+outermost_invariant_loop_for_expr (struct loop *loop, tree expr)
+{
+ basic_block def_bb;
+ unsigned i, len;
+
+ if (is_gimple_min_invariant (expr))
+ return current_loops->tree_root;
+
+ if (TREE_CODE (expr) == SSA_NAME)
+ {
+ def_bb = gimple_bb (SSA_NAME_DEF_STMT (expr));
+ if (def_bb)
+ {
+ if (flow_bb_inside_loop_p (loop, def_bb))
+ return NULL;
+ return superloop_at_depth (loop,
+ loop_depth (def_bb->loop_father) + 1);
+ }
+
+ return current_loops->tree_root;
+ }
+
+ if (!EXPR_P (expr))
+ return NULL;
+
+ unsigned maxdepth = 0;
+ len = TREE_OPERAND_LENGTH (expr);
+ for (i = 0; i < len; i++)
+ {
+ struct loop *ivloop;
+ if (!TREE_OPERAND (expr, i))
+ continue;
+
+ ivloop = outermost_invariant_loop_for_expr (loop, TREE_OPERAND (expr, i));
+ if (!ivloop)
+ return NULL;
+ maxdepth = MAX (maxdepth, loop_depth (ivloop));
+ }
+
+ return superloop_at_depth (loop, maxdepth);
+}
+
/* Returns true if expression EXPR is obviously invariant in LOOP,
i.e. if all its operands are defined outside of the LOOP. LOOP
should not be the function body. */