Commit cd38ca7f by Dorit Nuzman Committed by Dorit Nuzman

tree-vectorizer.h (stmt_vec_info_type): Add enum value induc_vec_info_type.

        * tree-vectorizer.h (stmt_vec_info_type): Add enum value
        induc_vec_info_type.
        (vectorizable_induction): New function declaration.
        * tree-vect-transform.c (get_initial_def_for_induction): No need to
        check if already vectorized.  Find first place in BB where new stmts
        can be inserted.  Takes only one argument.
        (vectorizable_induction): New function.
        (vect_transform_stmt): Add case for induc_vec_info_type to call
        vectorizable_induction.
        (vect_transform_loop): Consider phis for vectorization.
        * tree-vect-analyze.c (vect_determine_vectorization_factor): Simplify
        condition.
        (analyze_operations): Call vectorizable_induction when analyzing phis.
        Fix comment.
        (vect_mark_stmts_to_be_vectorized): Remove redundant checks.
        (vect_mark_relevant): Include phis in relevance analysis.
        (vect_mark_stmts_to_be_vectorize): Likewise.
        * tree-vect-patterns.c (widened_name_p): Remove obsolete asserts.

From-SVN: r123910
parent 39ef6592
2007-04-17 Dorit Nuzman <dorit@il.ibm.com>
* tree-vectorizer.h (stmt_vec_info_type): Add enum value
induc_vec_info_type.
(vectorizable_induction): New function declaration.
* tree-vect-transform.c (get_initial_def_for_induction): No need to
check if already vectorized. Find first place in BB where new stmts
can be inserted. Takes only one argument.
(vectorizable_induction): New function.
(vect_transform_stmt): Add case for induc_vec_info_type to call
vectorizable_induction.
(vect_transform_loop): Consider phis for vectorization.
* tree-vect-analyze.c (vect_determine_vectorization_factor): Simplify
condition.
(analyze_operations): Call vectorizable_induction when analyzing phis.
Fix comment.
(vect_mark_stmts_to_be_vectorized): Remove redundant checks.
(vect_mark_relevant): Include phis in relevance analysis.
(vect_mark_stmts_to_be_vectorize): Likewise.
* tree-vect-patterns.c (widened_name_p): Remove obsolete asserts.
2007-04-16 Lawrence Crowl <crowl@google.com> 2007-04-16 Lawrence Crowl <crowl@google.com>
* doc/invoke.texi (Debugging Options): Add documentation for the * doc/invoke.texi (Debugging Options): Add documentation for the
......
2007-04-17 Dorit Nuzman <dorit@il.ibm.com>
* gcc.dg/vect/no-tree-scev-cprop-vect-iv-3.c: New test.
2007-04-16 Lawrence Crowl <crowl@google.com> 2007-04-16 Lawrence Crowl <crowl@google.com>
* g++.dg/other/fesd-any.C: Test -femit-struct-debug-detailed=any. * g++.dg/other/fesd-any.C: Test -femit-struct-debug-detailed=any.
/* { dg-do compile } */
/* { dg-require-effective-target vect_int } */
#include <stdarg.h>
#include "tree-vect.h"
#define N 26
unsigned int main1 ()
{
unsigned short i;
unsigned int intsum = 0;
/* vectorization of reduction with induction, and widenning sum:
sum shorts into int.
Need -fno-tree-scev-cprop or else the loop is eliminated. */
for (i = 0; i < N; i++)
{
intsum += i;
}
return intsum;
}
/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_widen_sum_hi_to_si } } } */
/* { dg-final { scan-tree-dump-times "vect_recog_widen_sum_pattern: detected" 1 "vect" { target vect_widen_sum_hi_to_si } } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
...@@ -122,13 +122,7 @@ vect_determine_vectorization_factor (loop_vec_info loop_vinfo) ...@@ -122,13 +122,7 @@ vect_determine_vectorization_factor (loop_vec_info loop_vinfo)
gcc_assert (stmt_info); gcc_assert (stmt_info);
/* Two cases of "relevant" phis: those that define an if (STMT_VINFO_RELEVANT_P (stmt_info))
induction that is used in the loop, and those that
define a reduction. */
if ((STMT_VINFO_RELEVANT (stmt_info) == vect_used_in_loop
&& STMT_VINFO_DEF_TYPE (stmt_info) == vect_induction_def)
|| (STMT_VINFO_RELEVANT (stmt_info) == vect_used_by_reduction
&& STMT_VINFO_DEF_TYPE (stmt_info) == vect_reduction_def))
{ {
gcc_assert (!STMT_VINFO_VECTYPE (stmt_info)); gcc_assert (!STMT_VINFO_VECTYPE (stmt_info));
scalar_type = TREE_TYPE (PHI_RESULT (phi)); scalar_type = TREE_TYPE (PHI_RESULT (phi));
...@@ -311,6 +305,8 @@ vect_analyze_operations (loop_vec_info loop_vinfo) ...@@ -311,6 +305,8 @@ vect_analyze_operations (loop_vec_info loop_vinfo)
for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi)) for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
{ {
ok = true;
stmt_info = vinfo_for_stmt (phi); stmt_info = vinfo_for_stmt (phi);
if (vect_print_dump_info (REPORT_DETAILS)) if (vect_print_dump_info (REPORT_DETAILS))
{ {
...@@ -331,15 +327,29 @@ vect_analyze_operations (loop_vec_info loop_vinfo) ...@@ -331,15 +327,29 @@ vect_analyze_operations (loop_vec_info loop_vinfo)
if (STMT_VINFO_RELEVANT (stmt_info) == vect_used_in_loop if (STMT_VINFO_RELEVANT (stmt_info) == vect_used_in_loop
&& STMT_VINFO_DEF_TYPE (stmt_info) != vect_induction_def) && STMT_VINFO_DEF_TYPE (stmt_info) != vect_induction_def)
{ {
/* Most likely a reduction-like computation that is used /* A scalar-dependence cycle that we don't support. */
in the loop. */
if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS)) if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
fprintf (vect_dump, "not vectorized: unsupported pattern."); fprintf (vect_dump, "not vectorized: scalar dependence cycle.");
return false; return false;
} }
if (STMT_VINFO_RELEVANT_P (stmt_info)) if (STMT_VINFO_RELEVANT_P (stmt_info))
need_to_vectorize = true; {
need_to_vectorize = true;
if (STMT_VINFO_DEF_TYPE (stmt_info) == vect_induction_def)
ok = vectorizable_induction (phi, NULL, NULL);
}
if (!ok)
{
if (vect_print_dump_info (REPORT_UNVECTORIZED_LOOPS))
{
fprintf (vect_dump,
"not vectorized: relevant phi not supported: ");
print_generic_expr (vect_dump, phi, TDF_SLIM);
}
return false;
}
} }
for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si)) for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
...@@ -2106,11 +2116,6 @@ vect_mark_relevant (VEC(tree,heap) **worklist, tree stmt, ...@@ -2106,11 +2116,6 @@ vect_mark_relevant (VEC(tree,heap) **worklist, tree stmt,
if (relevant > STMT_VINFO_RELEVANT (stmt_info)) if (relevant > STMT_VINFO_RELEVANT (stmt_info))
STMT_VINFO_RELEVANT (stmt_info) = relevant; STMT_VINFO_RELEVANT (stmt_info) = relevant;
if (TREE_CODE (stmt) == PHI_NODE)
/* Don't put phi-nodes in the worklist. Phis that are marked relevant
or live will fail vectorization later on. */
return;
if (STMT_VINFO_RELEVANT (stmt_info) == save_relevant if (STMT_VINFO_RELEVANT (stmt_info) == save_relevant
&& STMT_VINFO_LIVE_P (stmt_info) == save_live_p) && STMT_VINFO_LIVE_P (stmt_info) == save_live_p)
{ {
...@@ -2228,27 +2233,23 @@ vect_mark_stmts_to_be_vectorized (loop_vec_info loop_vinfo) ...@@ -2228,27 +2233,23 @@ vect_mark_stmts_to_be_vectorized (loop_vec_info loop_vinfo)
worklist = VEC_alloc (tree, heap, 64); worklist = VEC_alloc (tree, heap, 64);
/* 1. Init worklist. */ /* 1. Init worklist. */
bb = loop->header;
for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
{
if (vect_print_dump_info (REPORT_DETAILS))
{
fprintf (vect_dump, "init: phi relevant? ");
print_generic_expr (vect_dump, phi, TDF_SLIM);
}
if (vect_stmt_relevant_p (phi, loop_vinfo, &relevant, &live_p))
vect_mark_relevant (&worklist, phi, relevant, live_p);
}
for (i = 0; i < nbbs; i++) for (i = 0; i < nbbs; i++)
{ {
bb = bbs[i]; bb = bbs[i];
for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
{
if (vect_print_dump_info (REPORT_DETAILS))
{
fprintf (vect_dump, "init: phi relevant? ");
print_generic_expr (vect_dump, phi, TDF_SLIM);
}
if (vect_stmt_relevant_p (phi, loop_vinfo, &relevant, &live_p))
vect_mark_relevant (&worklist, phi, relevant, live_p);
}
for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si)) for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
{ {
stmt = bsi_stmt (si); stmt = bsi_stmt (si);
if (vect_print_dump_info (REPORT_DETAILS)) if (vect_print_dump_info (REPORT_DETAILS))
{ {
fprintf (vect_dump, "init: stmt relevant? "); fprintf (vect_dump, "init: stmt relevant? ");
...@@ -2279,8 +2280,6 @@ vect_mark_stmts_to_be_vectorized (loop_vec_info loop_vinfo) ...@@ -2279,8 +2280,6 @@ vect_mark_stmts_to_be_vectorized (loop_vec_info loop_vinfo)
relevance properties of STMT. relevance properties of STMT.
*/ */
gcc_assert (TREE_CODE (stmt) != PHI_NODE);
ann = stmt_ann (stmt); ann = stmt_ann (stmt);
stmt_vinfo = vinfo_for_stmt (stmt); stmt_vinfo = vinfo_for_stmt (stmt);
...@@ -2318,7 +2317,6 @@ vect_mark_stmts_to_be_vectorized (loop_vec_info loop_vinfo) ...@@ -2318,7 +2317,6 @@ vect_mark_stmts_to_be_vectorized (loop_vec_info loop_vinfo)
/* case 2.2: */ /* case 2.2: */
if (STMT_VINFO_DEF_TYPE (stmt_vinfo) == vect_reduction_def) if (STMT_VINFO_DEF_TYPE (stmt_vinfo) == vect_reduction_def)
{ {
gcc_assert (relevant == vect_unused_in_loop && live_p);
relevant = vect_used_by_reduction; relevant = vect_used_by_reduction;
live_p = false; live_p = false;
} }
......
...@@ -109,10 +109,6 @@ widened_name_p (tree name, tree use_stmt, tree *half_type, tree *def_stmt) ...@@ -109,10 +109,6 @@ widened_name_p (tree name, tree use_stmt, tree *half_type, tree *def_stmt)
if (!vect_is_simple_use (oprnd0, loop_vinfo, &dummy, &dummy, &dt)) if (!vect_is_simple_use (oprnd0, loop_vinfo, &dummy, &dummy, &dt))
return false; return false;
if (dt != vect_invariant_def && dt != vect_constant_def
&& dt != vect_loop_def)
return false;
return true; return true;
} }
......
...@@ -514,7 +514,6 @@ vect_init_vector (tree stmt, tree vector_var, tree vector_type) ...@@ -514,7 +514,6 @@ vect_init_vector (tree stmt, tree vector_var, tree vector_type)
/* Function get_initial_def_for_induction /* Function get_initial_def_for_induction
Input: Input:
STMT - a stmt that performs an induction operation in the loop.
IV_PHI - the initial value of the induction variable IV_PHI - the initial value of the induction variable
Output: Output:
...@@ -524,9 +523,9 @@ vect_init_vector (tree stmt, tree vector_var, tree vector_type) ...@@ -524,9 +523,9 @@ vect_init_vector (tree stmt, tree vector_var, tree vector_type)
[X, X + S, X + 2*S, X + 3*S]. */ [X, X + S, X + 2*S, X + 3*S]. */
static tree static tree
get_initial_def_for_induction (tree stmt, tree iv_phi) get_initial_def_for_induction (tree iv_phi)
{ {
stmt_vec_info stmt_vinfo = vinfo_for_stmt (stmt); stmt_vec_info stmt_vinfo = vinfo_for_stmt (iv_phi);
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_vinfo); loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_vinfo);
struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo); struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
tree scalar_type = TREE_TYPE (iv_phi); tree scalar_type = TREE_TYPE (iv_phi);
...@@ -549,27 +548,17 @@ get_initial_def_for_induction (tree stmt, tree iv_phi) ...@@ -549,27 +548,17 @@ get_initial_def_for_induction (tree stmt, tree iv_phi)
tree expr; tree expr;
stmt_vec_info phi_info = vinfo_for_stmt (iv_phi); stmt_vec_info phi_info = vinfo_for_stmt (iv_phi);
tree stmts; tree stmts;
tree stmt = NULL_TREE;
block_stmt_iterator si;
basic_block bb = bb_for_stmt (iv_phi);
gcc_assert (phi_info); gcc_assert (phi_info);
gcc_assert (ncopies >= 1);
if (STMT_VINFO_VEC_STMT (phi_info)) /* Find the first insertion point in the BB. */
{ si = bsi_after_labels (bb);
induction_phi = STMT_VINFO_VEC_STMT (phi_info); stmt = bsi_stmt (si);
gcc_assert (TREE_CODE (induction_phi) == PHI_NODE);
if (vect_print_dump_info (REPORT_DETAILS))
{
fprintf (vect_dump, "induction already vectorized:");
print_generic_expr (vect_dump, iv_phi, TDF_SLIM);
fprintf (vect_dump, "\n");
print_generic_expr (vect_dump, induction_phi, TDF_SLIM);
}
return PHI_RESULT (induction_phi);
}
gcc_assert (ncopies >= 1);
access_fn = analyze_scalar_evolution (loop, PHI_RESULT (iv_phi)); access_fn = analyze_scalar_evolution (loop, PHI_RESULT (iv_phi));
gcc_assert (access_fn); gcc_assert (access_fn);
ok = vect_is_simple_iv_evolution (loop->num, access_fn, &init_expr, &step_expr); ok = vect_is_simple_iv_evolution (loop->num, access_fn, &init_expr, &step_expr);
...@@ -833,7 +822,7 @@ vect_get_vec_def_for_operand (tree op, tree stmt, tree *scalar_def) ...@@ -833,7 +822,7 @@ vect_get_vec_def_for_operand (tree op, tree stmt, tree *scalar_def)
gcc_assert (TREE_CODE (def_stmt) == PHI_NODE); gcc_assert (TREE_CODE (def_stmt) == PHI_NODE);
/* Get the def before the loop */ /* Get the def before the loop */
return get_initial_def_for_induction (stmt, def_stmt); return get_initial_def_for_induction (def_stmt);
} }
default: default:
...@@ -2233,6 +2222,59 @@ vect_min_worthwhile_factor (enum tree_code code) ...@@ -2233,6 +2222,59 @@ vect_min_worthwhile_factor (enum tree_code code)
} }
/* Function vectorizable_induction
Check if PHI performs an induction computation that can be vectorized.
If VEC_STMT is also passed, vectorize the induction PHI: create a vectorized
phi to replace it, put it in VEC_STMT, and add it to the same basic block.
Return FALSE if not a vectorizable STMT, TRUE otherwise. */
bool
vectorizable_induction (tree phi, block_stmt_iterator *bsi ATTRIBUTE_UNUSED,
tree *vec_stmt)
{
stmt_vec_info stmt_info = vinfo_for_stmt (phi);
tree vectype = STMT_VINFO_VECTYPE (stmt_info);
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
int nunits = TYPE_VECTOR_SUBPARTS (vectype);
int ncopies = LOOP_VINFO_VECT_FACTOR (loop_vinfo) / nunits;
tree vec_def;
gcc_assert (ncopies >= 1);
if (!STMT_VINFO_RELEVANT_P (stmt_info))
return false;
gcc_assert (STMT_VINFO_DEF_TYPE (stmt_info) == vect_induction_def);
if (STMT_VINFO_LIVE_P (stmt_info))
{
/* FORNOW: not yet supported. */
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "value used after loop.");
return false;
}
if (TREE_CODE (phi) != PHI_NODE)
return false;
if (!vec_stmt) /* transformation not required. */
{
STMT_VINFO_TYPE (stmt_info) = induc_vec_info_type;
return true;
}
/** Transform. **/
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "transform induction phi.");
vec_def = get_initial_def_for_induction (phi);
*vec_stmt = SSA_NAME_DEF_STMT (vec_def);
return true;
}
/* Function vectorizable_operation. /* Function vectorizable_operation.
Check if STMT performs a binary or unary operation that can be vectorized. Check if STMT performs a binary or unary operation that can be vectorized.
...@@ -4285,6 +4327,11 @@ vect_transform_stmt (tree stmt, block_stmt_iterator *bsi, bool *strided_store) ...@@ -4285,6 +4327,11 @@ vect_transform_stmt (tree stmt, block_stmt_iterator *bsi, bool *strided_store)
gcc_assert (done); gcc_assert (done);
break; break;
case induc_vec_info_type:
done = vectorizable_induction (stmt, bsi, &vec_stmt);
gcc_assert (done);
break;
case op_vec_info_type: case op_vec_info_type:
done = vectorizable_operation (stmt, bsi, &vec_stmt); done = vectorizable_operation (stmt, bsi, &vec_stmt);
gcc_assert (done); gcc_assert (done);
...@@ -5192,11 +5239,39 @@ vect_transform_loop (loop_vec_info loop_vinfo) ...@@ -5192,11 +5239,39 @@ vect_transform_loop (loop_vec_info loop_vinfo)
for (i = 0; i < nbbs; i++) for (i = 0; i < nbbs; i++)
{ {
basic_block bb = bbs[i]; basic_block bb = bbs[i];
stmt_vec_info stmt_info;
tree phi;
for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
{
if (vect_print_dump_info (REPORT_DETAILS))
{
fprintf (vect_dump, "------>vectorizing phi: ");
print_generic_expr (vect_dump, phi, TDF_SLIM);
}
stmt_info = vinfo_for_stmt (phi);
if (!stmt_info)
continue;
if (!STMT_VINFO_RELEVANT_P (stmt_info)
&& !STMT_VINFO_LIVE_P (stmt_info))
continue;
if ((TYPE_VECTOR_SUBPARTS (STMT_VINFO_VECTYPE (stmt_info))
!= (unsigned HOST_WIDE_INT) vectorization_factor)
&& vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "multiple-types.");
if (STMT_VINFO_DEF_TYPE (stmt_info) == vect_induction_def)
{
if (vect_print_dump_info (REPORT_DETAILS))
fprintf (vect_dump, "transform phi.");
vect_transform_stmt (phi, NULL, NULL);
}
}
for (si = bsi_start (bb); !bsi_end_p (si);) for (si = bsi_start (bb); !bsi_end_p (si);)
{ {
tree stmt = bsi_stmt (si); tree stmt = bsi_stmt (si);
stmt_vec_info stmt_info;
bool is_store; bool is_store;
if (vect_print_dump_info (REPORT_DETAILS)) if (vect_print_dump_info (REPORT_DETAILS))
......
...@@ -167,6 +167,7 @@ enum stmt_vec_info_type { ...@@ -167,6 +167,7 @@ enum stmt_vec_info_type {
assignment_vec_info_type, assignment_vec_info_type,
condition_vec_info_type, condition_vec_info_type,
reduc_vec_info_type, reduc_vec_info_type,
induc_vec_info_type,
type_promotion_vec_info_type, type_promotion_vec_info_type,
type_demotion_vec_info_type, type_demotion_vec_info_type,
type_conversion_vec_info_type type_conversion_vec_info_type
...@@ -428,6 +429,7 @@ extern bool vectorizable_call (tree, block_stmt_iterator *, tree *); ...@@ -428,6 +429,7 @@ extern bool vectorizable_call (tree, block_stmt_iterator *, tree *);
extern bool vectorizable_condition (tree, block_stmt_iterator *, tree *); extern bool vectorizable_condition (tree, block_stmt_iterator *, tree *);
extern bool vectorizable_live_operation (tree, block_stmt_iterator *, tree *); extern bool vectorizable_live_operation (tree, block_stmt_iterator *, tree *);
extern bool vectorizable_reduction (tree, block_stmt_iterator *, tree *); extern bool vectorizable_reduction (tree, block_stmt_iterator *, tree *);
extern bool vectorizable_induction (tree, block_stmt_iterator *, tree *);
/* Driver for transformation stage. */ /* Driver for transformation stage. */
extern void vect_transform_loop (loop_vec_info); extern void vect_transform_loop (loop_vec_info);
......
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