diff options
author | Richard Biener <rguenther@suse.de> | 2013-04-11 11:21:18 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2013-04-11 11:21:18 +0000 |
commit | 4ba5ea117ac17ad00bb26b2cb64588ae345a6491 (patch) | |
tree | 7131ce4ad93149ef59b657a80ec5ada7b65d7fb4 /gcc/tree-ssa-loop-ivopts.c | |
parent | 983a3d80db525e9d7fbba6f222d3030bfc0a68ac (diff) | |
download | gcc-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.c | 48 |
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. */ |