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
This commit is contained in:
Dorit Naishlos 2004-11-19 19:08:03 +00:00 committed by Dorit Nuzman
parent d690175432
commit 335d3d5495
2 changed files with 49 additions and 90 deletions

View File

@ -1,3 +1,21 @@
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

View File

@ -165,7 +165,7 @@ static struct loop *slpeel_tree_duplicate_loop_to_edge_cfg
static void slpeel_update_phis_for_duplicate_loop
(struct loop *, struct loop *, bool after);
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 bool slpeel_can_duplicate_loop_p (struct loop *, edge);
static void allocate_new_names (bitmap);
@ -251,12 +251,11 @@ static void vect_generate_tmps_on_preheader
static tree vect_build_loop_niters (loop_vec_info);
static void vect_update_ivs_after_vectorizer (struct loop *, 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
(struct data_reference *, struct loop *, tree niters);
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_transform_for_unknown_loop_bound
static void vect_do_peeling_for_loop_bound
(loop_vec_info, tree *, struct loops *);
/* 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)
/* 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
slpeel_make_loop_iterate_ntimes (struct loop *loop, tree niters,
tree begin_label, tree exit_label)
slpeel_make_loop_iterate_ntimes (struct loop *loop, tree niters)
{
tree indx_before_incr, indx_after_incr, cond_stmt, cond;
tree orig_cond;
edge exit_edge = loop->exit_edges[0];
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. */
loop->single_exit = loop->exit_edges[0];
@ -948,17 +950,13 @@ slpeel_tree_peel_loop_to_edge (struct loop *loop, struct loops *loops,
and second loop preheader edge. */
flow_loop_scan (first_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. */
if (!update_first_loop_count)
{
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);
}
slpeel_make_loop_iterate_ntimes (first_loop, first_niters);
/* 4. Add the guard before first loop:
@ -2791,16 +2789,11 @@ static void
vect_transform_loop_bound (loop_vec_info loop_vinfo, tree niters)
{
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;
HOST_WIDE_INT old_N = 0;
int vf;
tree cond_stmt;
tree new_loop_bound;
bool symbol_niters;
tree cond;
tree lb_type;
symbol_niters = !LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo);
@ -2814,45 +2807,16 @@ vect_transform_loop_bound (loop_vec_info loop_vinfo, tree niters)
#ifdef ENABLE_CHECKING
gcc_assert (orig_cond_expr);
#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: */
lb_type = TREE_TYPE (TREE_OPERAND (COND_EXPR_COND (orig_cond_expr), 1));
if (!symbol_niters)
new_loop_bound = fold_convert (lb_type,
build_int_cst (unsigned_type_node,
old_N/vf));
new_loop_bound =
fold_convert (lb_type, build_int_cst (unsigned_type_node, old_N/vf));
else
new_loop_bound = niters;
if (exit_edge->flags & EDGE_TRUE_VALUE) /* 'then' edge exits the loop. */
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;
slpeel_make_loop_iterate_ntimes (loop, new_loop_bound);
}
@ -2978,8 +2942,8 @@ vect_update_ivs_after_vectorizer (struct loop *loop, tree niters)
unknown loop bound. */
static void
vect_transform_for_unknown_loop_bound (loop_vec_info loop_vinfo, tree * ratio,
struct loops *loops)
vect_do_peeling_for_loop_bound (loop_vec_info loop_vinfo, tree * ratio,
struct loops *loops)
{
tree ni_name, ratio_mult_vf_name;
@ -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
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)
{
struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
tree niters_of_prolog_loop, ni_name;
tree n_iters;
if (vect_debug_details (NULL))
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)
niters_of_prolog_loop, ni_name, false);
/* 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. */
vect_update_inits_of_drs (loop_vinfo, niters_of_prolog_loop);
@ -3233,32 +3185,21 @@ vect_transform_loop (loop_vec_info loop_vinfo,
/* Peel the loop if there are data refs with unknown alignment.
Only one data ref with unknown store is allowed. */
if (LOOP_DO_PEELING_FOR_ALIGNMENT (loop_vinfo))
vect_do_peeling_for_alignment (loop_vinfo, loops);
/* If the loop has a symbolic number of iterations 'n'
(i.e. it's not a compile time constant),
then an epilog loop needs to be created. We therefore duplicate
the initial loop. The original loop will be vectorized, and will compute
the first (n/VF) iterations. The second copy of the loop will remain
serial and will compute the remaining (n%VF) iterations.
/* 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_NITERS_KNOWN_P (loop_vinfo))
vect_transform_for_unknown_loop_bound (loop_vinfo, &ratio, loops);
/* FORNOW: we'll treat the case where niters is constant and
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);
if (!LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
|| (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
&& LOOP_VINFO_INT_NITERS (loop_vinfo) % vectorization_factor != 0))
vect_do_peeling_for_loop_bound (loop_vinfo, &ratio, loops);
/* 1) Make sure the loop header has exactly two entries
2) Make sure we have a preheader basic block. */