Commit 335d3d54 by Dorit Naishlos Committed by Dorit Nuzman

tree-vectorizer.c (slpeel_make_loop_iterate_ntimes): Last two arguments removed.

        * tree-vectorizer.c (slpeel_make_loop_iterate_ntimes): Last two
        arguments removed.
        (slpeel_tree_peel_loop_to_edge): Call slpeel_make_loop_iterate_ntimes
        without last two arguments. Update single_exit of loops.
        (vect_update_niters_after_peeling): Removed. Its functionality was
        moved to vect_do_peeling_for_alignment.
        (vect_do_peeling_for_loop_bound): New name for function previously
        called vect_transform_for_unknown_loop_bound.
        (vect_transform_loop_bound): Call slpeel_make_loop_iterate_ntimes
        instead of code that duplicates the same functionality.
        (vect_do_peeling_for_alignment): Functionality of
        vect_update_niters_after_peeling moved here.
        (vect_transform_loop): Unify call to vect_do_peeling_for_loop_bound -
        previously named vect_transform_for_unknown_loop_bound - for both known
        and unknown loop bound cases.

From-SVN: r90931
parent d6901754
2004-11-19 Dorit Naishlos <dorit@il.ibm.com> 2004-11-19 Dorit Naishlos <dorit@il.ibm.com>
* tree-vectorizer.c (slpeel_make_loop_iterate_ntimes): Last two
arguments removed.
(slpeel_tree_peel_loop_to_edge): Call slpeel_make_loop_iterate_ntimes
without last two arguments. Update single_exit of loops.
(vect_update_niters_after_peeling): Removed. Its functionality was
moved to vect_do_peeling_for_alignment.
(vect_do_peeling_for_loop_bound): New name for function previously
called vect_transform_for_unknown_loop_bound.
(vect_transform_loop_bound): Call slpeel_make_loop_iterate_ntimes
instead of code that duplicates the same functionality.
(vect_do_peeling_for_alignment): Functionality of
vect_update_niters_after_peeling moved here.
(vect_transform_loop): Unify call to vect_do_peeling_for_loop_bound -
previously named vect_transform_for_unknown_loop_bound - for both known
and unknown loop bound cases.
2004-11-19 Dorit Naishlos <dorit@il.ibm.com>
* tree-vectorizer.c (slpeel_can_duplicate_loop_p): New name for function * tree-vectorizer.c (slpeel_can_duplicate_loop_p): New name for function
previously called verify_loop_for_duplication. All conditions compacted previously called verify_loop_for_duplication. All conditions compacted
into one compound condition. Removed debug dumps. into one compound condition. Removed debug dumps.
......
...@@ -165,7 +165,7 @@ static struct loop *slpeel_tree_duplicate_loop_to_edge_cfg ...@@ -165,7 +165,7 @@ static struct loop *slpeel_tree_duplicate_loop_to_edge_cfg
static void slpeel_update_phis_for_duplicate_loop static void slpeel_update_phis_for_duplicate_loop
(struct loop *, struct loop *, bool after); (struct loop *, struct loop *, bool after);
static void slpeel_update_phi_nodes_for_guard (edge, struct loop *); static void slpeel_update_phi_nodes_for_guard (edge, struct loop *);
static void slpeel_make_loop_iterate_ntimes (struct loop *, tree, tree, tree); static void slpeel_make_loop_iterate_ntimes (struct loop *, tree);
static edge slpeel_add_loop_guard (basic_block, tree, basic_block); static edge slpeel_add_loop_guard (basic_block, tree, basic_block);
static bool slpeel_can_duplicate_loop_p (struct loop *, edge); static bool slpeel_can_duplicate_loop_p (struct loop *, edge);
static void allocate_new_names (bitmap); static void allocate_new_names (bitmap);
...@@ -251,12 +251,11 @@ static void vect_generate_tmps_on_preheader ...@@ -251,12 +251,11 @@ static void vect_generate_tmps_on_preheader
static tree vect_build_loop_niters (loop_vec_info); static tree vect_build_loop_niters (loop_vec_info);
static void vect_update_ivs_after_vectorizer (struct loop *, tree); static void vect_update_ivs_after_vectorizer (struct loop *, tree);
static tree vect_gen_niters_for_prolog_loop (loop_vec_info, tree); static tree vect_gen_niters_for_prolog_loop (loop_vec_info, tree);
static void vect_update_niters_after_peeling (loop_vec_info, tree);
static void vect_update_inits_of_dr static void vect_update_inits_of_dr
(struct data_reference *, struct loop *, tree niters); (struct data_reference *, struct loop *, tree niters);
static void vect_update_inits_of_drs (loop_vec_info, tree); static void vect_update_inits_of_drs (loop_vec_info, tree);
static void vect_do_peeling_for_alignment (loop_vec_info, struct loops *); static void vect_do_peeling_for_alignment (loop_vec_info, struct loops *);
static void vect_transform_for_unknown_loop_bound static void vect_do_peeling_for_loop_bound
(loop_vec_info, tree *, struct loops *); (loop_vec_info, tree *, struct loops *);
/* Utilities for creation and deletion of vec_info structs. */ /* Utilities for creation and deletion of vec_info structs. */
...@@ -605,16 +604,19 @@ slpeel_update_phi_nodes_for_guard (edge guard_true_edge, struct loop * loop) ...@@ -605,16 +604,19 @@ slpeel_update_phi_nodes_for_guard (edge guard_true_edge, struct loop * loop)
/* Make the LOOP iterate NITERS times. This is done by adding a new IV /* Make the LOOP iterate NITERS times. This is done by adding a new IV
that starts at zero, increases by one and its limit is NITERS. */ that starts at zero, increases by one and its limit is NITERS.
Assumption: the exit-condition of LOOP is the last stmt in the loop. */
static void static void
slpeel_make_loop_iterate_ntimes (struct loop *loop, tree niters, slpeel_make_loop_iterate_ntimes (struct loop *loop, tree niters)
tree begin_label, tree exit_label)
{ {
tree indx_before_incr, indx_after_incr, cond_stmt, cond; tree indx_before_incr, indx_after_incr, cond_stmt, cond;
tree orig_cond; tree orig_cond;
edge exit_edge = loop->exit_edges[0]; edge exit_edge = loop->exit_edges[0];
block_stmt_iterator loop_exit_bsi = bsi_last (exit_edge->src); block_stmt_iterator loop_exit_bsi = bsi_last (exit_edge->src);
tree begin_label = tree_block_label (loop->latch);
tree exit_label = tree_block_label (loop->single_exit->dest);
/* Flow loop scan does not update loop->single_exit field. */ /* Flow loop scan does not update loop->single_exit field. */
loop->single_exit = loop->exit_edges[0]; loop->single_exit = loop->exit_edges[0];
...@@ -948,17 +950,13 @@ slpeel_tree_peel_loop_to_edge (struct loop *loop, struct loops *loops, ...@@ -948,17 +950,13 @@ slpeel_tree_peel_loop_to_edge (struct loop *loop, struct loops *loops,
and second loop preheader edge. */ and second loop preheader edge. */
flow_loop_scan (first_loop, LOOP_ALL); flow_loop_scan (first_loop, LOOP_ALL);
flow_loop_scan (second_loop, LOOP_ALL); flow_loop_scan (second_loop, LOOP_ALL);
/* Flow loop scan does not update loop->single_exit field. */
first_loop->single_exit = first_loop->exit_edges[0];
second_loop->single_exit = second_loop->exit_edges[0];
/* 3. Make first loop iterate FIRST_NITERS times, if needed. */ /* 3. Make first loop iterate FIRST_NITERS times, if needed. */
if (!update_first_loop_count) if (!update_first_loop_count)
{ slpeel_make_loop_iterate_ntimes (first_loop, first_niters);
tree first_loop_latch_lbl = tree_block_label (first_loop->latch);
tree first_loop_exit_lbl = tree_block_label (first_exit_bb);
slpeel_make_loop_iterate_ntimes (first_loop, first_niters,
first_loop_latch_lbl,
first_loop_exit_lbl);
}
/* 4. Add the guard before first loop: /* 4. Add the guard before first loop:
...@@ -2791,16 +2789,11 @@ static void ...@@ -2791,16 +2789,11 @@ static void
vect_transform_loop_bound (loop_vec_info loop_vinfo, tree niters) vect_transform_loop_bound (loop_vec_info loop_vinfo, tree niters)
{ {
struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo); struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
edge exit_edge = loop->single_exit;
block_stmt_iterator loop_exit_bsi = bsi_last (exit_edge->src);
tree indx_before_incr, indx_after_incr;
tree orig_cond_expr; tree orig_cond_expr;
HOST_WIDE_INT old_N = 0; HOST_WIDE_INT old_N = 0;
int vf; int vf;
tree cond_stmt;
tree new_loop_bound; tree new_loop_bound;
bool symbol_niters; bool symbol_niters;
tree cond;
tree lb_type; tree lb_type;
symbol_niters = !LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo); symbol_niters = !LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo);
...@@ -2814,45 +2807,16 @@ vect_transform_loop_bound (loop_vec_info loop_vinfo, tree niters) ...@@ -2814,45 +2807,16 @@ vect_transform_loop_bound (loop_vec_info loop_vinfo, tree niters)
#ifdef ENABLE_CHECKING #ifdef ENABLE_CHECKING
gcc_assert (orig_cond_expr); gcc_assert (orig_cond_expr);
#endif #endif
gcc_assert (orig_cond_expr == bsi_stmt (loop_exit_bsi));
create_iv (integer_zero_node, integer_one_node, NULL_TREE, loop,
&loop_exit_bsi, false, &indx_before_incr, &indx_after_incr);
/* bsi_insert is using BSI_NEW_STMT. We need to bump it back
to point to the exit condition. */
bsi_next (&loop_exit_bsi);
gcc_assert (bsi_stmt (loop_exit_bsi) == orig_cond_expr);
/* new loop exit test: */ /* new loop exit test: */
lb_type = TREE_TYPE (TREE_OPERAND (COND_EXPR_COND (orig_cond_expr), 1)); lb_type = TREE_TYPE (TREE_OPERAND (COND_EXPR_COND (orig_cond_expr), 1));
if (!symbol_niters) if (!symbol_niters)
new_loop_bound = fold_convert (lb_type, new_loop_bound =
build_int_cst (unsigned_type_node, fold_convert (lb_type, build_int_cst (unsigned_type_node, old_N/vf));
old_N/vf));
else else
new_loop_bound = niters; new_loop_bound = niters;
if (exit_edge->flags & EDGE_TRUE_VALUE) /* 'then' edge exits the loop. */ slpeel_make_loop_iterate_ntimes (loop, new_loop_bound);
cond = build2 (GE_EXPR, boolean_type_node,
indx_after_incr, new_loop_bound);
else /* 'then' edge loops back. */
cond = build2 (LT_EXPR, boolean_type_node,
indx_after_incr, new_loop_bound);
cond_stmt = build3 (COND_EXPR, TREE_TYPE (orig_cond_expr), cond,
COND_EXPR_THEN (orig_cond_expr),
COND_EXPR_ELSE (orig_cond_expr));
bsi_insert_before (&loop_exit_bsi, cond_stmt, BSI_SAME_STMT);
/* remove old loop exit test: */
bsi_remove (&loop_exit_bsi);
if (vect_debug_details (NULL))
print_generic_expr (dump_file, cond_stmt, TDF_SLIM);
loop->nb_iterations = new_loop_bound;
} }
...@@ -2978,8 +2942,8 @@ vect_update_ivs_after_vectorizer (struct loop *loop, tree niters) ...@@ -2978,8 +2942,8 @@ vect_update_ivs_after_vectorizer (struct loop *loop, tree niters)
unknown loop bound. */ unknown loop bound. */
static void static void
vect_transform_for_unknown_loop_bound (loop_vec_info loop_vinfo, tree * ratio, vect_do_peeling_for_loop_bound (loop_vec_info loop_vinfo, tree * ratio,
struct loops *loops) struct loops *loops)
{ {
tree ni_name, ratio_mult_vf_name; tree ni_name, ratio_mult_vf_name;
...@@ -3095,21 +3059,6 @@ vect_gen_niters_for_prolog_loop (loop_vec_info loop_vinfo, tree niters) ...@@ -3095,21 +3059,6 @@ vect_gen_niters_for_prolog_loop (loop_vec_info loop_vinfo, tree niters)
} }
/* Function vect_update_niters_after_peeling
NITERS iterations were peeled from the loop represented by LOOP_VINFO.
The new number of iterations is therefore original_niters - NITERS.
Record the new number of iterations in LOOP_VINFO. */
static void
vect_update_niters_after_peeling (loop_vec_info loop_vinfo, tree niters)
{
tree n_iters = LOOP_VINFO_NITERS (loop_vinfo);
LOOP_VINFO_NITERS (loop_vinfo) =
build (MINUS_EXPR, integer_type_node, n_iters, niters);
}
/* Function vect_update_inits_of_dr /* Function vect_update_inits_of_dr
NITERS iterations were peeled from LOOP. DR represents a data reference NITERS iterations were peeled from LOOP. DR represents a data reference
...@@ -3183,6 +3132,7 @@ vect_do_peeling_for_alignment (loop_vec_info loop_vinfo, struct loops *loops) ...@@ -3183,6 +3132,7 @@ vect_do_peeling_for_alignment (loop_vec_info loop_vinfo, struct loops *loops)
{ {
struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo); struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
tree niters_of_prolog_loop, ni_name; tree niters_of_prolog_loop, ni_name;
tree n_iters;
if (vect_debug_details (NULL)) if (vect_debug_details (NULL))
fprintf (dump_file, "\n<<vect_do_peeling_for_alignment>>\n"); fprintf (dump_file, "\n<<vect_do_peeling_for_alignment>>\n");
...@@ -3196,7 +3146,9 @@ vect_do_peeling_for_alignment (loop_vec_info loop_vinfo, struct loops *loops) ...@@ -3196,7 +3146,9 @@ vect_do_peeling_for_alignment (loop_vec_info loop_vinfo, struct loops *loops)
niters_of_prolog_loop, ni_name, false); niters_of_prolog_loop, ni_name, false);
/* Update number of times loop executes. */ /* Update number of times loop executes. */
vect_update_niters_after_peeling (loop_vinfo, niters_of_prolog_loop); n_iters = LOOP_VINFO_NITERS (loop_vinfo);
LOOP_VINFO_NITERS (loop_vinfo) =
build (MINUS_EXPR, integer_type_node, n_iters, niters_of_prolog_loop);
/* Update all inits of access functions of all data refs. */ /* Update all inits of access functions of all data refs. */
vect_update_inits_of_drs (loop_vinfo, niters_of_prolog_loop); vect_update_inits_of_drs (loop_vinfo, niters_of_prolog_loop);
...@@ -3233,32 +3185,21 @@ vect_transform_loop (loop_vec_info loop_vinfo, ...@@ -3233,32 +3185,21 @@ vect_transform_loop (loop_vec_info loop_vinfo,
/* Peel the loop if there are data refs with unknown alignment. /* Peel the loop if there are data refs with unknown alignment.
Only one data ref with unknown store is allowed. */ Only one data ref with unknown store is allowed. */
if (LOOP_DO_PEELING_FOR_ALIGNMENT (loop_vinfo)) if (LOOP_DO_PEELING_FOR_ALIGNMENT (loop_vinfo))
vect_do_peeling_for_alignment (loop_vinfo, loops); vect_do_peeling_for_alignment (loop_vinfo, loops);
/* If the loop has a symbolic number of iterations 'n' /* If the loop has a symbolic number of iterations 'n' (i.e. it's not a
(i.e. it's not a compile time constant), compile time constant), or it is a constant that doesn't divide by the
then an epilog loop needs to be created. We therefore duplicate vectorization factor, then an epilog loop needs to be created.
the initial loop. The original loop will be vectorized, and will compute We therefore duplicate the loop: the original loop will be vectorized,
the first (n/VF) iterations. The second copy of the loop will remain and will compute the first (n/VF) iterations. The second copy of the loop
serial and will compute the remaining (n%VF) iterations. will remain scalar and will compute the remaining (n%VF) iterations.
(VF is the vectorization factor). */ (VF is the vectorization factor). */
if (!LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)) if (!LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
vect_transform_for_unknown_loop_bound (loop_vinfo, &ratio, loops); || (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
&& LOOP_VINFO_INT_NITERS (loop_vinfo) % vectorization_factor != 0))
/* FORNOW: we'll treat the case where niters is constant and vect_do_peeling_for_loop_bound (loop_vinfo, &ratio, loops);
niters % vf != 0
in the way similar to one with symbolic niters.
For this we'll generate variable which value is equal to niters. */
if (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
&& (LOOP_VINFO_INT_NITERS (loop_vinfo) % vectorization_factor != 0))
vect_transform_for_unknown_loop_bound (loop_vinfo, &ratio, loops);
/* 1) Make sure the loop header has exactly two entries /* 1) Make sure the loop header has exactly two entries
2) Make sure we have a preheader basic block. */ 2) Make sure we have a preheader basic block. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment