Commit d6901754 by Dorit Naishlos Committed by Dorit Nuzman

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.

        * tree-vectorizer.c (slpeel_can_duplicate_loop_p): New name for function
        previously called verify_loop_for_duplication. All conditions compacted
        into one compound condition. Removed debug dumps.
        (vect_analyze_loop_with_symbolic_num_of_iters): Removed. Some of the
        functionality moved to vect_can_advance_ivs_p, and some to
        vect_analyze_loop_form.
        (vect_can_advance_ivs_p): New function. Contains functionality that was
        taken out of vect_analyze_loop_with_symbolic_num_of_iters.
        (slpeel_tree_peel_loop_to_edge): Call slpeel_can_duplicate_loop_p.
        (vect_analyze_operations): Call vect_can_advance_ivs_p and
        slpeel_can_duplicate_loop_p.
        (vect_get_loop_niters): Added documentation.
        (vect_analyze_loop_form): Check the loop entry always - not only in case
        of unknown loop bound. Create preheader and exit bb if necessary. Apply
        a check that used to take place in
        vect_analyze_loop_with_symbolic_num_of_iters.
        (vectorize_loops): Call verify_loop_closed_ssa under ENABLE_CHECKING.
        Remove redundant call to rewrite_into_loop_closed_ssa.
        (vect_compute_data_refs_alignment): Removed obsolete comment.

From-SVN: r90930
parent f88a8cfa
2004-11-19 Dorit Naishlos <dorit@il.ibm.com>
* tree-vectorizer.c (slpeel_can_duplicate_loop_p): New name for function
previously called verify_loop_for_duplication. All conditions compacted
into one compound condition. Removed debug dumps.
(vect_analyze_loop_with_symbolic_num_of_iters): Removed. Some of the
functionality moved to vect_can_advance_ivs_p, and some to
vect_analyze_loop_form.
(vect_can_advance_ivs_p): New function. Contains functionality that was
taken out of vect_analyze_loop_with_symbolic_num_of_iters.
(slpeel_tree_peel_loop_to_edge): Call slpeel_can_duplicate_loop_p.
(vect_analyze_operations): Call vect_can_advance_ivs_p and
slpeel_can_duplicate_loop_p.
(vect_get_loop_niters): Added documentation.
(vect_analyze_loop_form): Check the loop entry always - not only in case
of unknown loop bound. Create preheader and exit bb if necessary. Apply
a check that used to take place in
vect_analyze_loop_with_symbolic_num_of_iters.
(vectorize_loops): Call verify_loop_closed_ssa under ENABLE_CHECKING.
Remove redundant call to rewrite_into_loop_closed_ssa.
(vect_compute_data_refs_alignment): Removed obsolete comment.
2004-11-19 Dorit Naishlos <dorit@il.ibm.com>
* tree-vectorizer.c (slpeel_tree_peel_loop_to_edge): New name for
function previously called tree_duplicate_loop_to_edge.
(slpeel_tree_duplicate_loop_to_edge_cfg): New name for function
......
......@@ -167,6 +167,7 @@ static void slpeel_update_phis_for_duplicate_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 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);
static void rename_use_op (use_operand_p);
static void rename_def_op (def_operand_p, tree);
......@@ -217,8 +218,7 @@ static bool vect_get_first_index (tree, tree *);
static bool vect_can_force_dr_alignment_p (tree, unsigned int);
static struct data_reference * vect_analyze_pointer_ref_access
(tree, tree, bool);
static bool vect_analyze_loop_with_symbolic_num_of_iters
(tree niters, struct loop *loop);
static bool vect_can_advance_ivs_p (struct loop *);
static tree vect_get_base_and_bit_offset
(struct data_reference *, tree, tree, loop_vec_info, tree *, bool*);
static struct data_reference * vect_analyze_pointer_ref_access
......@@ -799,83 +799,37 @@ slpeel_add_loop_guard (basic_block guard_bb, tree cond, basic_block exit_bb)
}
/* This function verifies that certain restrictions apply to LOOP. */
/* This function verifies that the following restrictions apply to LOOP:
(1) it is innermost
(2) it consists of exactly 2 basic blocks - header, and an empty latch.
(3) it is single entry, single exit
(4) its exit condition is the last stmt in the header
(5) E is the entry/exit edge of LOOP.
*/
static bool
slpeel_verify_loop_for_duplication (struct loop *loop,
bool update_first_loop_count, edge e)
slpeel_can_duplicate_loop_p (struct loop *loop, edge e)
{
edge exit_e = loop->exit_edges [0];
edge entry_e = loop_preheader_edge (loop);
/* We duplicate only innermost loops. */
if (loop->inner)
{
if (vect_debug_stats (loop) || vect_debug_details (loop))
fprintf (dump_file,
"Loop duplication failed. Loop is not innermost.\n");
return false;
}
/* Only loops with 1 exit. */
if (loop->num_exits != 1)
{
if (vect_debug_stats (loop) || vect_debug_details (loop))
fprintf (dump_file,
"More than one exit from loop.\n");
return false;
}
/* Only loops with 1 entry. */
if (loop->num_entries != 1)
{
if (vect_debug_stats (loop) || vect_debug_details (loop))
fprintf (dump_file,
"More than one exit from loop.\n");
return false;
}
/* All loops has outers, the only case loop->outer is NULL is for
the function itself. */
if (!loop->outer)
{
if (vect_debug_stats (loop) || vect_debug_details (loop))
fprintf (dump_file,
"Loop is outer-most loop.\n");
return false;
}
/* Verify that new IV can be created and loop condition
can be changed to make first loop iterate first_niters times. */
if (!update_first_loop_count)
{
tree orig_cond = get_loop_exit_condition (loop);
block_stmt_iterator loop_exit_bsi = bsi_last (exit_e->src);
if (!orig_cond)
{
if (vect_debug_stats (loop) || vect_debug_details (loop))
fprintf (dump_file,
"Loop has no exit condition.\n");
if (any_marked_for_rewrite_p ())
return false;
}
if (orig_cond != bsi_stmt (loop_exit_bsi))
{
if (vect_debug_stats (loop) || vect_debug_details (loop))
fprintf (dump_file,
"Loop exit condition is not loop header last stmt.\n");
return false;
}
}
/* Make sure E is either an entry or an exit edge. */
if (e != exit_e && e != entry_e)
{
if (vect_debug_stats (loop) || vect_debug_details (loop))
fprintf (dump_file,
"E is not loop entry or exit edge.\n");
if (loop->inner
/* All loops have an outer scope; the only case loop->outer is NULL is for
the function itself. */
|| !loop->outer
|| loop->num_nodes != 2
|| !empty_block_p (loop->latch)
|| loop->num_exits != 1
|| loop->num_entries != 1
/* Verify that new loop exit condition can be trivially modified. */
|| (!orig_cond || orig_cond != bsi_stmt (loop_exit_bsi))
|| (e != exit_e && e != entry_e))
return false;
}
return true;
}
......@@ -949,9 +903,7 @@ slpeel_tree_peel_loop_to_edge (struct loop *loop, struct loops *loops,
basic_block pre_header_bb;
edge exit_e = loop->exit_edges [0];
gcc_assert (!any_marked_for_rewrite_p ());
if (!slpeel_verify_loop_for_duplication (loop, update_first_loop_count, e))
if (!slpeel_can_duplicate_loop_p (loop, e))
return NULL;
/* We have to initialize cfg_hooks. Then, when calling
......@@ -3595,23 +3547,26 @@ vect_analyze_operations (loop_vec_info loop_vinfo)
}
LOOP_VINFO_VECT_FACTOR (loop_vinfo) = vectorization_factor;
if (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
&& vect_debug_details (NULL))
if (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo) && vect_debug_details (NULL))
fprintf (dump_file,
"vectorization_factor = %d, niters = " HOST_WIDE_INT_PRINT_DEC,
vectorization_factor, LOOP_VINFO_INT_NITERS (loop_vinfo));
if (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
&& LOOP_VINFO_INT_NITERS (loop_vinfo) % vectorization_factor != 0)
if (!LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
|| LOOP_VINFO_INT_NITERS (loop_vinfo) % vectorization_factor != 0)
{
if (vect_debug_stats (loop) || vect_debug_details (loop))
fprintf (dump_file, "epilog loop required.");
if (!vect_can_advance_ivs_p (loop))
{
/* In this case we have to generate epilog loop, that
can be done only for loops with one entry edge. */
if (LOOP_VINFO_LOOP (loop_vinfo)->num_entries != 1
|| !(LOOP_VINFO_LOOP (loop_vinfo)->pre_header))
if (vect_debug_stats (loop) || vect_debug_details (loop))
fprintf (dump_file, "not vectorized: can't create epilog loop 1.");
return false;
}
if (!slpeel_can_duplicate_loop_p (loop, loop->exit_edges[0]))
{
if (vect_debug_stats (loop) || vect_debug_details (loop))
fprintf (dump_file, "not vectorized: more than one entry.");
fprintf (dump_file, "not vectorized: can't create epilog loop 2.");
return false;
}
}
......@@ -4358,9 +4313,7 @@ vect_compute_data_refs_alignment (loop_vec_info loop_vinfo)
FOR NOW: we assume that whatever versioning/peeling takes place, only the
original loop is to be vectorized; Any other loops that are created by
the transformations performed in this pass - are not supposed to be
vectorized. This restriction will be relaxed.
FOR NOW: No transformation is actually performed. TODO. */
vectorized. This restriction will be relaxed. */
static void
vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
......@@ -5347,7 +5300,7 @@ vect_mark_stmts_to_be_vectorized (loop_vec_info loop_vinfo)
}
/* Function vect_analyze_loop_with_symbolic_num_of_iters.
/* Function vect_can_advance_ivs_p
In case the number of iterations that LOOP iterates in unknown at compile
time, an epilog loop will be generated, and the loop induction variables
......@@ -5357,36 +5310,11 @@ vect_mark_stmts_to_be_vectorized (loop_vec_info loop_vinfo)
These restrictions will be relaxed in the future. */
static bool
vect_analyze_loop_with_symbolic_num_of_iters (tree niters,
struct loop *loop)
vect_can_advance_ivs_p (struct loop *loop)
{
basic_block bb = loop->header;
tree phi;
if (vect_debug_details (NULL))
fprintf (dump_file,
"\n<<vect_analyze_loop_with_symbolic_num_of_iters>>\n");
if (chrec_contains_undetermined (niters))
{
if (vect_debug_details (NULL))
fprintf (dump_file, "Infinite number of iterations.");
return false;
}
if (!niters)
{
if (vect_debug_details (NULL))
fprintf (dump_file, "niters is NULL pointer.");
return false;
}
if (vect_debug_details (NULL))
{
fprintf (dump_file, "Symbolic number of iterations is ");
print_generic_expr (dump_file, niters, TDF_DETAILS);
}
/* Analyze phi functions of the loop header. */
for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
......@@ -5446,7 +5374,10 @@ vect_analyze_loop_with_symbolic_num_of_iters (tree niters,
/* Function vect_get_loop_niters.
Determine how many iterations the loop is executed. */
Determine how many iterations the loop is executed.
If an expression that represents the number of iterations
can be constructed, place it in NUMBER_OF_ITERATIONS.
Return the loop exit condition. */
static tree
vect_get_loop_niters (struct loop *loop, tree *number_of_iterations)
......@@ -5490,13 +5421,16 @@ vect_analyze_loop_form (struct loop *loop)
loop_vec_info loop_vinfo;
tree loop_cond;
tree number_of_iterations = NULL;
bool rescan = false;
if (vect_debug_details (loop))
fprintf (dump_file, "\n<<vect_analyze_loop_form>>\n");
if (loop->inner
|| !loop->single_exit
|| loop->num_nodes != 2)
|| loop->num_nodes != 2
|| EDGE_COUNT (loop->header->preds) != 2
|| loop->num_entries != 1)
{
if (vect_debug_stats (loop) || vect_debug_details (loop))
{
......@@ -5507,6 +5441,10 @@ vect_analyze_loop_form (struct loop *loop)
fprintf (dump_file, "multiple exits.");
else if (loop->num_nodes != 2)
fprintf (dump_file, "too many BBs in loop.");
else if (EDGE_COUNT (loop->header->preds) != 2)
fprintf (dump_file, "too many incoming edges.");
else if (loop->num_entries != 1)
fprintf (dump_file, "too many entries.");
}
return NULL;
......@@ -5523,6 +5461,27 @@ vect_analyze_loop_form (struct loop *loop)
return NULL;
}
/* Make sure we have a preheader basic block. */
if (!loop->pre_header)
{
rescan = true;
loop_split_edge_with (loop_preheader_edge (loop), NULL);
}
/* Make sure there exists a single-predecessor exit bb: */
if (EDGE_COUNT (loop->exit_edges[0]->dest->preds) != 1)
{
rescan = true;
loop_split_edge_with (loop->exit_edges[0], NULL);
}
if (rescan)
{
flow_loop_scan (loop, LOOP_ALL);
/* Flow loop scan does not update loop->single_exit field. */
loop->single_exit = loop->exit_edges[0];
}
if (empty_block_p (loop->header))
{
if (vect_debug_stats (loop) || vect_debug_details (loop))
......@@ -5546,32 +5505,23 @@ vect_analyze_loop_form (struct loop *loop)
return NULL;
}
if (chrec_contains_undetermined (number_of_iterations))
{
if (vect_debug_details (NULL))
fprintf (dump_file, "Infinite number of iterations.");
return false;
}
loop_vinfo = new_loop_vec_info (loop);
LOOP_VINFO_NITERS (loop_vinfo) = number_of_iterations;
if (!LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo))
{
if (vect_debug_stats (loop) || vect_debug_details (loop))
fprintf (dump_file, "loop bound unknown.");
/* Unknown loop bound. */
if (!vect_analyze_loop_with_symbolic_num_of_iters
(number_of_iterations, loop))
{
if (vect_debug_stats (loop) || vect_debug_details (loop))
fprintf (dump_file,
"not vectorized: can't determine loop bound.");
return NULL;
}
else
if (!LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo))
{
/* We need only one loop entry for unknown loop bound support. */
if (loop->num_entries != 1 || !loop->pre_header)
if (vect_debug_details (loop))
{
if (vect_debug_stats (loop) || vect_debug_details (loop))
fprintf (dump_file,
"not vectorized: more than one loop entry.");
return NULL;
}
fprintf (dump_file, "loop bound unknown.\n");
fprintf (dump_file, "Symbolic number of iterations is ");
print_generic_expr (dump_file, number_of_iterations, TDF_DETAILS);
}
}
else
......@@ -5739,6 +5689,10 @@ vectorize_loops (struct loops *loops)
return;
}
#ifdef ENABLE_CHECKING
verify_loop_closed_ssa ();
#endif
compute_immediate_uses (TDFA_USE_OPS, need_imm_uses_for);
/* ----------- Analyze loops. ----------- */
......@@ -5785,13 +5739,6 @@ vectorize_loops (struct loops *loops)
}
rewrite_into_ssa (false);
if (!bitmap_empty_p (vars_to_rename))
{
/* The rewrite of ssa names may cause violation of loop closed ssa
form invariants. TODO -- avoid these rewrites completely.
Information in virtual phi nodes is sufficient for it. */
rewrite_into_loop_closed_ssa ();
}
rewrite_into_loop_closed_ssa ();
rewrite_into_loop_closed_ssa (); /* FORNOW */
bitmap_clear (vars_to_rename);
}
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