aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-vect-loop-manip.c
diff options
context:
space:
mode:
authorBin Cheng <bin.cheng@arm.com>2016-07-29 15:48:25 +0000
committerBin Cheng <amker@gcc.gnu.org>2016-07-29 15:48:25 +0000
commit01d32b2b8b860db7cf58b88aa1880d93dc37c450 (patch)
tree17c5a12a18cff4922671091f3bf2f74b62ff94d4 /gcc/tree-vect-loop-manip.c
parent18767ebc32eaed40760aab394fe77d0815454efd (diff)
downloadgcc-01d32b2b8b860db7cf58b88aa1880d93dc37c450.zip
gcc-01d32b2b8b860db7cf58b88aa1880d93dc37c450.tar.gz
gcc-01d32b2b8b860db7cf58b88aa1880d93dc37c450.tar.bz2
re PR tree-optimization/57558 (Loop not vectorized if iteration count could be infinite)
PR tree-optimization/57558 * tree-vect-loop-manip.c (vect_create_cond_for_niters_checks): New function. (vect_loop_versioning): Support versioning with niter assumptions. * tree-vect-loop.c (tree-ssa-loop.h): Include header file. (vect_get_loop_niters): New parameter. Reimplement to support assumptions in loop niter info. (vect_analyze_loop_form_1, vect_analyze_loop_form): Ditto. (new_loop_vec_info): Init LOOP_VINFO_NITERS_ASSUMPTIONS. (vect_estimate_min_profitable_iters): Use LOOP_REQUIRES_VERSIONING. Support loop versioning for niters. * tree-vectorizer.c (tree-ssa-loop-niter.h): Include header file. (vect_free_loop_info_assumptions): New function. (vectorize_loops): Free loop niter info for loops with flag LOOP_F_ASSUMPTIONS set if vectorization failed. * tree-vectorizer.h (struct _loop_vec_info): New field num_iters_assumptions. (LOOP_VINFO_NITERS_ASSUMPTIONS): New macro. (LOOP_REQUIRES_VERSIONING_FOR_NITERS): New macro. (LOOP_REQUIRES_VERSIONING): New macro. (vect_free_loop_info_assumptions): New decl. gcc/testsuite PR tree-optimization/57558 * gcc.dg/vect/pr57558-1.c: New test. * gcc.dg/vect/pr57558-2.c: New test. From-SVN: r238877
Diffstat (limited to 'gcc/tree-vect-loop-manip.c')
-rw-r--r--gcc/tree-vect-loop-manip.c68
1 files changed, 57 insertions, 11 deletions
diff --git a/gcc/tree-vect-loop-manip.c b/gcc/tree-vect-loop-manip.c
index 819abcd..c1381b3 100644
--- a/gcc/tree-vect-loop-manip.c
+++ b/gcc/tree-vect-loop-manip.c
@@ -2082,6 +2082,37 @@ vect_do_peeling_for_alignment (loop_vec_info loop_vinfo, tree ni_name,
free_original_copy_tables ();
}
+/* Function vect_create_cond_for_niters_checks.
+
+ Create a conditional expression that represents the run-time checks for
+ loop's niter. The loop is guaranteed to to terminate if the run-time
+ checks hold.
+
+ Input:
+ COND_EXPR - input conditional expression. New conditions will be chained
+ with logical AND operation. If it is NULL, then the function
+ is used to return the number of alias checks.
+ LOOP_VINFO - field LOOP_VINFO_MAY_ALIAS_STMTS contains the list of ddrs
+ to be checked.
+
+ Output:
+ COND_EXPR - conditional expression.
+
+ The returned COND_EXPR is the conditional expression to be used in the
+ if statement that controls which version of the loop gets executed at
+ runtime. */
+
+static void
+vect_create_cond_for_niters_checks (loop_vec_info loop_vinfo, tree *cond_expr)
+{
+ tree part_cond_expr = LOOP_VINFO_NITERS_ASSUMPTIONS (loop_vinfo);
+
+ if (*cond_expr)
+ *cond_expr = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
+ *cond_expr, part_cond_expr);
+ else
+ *cond_expr = part_cond_expr;
+}
/* Function vect_create_cond_for_align_checks.
@@ -2330,7 +2361,7 @@ void
vect_loop_versioning (loop_vec_info loop_vinfo,
unsigned int th, bool check_profitability)
{
- struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
+ struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo), *nloop;
struct loop *scalar_loop = LOOP_VINFO_SCALAR_LOOP (loop_vinfo);
basic_block condition_bb;
gphi_iterator gsi;
@@ -2347,14 +2378,19 @@ vect_loop_versioning (loop_vec_info loop_vinfo,
tree scalar_loop_iters = LOOP_VINFO_NITERS (loop_vinfo);
bool version_align = LOOP_REQUIRES_VERSIONING_FOR_ALIGNMENT (loop_vinfo);
bool version_alias = LOOP_REQUIRES_VERSIONING_FOR_ALIAS (loop_vinfo);
+ bool version_niter = LOOP_REQUIRES_VERSIONING_FOR_NITERS (loop_vinfo);
if (check_profitability)
- {
- cond_expr = fold_build2 (GT_EXPR, boolean_type_node, scalar_loop_iters,
- build_int_cst (TREE_TYPE (scalar_loop_iters), th));
- cond_expr = force_gimple_operand_1 (cond_expr, &cond_expr_stmt_list,
- is_gimple_condexpr, NULL_TREE);
- }
+ cond_expr = fold_build2 (GT_EXPR, boolean_type_node, scalar_loop_iters,
+ build_int_cst (TREE_TYPE (scalar_loop_iters),
+ th));
+
+ if (version_niter)
+ vect_create_cond_for_niters_checks (loop_vinfo, &cond_expr);
+
+ if (cond_expr)
+ cond_expr = force_gimple_operand_1 (cond_expr, &cond_expr_stmt_list,
+ is_gimple_condexpr, NULL_TREE);
if (version_align)
vect_create_cond_for_align_checks (loop_vinfo, &cond_expr,
@@ -2375,8 +2411,8 @@ vect_loop_versioning (loop_vec_info loop_vinfo,
/* We don't want to scale SCALAR_LOOP's frequencies, we need to
scale LOOP's frequencies instead. */
- loop_version (scalar_loop, cond_expr, &condition_bb,
- prob, REG_BR_PROB_BASE, REG_BR_PROB_BASE - prob, true);
+ nloop = loop_version (scalar_loop, cond_expr, &condition_bb, prob,
+ REG_BR_PROB_BASE, REG_BR_PROB_BASE - prob, true);
scale_loop_frequencies (loop, prob, REG_BR_PROB_BASE);
/* CONDITION_BB was created above SCALAR_LOOP's preheader,
while we need to move it above LOOP's preheader. */
@@ -2403,8 +2439,18 @@ vect_loop_versioning (loop_vec_info loop_vinfo,
condition_bb);
}
else
- loop_version (loop, cond_expr, &condition_bb,
- prob, prob, REG_BR_PROB_BASE - prob, true);
+ nloop = loop_version (loop, cond_expr, &condition_bb,
+ prob, prob, REG_BR_PROB_BASE - prob, true);
+
+ if (version_niter)
+ {
+ /* The versioned loop could be infinite, we need to clear existing
+ niter information which is copied from the original loop. */
+ gcc_assert (loop_constraint_set_p (loop, LOOP_C_FINITE));
+ vect_free_loop_info_assumptions (nloop);
+ /* And set constraint LOOP_C_INFINITE for niter analyzer. */
+ loop_constraint_set (loop, LOOP_C_INFINITE);
+ }
if (LOCATION_LOCUS (vect_location) != UNKNOWN_LOCATION
&& dump_enabled_p ())