aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-vectorizer.c
diff options
context:
space:
mode:
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;
}