aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-vectorizer.c
diff options
context:
space:
mode:
authorDorit Nuzman <dorit@il.ibm.com>2005-06-05 09:54:20 +0000
committerDorit Nuzman <dorit@gcc.gnu.org>2005-06-05 09:54:20 +0000
commit88088c03967bc1ccf78ee8ddd9c0612f565df20a (patch)
tree26cd50c3f350a2ee9a8127ba71ee3f88ea837a07 /gcc/tree-vectorizer.c
parent57049d399a8eff8cd573a9f162467cb3aaeeee35 (diff)
downloadgcc-88088c03967bc1ccf78ee8ddd9c0612f565df20a.zip
gcc-88088c03967bc1ccf78ee8ddd9c0612f565df20a.tar.gz
gcc-88088c03967bc1ccf78ee8ddd9c0612f565df20a.tar.bz2
tree-flow.h (stmt_ann_d): Move aux to ...
* tree-flow.h (stmt_ann_d): Move aux to ... (tree_ann_common_d): ... here. * tree-ssa-loop-im.c (LIM_DATA, determine_invariantness_stmt, move_computations_stmt, schedule_sm): Update references to aux. * tree-vectorizer.h (set_stmt_info, vinfo_for_stmt): Likewise. * tree-vect-transform.c (vect_create_index_for_vector_ref): Update call to set_stmt_info. (vect_transform_loop): Likewise. * tree-vectorizer.c (new_loop_vec_info, destroy_loop_vec_info): Likewise. * tree-vect-analyze.c (vect_analyze_scalar_cycles): Made void instead of bool. (vect_mark_relevant): Takes two additional arguments - live_p and relevant_p. Set RELEVANT_P and LIVE_P according to these arguments. (vect_stmt_relevant_p): Differentiate between a live stmt and a relevant stmt. Return two values = live_p and relevant_p. (vect_mark_stmts_to_be_vectorized): Call vect_mark_relevant and vect_stmt_relevant_p with additional arguments. Phis are no longer put into the worklist (analyzed seperately in analyze_scalar_cycles). (vect_determine_vectorization_factor): Also check for LIVE_P, because a stmt that is marked as irrelevant and live, cause it's only used out side the loop, may need to be vectorized (e.g. reduction). (vect_analyze_operations): Examine phis. Call vectorizable_live_operation for for LIVE_P stmts. Check if need_to_vectorize. (vect_analyze_scalar_cycles): Update documentation. Don't fail vectorization - just classify the scalar cycles created by the loop phis. Call vect_is_simple_reduction. (vect_analyze_loop): Call to analyze_scalar_cycles moved earlier. * tree-vect-transform.c (vect_create_index_for_vector_ref): Update call to set_stmt_info. (vect_get_vec_def_for_operand): Code reorganized - the code that classifies the type of use was factored out to vect_is_simple_use. (vectorizable_store, vect_is_simple_cond): Call vect_is_simple_use with additional arguments. (vectorizable_assignment): Likewise. Also make sure the stmt is relevant and computes a loop_vec_def. (vectorizable_operation, vectorizable_load, vectorizable_condition): Likewise. (vectorizable_live_operation): New. (vect_transform_stmt): Handle LIVE_P stmts. * tree-vectorizer.c (new_stmt_vec_info): Initialize the new fields STMT_VINFO_LIVE_P and STMT_VINFO_DEF_TYPE. (new_loop_vec_info, destroy_loop_vec_info): Also handle phis. (vect_is_simple_use): Determine the type of the def and return it in a new function argument. Consider vect_reduction_def and vect_induction_def, but for now these are not supported. (vect_is_simple_reduction): New. Empty for now. * tree-vectorizer.h (vect_def_type): New enum type. (_stmt_vec_info): Added new fields - live and _stmt_vec_info. (STMT_VINFO_LIVE_P, STMT_VINFO_DEF_TYPE): New accessor macros. (vect_is_simple_use): New arguments added to function declaration. (vect_is_simple_reduction): New function declaration. (vectorizable_live_operation): New function declaration. * tree-vect-analyze.c (vect_can_advance_ivs_p): Add debug printout. (vect_can_advance_ivs_p): Likewise. * tree-vect-transform.c (vect_update_ivs_after_vectorizer): Likewise. From-SVN: r100617
Diffstat (limited to 'gcc/tree-vectorizer.c')
-rw-r--r--gcc/tree-vectorizer.c178
1 files changed, 144 insertions, 34 deletions
diff --git a/gcc/tree-vectorizer.c b/gcc/tree-vectorizer.c
index 883f403..53f5358 100644
--- a/gcc/tree-vectorizer.c
+++ b/gcc/tree-vectorizer.c
@@ -1338,9 +1338,14 @@ new_stmt_vec_info (tree stmt, loop_vec_info loop_vinfo)
STMT_VINFO_STMT (res) = stmt;
STMT_VINFO_LOOP_VINFO (res) = loop_vinfo;
STMT_VINFO_RELEVANT_P (res) = 0;
+ STMT_VINFO_LIVE_P (res) = 0;
STMT_VINFO_VECTYPE (res) = NULL;
STMT_VINFO_VEC_STMT (res) = NULL;
STMT_VINFO_DATA_REF (res) = NULL;
+ if (TREE_CODE (stmt) == PHI_NODE)
+ STMT_VINFO_DEF_TYPE (res) = vect_unknown_def_type;
+ else
+ STMT_VINFO_DEF_TYPE (res) = vect_loop_def;
STMT_VINFO_MEMTAG (res) = NULL;
STMT_VINFO_PTR_INFO (res) = NULL;
STMT_VINFO_SUBVARS (res) = NULL;
@@ -1375,13 +1380,21 @@ new_loop_vec_info (struct loop *loop)
for (i = 0; i < loop->num_nodes; i++)
{
basic_block bb = bbs[i];
+ tree phi;
+
+ for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
+ {
+ tree_ann_t ann = get_tree_ann (phi);
+ set_stmt_info (ann, new_stmt_vec_info (phi, res));
+ }
+
for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
{
tree stmt = bsi_stmt (si);
stmt_ann_t ann;
ann = stmt_ann (stmt);
- set_stmt_info (ann, new_stmt_vec_info (stmt, res));
+ set_stmt_info ((tree_ann_t)ann, new_stmt_vec_info (stmt, res));
}
}
@@ -1428,13 +1441,26 @@ destroy_loop_vec_info (loop_vec_info loop_vinfo)
for (j = 0; j < nbbs; j++)
{
basic_block bb = bbs[j];
+ tree phi;
+ stmt_vec_info stmt_info;
+
+ for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
+ {
+ tree_ann_t ann = get_tree_ann (phi);
+
+ stmt_info = vinfo_for_stmt (phi);
+ free (stmt_info);
+ set_stmt_info (ann, NULL);
+ }
+
for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
{
tree stmt = bsi_stmt (si);
stmt_ann_t ann = stmt_ann (stmt);
+
stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
free (stmt_info);
- set_stmt_info (ann, NULL);
+ set_stmt_info ((tree_ann_t)ann, NULL);
}
}
@@ -1596,64 +1622,148 @@ vect_supportable_dr_alignment (struct data_reference *dr)
in reduction/induction computations). */
bool
-vect_is_simple_use (tree operand, loop_vec_info loop_vinfo, tree *def)
+vect_is_simple_use (tree operand, loop_vec_info loop_vinfo, tree *def_stmt,
+ tree *def, enum vect_def_type *dt)
{
- tree def_stmt;
basic_block bb;
+ stmt_vec_info stmt_vinfo;
struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
- if (def)
- *def = NULL_TREE;
-
+ *def_stmt = NULL_TREE;
+ *def = NULL_TREE;
+
+ if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
+ {
+ fprintf (vect_dump, "vect_is_simple_use: operand ");
+ print_generic_expr (vect_dump, operand, TDF_SLIM);
+ }
+
if (TREE_CODE (operand) == INTEGER_CST || TREE_CODE (operand) == REAL_CST)
- return true;
-
+ {
+ *dt = vect_constant_def;
+ return true;
+ }
+
if (TREE_CODE (operand) != SSA_NAME)
- return false;
-
- def_stmt = SSA_NAME_DEF_STMT (operand);
- if (def_stmt == NULL_TREE )
+ {
+ if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
+ fprintf (vect_dump, "not ssa-name.");
+ return false;
+ }
+
+ *def_stmt = SSA_NAME_DEF_STMT (operand);
+ if (*def_stmt == NULL_TREE )
{
if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
fprintf (vect_dump, "no def_stmt.");
return false;
}
+ if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
+ {
+ fprintf (vect_dump, "def_stmt: ");
+ print_generic_expr (vect_dump, *def_stmt, TDF_SLIM);
+ }
+
/* empty stmt is expected only in case of a function argument.
(Otherwise - we expect a phi_node or a modify_expr). */
- if (IS_EMPTY_STMT (def_stmt))
+ if (IS_EMPTY_STMT (*def_stmt))
{
- tree arg = TREE_OPERAND (def_stmt, 0);
+ tree arg = TREE_OPERAND (*def_stmt, 0);
if (TREE_CODE (arg) == INTEGER_CST || TREE_CODE (arg) == REAL_CST)
- return true;
+ {
+ *def = operand;
+ *dt = vect_invariant_def;
+ return true;
+ }
+
if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
- {
- fprintf (vect_dump, "Unexpected empty stmt: ");
- print_generic_expr (vect_dump, def_stmt, TDF_SLIM);
- }
- return false;
+ fprintf (vect_dump, "Unexpected empty stmt.");
+ return false;
}
- /* phi_node inside the loop indicates an induction/reduction pattern.
- This is not supported yet. */
- bb = bb_for_stmt (def_stmt);
- if (TREE_CODE (def_stmt) == PHI_NODE && flow_bb_inside_loop_p (loop, bb))
+ bb = bb_for_stmt (*def_stmt);
+ if (!flow_bb_inside_loop_p (loop, bb))
+ *dt = vect_invariant_def;
+ else
+ {
+ stmt_vinfo = vinfo_for_stmt (*def_stmt);
+ *dt = STMT_VINFO_DEF_TYPE (stmt_vinfo);
+ }
+
+ if (*dt == vect_unknown_def_type)
{
if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
- fprintf (vect_dump, "reduction/induction - unsupported.");
- return false; /* FORNOW: not supported yet. */
+ fprintf (vect_dump, "Unsupported pattern.");
+ return false;
}
- /* Expecting a modify_expr or a phi_node. */
- if (TREE_CODE (def_stmt) == MODIFY_EXPR
- || TREE_CODE (def_stmt) == PHI_NODE)
+ /* stmts inside the loop that have been identified as performing
+ a reduction operation cannot have uses in the loop. */
+ if (*dt == vect_reduction_def && TREE_CODE (*def_stmt) != PHI_NODE)
{
- if (def)
- *def = def_stmt;
- return true;
+ if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
+ fprintf (vect_dump, "reduction used in loop.");
+ return false;
+ }
+
+ if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
+ fprintf (vect_dump, "type of def: %d.",*dt);
+
+ switch (TREE_CODE (*def_stmt))
+ {
+ case PHI_NODE:
+ *def = PHI_RESULT (*def_stmt);
+ gcc_assert (*dt == vect_induction_def || *dt == vect_reduction_def
+ || *dt == vect_invariant_def);
+ break;
+
+ case MODIFY_EXPR:
+ *def = TREE_OPERAND (*def_stmt, 0);
+ gcc_assert (*dt == vect_loop_def || *dt == vect_invariant_def);
+ break;
+
+ default:
+ if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
+ fprintf (vect_dump, "unsupported defining stmt: ");
+ return false;
}
- return false;
+ if (*dt == vect_induction_def)
+ {
+ if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
+ fprintf (vect_dump, "induction not supported.");
+ return false;
+ }
+
+ return true;
+}
+
+
+/* Function vect_is_simple_reduction
+
+ TODO:
+ Detect a cross-iteration def-use cucle that represents a simple
+ reduction computation. We look for the followng pattern:
+
+ loop_header:
+ a1 = phi < a0, a2 >
+ a3 = ...
+ a2 = operation (a3, a1)
+
+ such that:
+ 1. operation is...
+ 2. no uses for a2 in the loop (elsewhere) */
+
+tree
+vect_is_simple_reduction (struct loop *loop ATTRIBUTE_UNUSED,
+ tree phi ATTRIBUTE_UNUSED)
+{
+ /* FORNOW */
+ if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
+ fprintf (vect_dump, "reduction: unknown pattern.");
+
+ return NULL_TREE;
}