diff options
author | Bin Cheng <bin.cheng@arm.com> | 2016-07-29 15:48:25 +0000 |
---|---|---|
committer | Bin Cheng <amker@gcc.gnu.org> | 2016-07-29 15:48:25 +0000 |
commit | 01d32b2b8b860db7cf58b88aa1880d93dc37c450 (patch) | |
tree | 17c5a12a18cff4922671091f3bf2f74b62ff94d4 /gcc/tree-vect-loop-manip.c | |
parent | 18767ebc32eaed40760aab394fe77d0815454efd (diff) | |
download | gcc-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.c | 68 |
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 ()) |