aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-vect-loop.c
diff options
context:
space:
mode:
authorBin Cheng <bin.cheng@arm.com>2016-10-13 11:03:31 +0000
committerBin Cheng <amker@gcc.gnu.org>2016-10-13 11:03:31 +0000
commita5e3d6146d07611eb967befec4dc480c8a19db0d (patch)
treed06f61f6ed26f287b7714e5de2d0d009eff03904 /gcc/tree-vect-loop.c
parent3884da6f21ef44778d38b90afc5738ee3d49b4e6 (diff)
downloadgcc-a5e3d6146d07611eb967befec4dc480c8a19db0d.zip
gcc-a5e3d6146d07611eb967befec4dc480c8a19db0d.tar.gz
gcc-a5e3d6146d07611eb967befec4dc480c8a19db0d.tar.bz2
tree-vect-loop-manip.c (adjust_vec_debug_stmts): Don't release adjust_vec automatically.
* tree-vect-loop-manip.c (adjust_vec_debug_stmts): Don't release adjust_vec automatically. (slpeel_add_loop_guard): Remove param cond_expr_stmt_list. Rename param exit_bb to guard_to. (slpeel_checking_verify_cfg_after_peeling): (set_prologue_iterations): (create_lcssa_for_virtual_phi): New func which is factored out from slpeel_tree_peel_loop_to_edge. (slpeel_tree_peel_loop_to_edge): (iv_phi_p): New func. (vect_can_advance_ivs_p): Call iv_phi_p. (vect_update_ivs_after_vectorizer): Call iv_phi_p. Directly insert new gimple stmts in basic block. (vect_do_peeling_for_loop_bound): (vect_do_peeling_for_alignment): (vect_gen_niters_for_prolog_loop): Rename to... (vect_gen_prolog_loop_niters): ...Rename from. Change parameters and adjust implementation. (vect_update_inits_of_drs): Fix code style issue. Convert niters to sizetype if necessary. (vect_build_loop_niters): Move to here from tree-vect-loop.c. Change it to external function. (vect_gen_scalar_loop_niters, vect_gen_vector_loop_niters): New. (vect_gen_vector_loop_niters_mult_vf): New. (slpeel_update_phi_nodes_for_loops): New. (slpeel_update_phi_nodes_for_guard1): Reimplement. (find_guard_arg, slpeel_update_phi_nodes_for_guard2): Reimplement. (slpeel_update_phi_nodes_for_lcssa, vect_do_peeling): New. * tree-vect-loop.c (vect_build_loop_niters): Move to file tree-vect-loop-manip.c (vect_generate_tmps_on_preheader): Delete. (vect_transform_loop): Rename vectorization_factor to vf. Call vect_do_peeling instead of vect_do_peeling-* functions. * tree-vectorizer.h (vect_do_peeling): New decl. (vect_build_loop_niters, vect_gen_vector_loop_niters): New decls. (vect_do_peeling_for_loop_bound): Delete. (vect_do_peeling_for_alignment): Delete. From-SVN: r241099
Diffstat (limited to 'gcc/tree-vect-loop.c')
-rw-r--r--gcc/tree-vect-loop.c191
1 files changed, 23 insertions, 168 deletions
diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c
index be6f3fb..0470445 100644
--- a/gcc/tree-vect-loop.c
+++ b/gcc/tree-vect-loop.c
@@ -6620,120 +6620,6 @@ vect_loop_kill_debug_uses (struct loop *loop, gimple *stmt)
}
}
-
-/* This function builds ni_name = number of iterations. Statements
- are emitted on the loop preheader edge. */
-
-static tree
-vect_build_loop_niters (loop_vec_info loop_vinfo)
-{
- tree ni = unshare_expr (LOOP_VINFO_NITERS (loop_vinfo));
- if (TREE_CODE (ni) == INTEGER_CST)
- return ni;
- else
- {
- tree ni_name, var;
- gimple_seq stmts = NULL;
- edge pe = loop_preheader_edge (LOOP_VINFO_LOOP (loop_vinfo));
-
- var = create_tmp_var (TREE_TYPE (ni), "niters");
- ni_name = force_gimple_operand (ni, &stmts, false, var);
- if (stmts)
- gsi_insert_seq_on_edge_immediate (pe, stmts);
-
- return ni_name;
- }
-}
-
-
-/* This function generates the following statements:
-
- ni_name = number of iterations loop executes
- ratio = ni_name / vf
- ratio_mult_vf_name = ratio * vf
-
- and places them on the loop preheader edge. */
-
-static void
-vect_generate_tmps_on_preheader (loop_vec_info loop_vinfo,
- tree ni_name,
- tree *ratio_mult_vf_name_ptr,
- tree *ratio_name_ptr)
-{
- tree ni_minus_gap_name;
- tree var;
- tree ratio_name;
- tree ratio_mult_vf_name;
- int vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
- edge pe = loop_preheader_edge (LOOP_VINFO_LOOP (loop_vinfo));
- tree log_vf;
-
- log_vf = build_int_cst (TREE_TYPE (ni_name), exact_log2 (vf));
-
- /* If epilogue loop is required because of data accesses with gaps, we
- subtract one iteration from the total number of iterations here for
- correct calculation of RATIO. */
- if (LOOP_VINFO_PEELING_FOR_GAPS (loop_vinfo))
- {
- ni_minus_gap_name = fold_build2 (MINUS_EXPR, TREE_TYPE (ni_name),
- ni_name,
- build_one_cst (TREE_TYPE (ni_name)));
- if (!is_gimple_val (ni_minus_gap_name))
- {
- var = create_tmp_var (TREE_TYPE (ni_name), "ni_gap");
- gimple *stmts = NULL;
- ni_minus_gap_name = force_gimple_operand (ni_minus_gap_name, &stmts,
- true, var);
- gsi_insert_seq_on_edge_immediate (pe, stmts);
- }
- }
- else
- ni_minus_gap_name = ni_name;
-
- /* Create: ratio = ni >> log2(vf) */
- /* ??? As we have ni == number of latch executions + 1, ni could
- have overflown to zero. So avoid computing ratio based on ni
- but compute it using the fact that we know ratio will be at least
- one, thus via (ni - vf) >> log2(vf) + 1. */
- ratio_name
- = fold_build2 (PLUS_EXPR, TREE_TYPE (ni_name),
- fold_build2 (RSHIFT_EXPR, TREE_TYPE (ni_name),
- fold_build2 (MINUS_EXPR, TREE_TYPE (ni_name),
- ni_minus_gap_name,
- build_int_cst
- (TREE_TYPE (ni_name), vf)),
- log_vf),
- build_int_cst (TREE_TYPE (ni_name), 1));
- if (!is_gimple_val (ratio_name))
- {
- var = create_tmp_var (TREE_TYPE (ni_name), "bnd");
- gimple *stmts = NULL;
- ratio_name = force_gimple_operand (ratio_name, &stmts, true, var);
- gsi_insert_seq_on_edge_immediate (pe, stmts);
- }
- *ratio_name_ptr = ratio_name;
-
- /* Create: ratio_mult_vf = ratio << log2 (vf). */
-
- if (ratio_mult_vf_name_ptr)
- {
- ratio_mult_vf_name = fold_build2 (LSHIFT_EXPR, TREE_TYPE (ratio_name),
- ratio_name, log_vf);
- if (!is_gimple_val (ratio_mult_vf_name))
- {
- var = create_tmp_var (TREE_TYPE (ni_name), "ratio_mult_vf");
- gimple *stmts = NULL;
- ratio_mult_vf_name = force_gimple_operand (ratio_mult_vf_name, &stmts,
- true, var);
- gsi_insert_seq_on_edge_immediate (pe, stmts);
- }
- *ratio_mult_vf_name_ptr = ratio_mult_vf_name;
- }
-
- return;
-}
-
-
/* Function vect_transform_loop.
The analysis phase has determined that the loop is vectorizable.
@@ -6747,8 +6633,8 @@ vect_transform_loop (loop_vec_info loop_vinfo)
basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
int nbbs = loop->num_nodes;
int i;
- tree ratio = NULL;
- int vectorization_factor = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
+ tree niters_vector = NULL;
+ int vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
bool grouped_store;
bool slp_scheduled = false;
gimple *stmt, *pattern_stmt;
@@ -6818,49 +6704,20 @@ vect_transform_loop (loop_vec_info loop_vinfo)
}
}
- tree ni_name = vect_build_loop_niters (loop_vinfo);
- LOOP_VINFO_NITERS_UNCHANGED (loop_vinfo) = ni_name;
-
- /* Peel the loop if there are data refs with unknown alignment.
- Only one data ref with unknown store is allowed. */
-
- if (LOOP_VINFO_PEELING_FOR_ALIGNMENT (loop_vinfo))
+ tree niters = vect_build_loop_niters (loop_vinfo);
+ LOOP_VINFO_NITERS_UNCHANGED (loop_vinfo) = niters;
+ tree nitersm1 = unshare_expr (LOOP_VINFO_NITERSM1 (loop_vinfo));
+ vect_do_peeling (loop_vinfo, niters, nitersm1, &niters_vector, th,
+ check_profitability, false);
+ if (niters_vector == NULL_TREE)
{
- vect_do_peeling_for_alignment (loop_vinfo, ni_name,
- th, check_profitability);
- check_profitability = false;
- /* The above adjusts LOOP_VINFO_NITERS, so cause ni_name to
- be re-computed. */
- ni_name = NULL_TREE;
- }
-
- /* If the loop has a symbolic number of iterations 'n' (i.e. it's not a
- compile time constant), or it is a constant that doesn't divide by the
- vectorization factor, then an epilog loop needs to be created.
- We therefore duplicate the loop: the original loop will be vectorized,
- and will compute the first (n/VF) iterations. The second copy of the loop
- will remain scalar and will compute the remaining (n%VF) iterations.
- (VF is the vectorization factor). */
-
- if (LOOP_VINFO_PEELING_FOR_NITER (loop_vinfo)
- || LOOP_VINFO_PEELING_FOR_GAPS (loop_vinfo))
- {
- tree ratio_mult_vf;
- if (!ni_name)
- ni_name = vect_build_loop_niters (loop_vinfo);
- vect_generate_tmps_on_preheader (loop_vinfo, ni_name, &ratio_mult_vf,
- &ratio);
- vect_do_peeling_for_loop_bound (loop_vinfo, ni_name, ratio_mult_vf,
- th, check_profitability);
- }
- else if (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo))
- ratio = build_int_cst (TREE_TYPE (LOOP_VINFO_NITERS (loop_vinfo)),
- LOOP_VINFO_INT_NITERS (loop_vinfo) / vectorization_factor);
- else
- {
- if (!ni_name)
- ni_name = vect_build_loop_niters (loop_vinfo);
- vect_generate_tmps_on_preheader (loop_vinfo, ni_name, NULL, &ratio);
+ if (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo))
+ niters_vector
+ = build_int_cst (TREE_TYPE (LOOP_VINFO_NITERS (loop_vinfo)),
+ LOOP_VINFO_INT_NITERS (loop_vinfo) / vf);
+ else
+ vect_gen_vector_loop_niters (loop_vinfo, niters, &niters_vector,
+ false);
}
/* 1) Make sure the loop header has exactly two entries
@@ -6903,7 +6760,7 @@ vect_transform_loop (loop_vec_info loop_vinfo)
if (STMT_VINFO_VECTYPE (stmt_info)
&& (TYPE_VECTOR_SUBPARTS (STMT_VINFO_VECTYPE (stmt_info))
- != (unsigned HOST_WIDE_INT) vectorization_factor)
+ != (unsigned HOST_WIDE_INT) vf)
&& dump_enabled_p ())
dump_printf_loc (MSG_NOTE, vect_location, "multiple-types.\n");
@@ -7036,7 +6893,7 @@ vect_transform_loop (loop_vec_info loop_vinfo)
= (unsigned int)
TYPE_VECTOR_SUBPARTS (STMT_VINFO_VECTYPE (stmt_info));
if (!STMT_SLP_TYPE (stmt_info)
- && nunits != (unsigned int) vectorization_factor
+ && nunits != (unsigned int) vf
&& dump_enabled_p ())
/* For SLP VF is set according to unrolling factor, and not
to vector size, hence for SLP this print is not valid. */
@@ -7108,11 +6965,11 @@ vect_transform_loop (loop_vec_info loop_vinfo)
} /* stmts in BB */
} /* BBs in loop */
- slpeel_make_loop_iterate_ntimes (loop, ratio);
+ slpeel_make_loop_iterate_ntimes (loop, niters_vector);
/* Reduce loop iterations by the vectorization factor. */
- scale_loop_profile (loop, GCOV_COMPUTE_SCALE (1, vectorization_factor),
- expected_iterations / vectorization_factor);
+ scale_loop_profile (loop, GCOV_COMPUTE_SCALE (1, vf),
+ expected_iterations / vf);
if (LOOP_VINFO_PEELING_FOR_GAPS (loop_vinfo))
{
if (loop->nb_iterations_upper_bound != 0)
@@ -7122,16 +6979,14 @@ vect_transform_loop (loop_vec_info loop_vinfo)
= loop->nb_iterations_likely_upper_bound - 1;
}
loop->nb_iterations_upper_bound
- = wi::udiv_floor (loop->nb_iterations_upper_bound + 1,
- vectorization_factor) - 1;
+ = wi::udiv_floor (loop->nb_iterations_upper_bound + 1, vf) - 1;
loop->nb_iterations_likely_upper_bound
- = wi::udiv_floor (loop->nb_iterations_likely_upper_bound + 1,
- vectorization_factor) - 1;
+ = wi::udiv_floor (loop->nb_iterations_likely_upper_bound + 1, vf) - 1;
if (loop->any_estimate)
{
loop->nb_iterations_estimate
- = wi::udiv_floor (loop->nb_iterations_estimate, vectorization_factor);
+ = wi::udiv_floor (loop->nb_iterations_estimate, vf);
if (LOOP_VINFO_PEELING_FOR_GAPS (loop_vinfo)
&& loop->nb_iterations_estimate != 0)
loop->nb_iterations_estimate = loop->nb_iterations_estimate - 1;