static bool
vect_analyze_slp_instance (vec_info *vinfo,
scalar_stmts_to_slp_tree_map_t *bst_map,
- stmt_vec_info stmt_info, unsigned max_tree_size);
+ stmt_vec_info stmt_info, slp_instance_kind kind,
+ unsigned max_tree_size);
/* Analyze an SLP instance starting from SCALAR_STMTS which are a group
of KIND. Return true if successful. */
stmt_vec_info rest = vect_split_slp_store_group (stmt_info,
group1_size);
bool res = vect_analyze_slp_instance (vinfo, bst_map, stmt_info,
- max_tree_size);
+ kind, max_tree_size);
/* Split the rest at the failure point and possibly
re-analyze the remaining matching part if it has
at least two lanes. */
stmt_vec_info rest2 = rest;
rest = vect_split_slp_store_group (rest, i - group1_size);
if (i - group1_size > 1)
- res |= vect_analyze_slp_instance (vinfo, bst_map,
- rest2, max_tree_size);
+ res |= vect_analyze_slp_instance (vinfo, bst_map, rest2,
+ kind, max_tree_size);
}
/* Re-analyze the non-matching tail if it has at least
two lanes. */
if (i + 1 < group_size)
res |= vect_analyze_slp_instance (vinfo, bst_map,
- rest, max_tree_size);
+ rest, kind, max_tree_size);
return res;
}
}
DR_GROUP_GAP (stmt_info) = 0;
bool res = vect_analyze_slp_instance (vinfo, bst_map, stmt_info,
- max_tree_size);
+ kind, max_tree_size);
if (i + 1 < group_size)
res |= vect_analyze_slp_instance (vinfo, bst_map,
- rest, max_tree_size);
+ rest, kind, max_tree_size);
return res;
}
static bool
vect_analyze_slp_instance (vec_info *vinfo,
scalar_stmts_to_slp_tree_map_t *bst_map,
- stmt_vec_info stmt_info, unsigned max_tree_size)
+ stmt_vec_info stmt_info,
+ slp_instance_kind kind,
+ unsigned max_tree_size)
{
- unsigned int group_size;
unsigned int i;
- struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info);
vec<stmt_vec_info> scalar_stmts;
- slp_instance_kind kind;
if (is_a <bb_vec_info> (vinfo))
vect_location = stmt_info->stmt;
- if (STMT_VINFO_GROUPED_ACCESS (stmt_info))
- {
- kind = slp_inst_kind_store;
- group_size = DR_GROUP_SIZE (stmt_info);
- }
- else if (!dr && REDUC_GROUP_FIRST_ELEMENT (stmt_info))
- {
- kind = slp_inst_kind_reduc_chain;
- gcc_assert (is_a <loop_vec_info> (vinfo));
- group_size = REDUC_GROUP_SIZE (stmt_info);
- }
- else if (is_gimple_assign (stmt_info->stmt)
- && gimple_assign_rhs_code (stmt_info->stmt) == CONSTRUCTOR)
- {
- kind = slp_inst_kind_ctor;
- group_size = CONSTRUCTOR_NELTS (gimple_assign_rhs1 (stmt_info->stmt));
- }
- else
- {
- kind = slp_inst_kind_reduc_group;
- gcc_assert (is_a <loop_vec_info> (vinfo));
- group_size = as_a <loop_vec_info> (vinfo)->reductions.length ();
- }
- /* Create a node (a root of the SLP tree) for the packed grouped stores. */
- scalar_stmts.create (group_size);
stmt_vec_info next_info = stmt_info;
- if (STMT_VINFO_GROUPED_ACCESS (stmt_info))
+ if (kind == slp_inst_kind_store)
{
- /* Collect the stores and store them in SLP_TREE_SCALAR_STMTS. */
+ /* Collect the stores and store them in scalar_stmts. */
+ scalar_stmts.create (DR_GROUP_SIZE (stmt_info));
while (next_info)
{
- scalar_stmts.safe_push (vect_stmt_to_vectorize (next_info));
+ scalar_stmts.quick_push (vect_stmt_to_vectorize (next_info));
next_info = DR_GROUP_NEXT_ELEMENT (next_info);
}
}
- else if (!dr && REDUC_GROUP_FIRST_ELEMENT (stmt_info))
+ else if (kind == slp_inst_kind_reduc_chain)
{
- /* Collect the reduction stmts and store them in
- SLP_TREE_SCALAR_STMTS. */
+ /* Collect the reduction stmts and store them in scalar_stmts. */
+ scalar_stmts.create (REDUC_GROUP_SIZE (stmt_info));
while (next_info)
{
- scalar_stmts.safe_push (vect_stmt_to_vectorize (next_info));
+ scalar_stmts.quick_push (vect_stmt_to_vectorize (next_info));
next_info = REDUC_GROUP_NEXT_ELEMENT (next_info);
}
/* Mark the first element of the reduction chain as reduction to properly
{
tree rhs = gimple_assign_rhs1 (stmt_info->stmt);
tree val;
+ scalar_stmts.create (CONSTRUCTOR_NELTS (rhs));
FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (rhs), i, val)
{
- if (TREE_CODE (val) == SSA_NAME)
- {
- gimple* def = SSA_NAME_DEF_STMT (val);
- stmt_vec_info def_info = vinfo->lookup_stmt (def);
- /* Value is defined in another basic block. */
- if (!def_info)
- return false;
- def_info = vect_stmt_to_vectorize (def_info);
- scalar_stmts.safe_push (def_info);
- }
- else
- return false;
+ stmt_vec_info def_info = vinfo->lookup_def (val);
+ def_info = vect_stmt_to_vectorize (def_info);
+ scalar_stmts.quick_push (def_info);
}
if (dump_enabled_p ())
dump_printf_loc (MSG_NOTE, vect_location,
"Analyzing vectorizable constructor: %G\n",
stmt_info->stmt);
}
- else
+ else if (kind == slp_inst_kind_reduc_group)
{
/* Collect reduction statements. */
vec<stmt_vec_info> reductions = as_a <loop_vec_info> (vinfo)->reductions;
+ scalar_stmts.create (reductions.length ());
for (i = 0; reductions.iterate (i, &next_info); i++)
if (STMT_VINFO_RELEVANT_P (next_info)
|| STMT_VINFO_LIVE_P (next_info))
if (scalar_stmts.length () < 2)
return false;
}
+ else
+ gcc_unreachable ();
/* Build the tree for the SLP instance. */
bool res = vect_build_slp_instance (vinfo, kind, scalar_stmts,
kind == slp_inst_kind_ctor
? stmt_info : NULL,
- max_tree_size,
- bst_map, stmt_info);
+ max_tree_size, bst_map,
+ kind == slp_inst_kind_store
+ ? stmt_info : NULL);
/* ??? If this is slp_inst_kind_store and the above succeeded here's
where we should do store group splitting. */
/* Find SLP sequences starting from groups of grouped stores. */
FOR_EACH_VEC_ELT (vinfo->grouped_stores, i, first_element)
- vect_analyze_slp_instance (vinfo, bst_map, first_element, max_tree_size);
+ vect_analyze_slp_instance (vinfo, bst_map, first_element,
+ STMT_VINFO_GROUPED_ACCESS (first_element)
+ ? slp_inst_kind_store : slp_inst_kind_ctor,
+ max_tree_size);
if (loop_vec_info loop_vinfo = dyn_cast <loop_vec_info> (vinfo))
{
&& ! STMT_VINFO_LIVE_P (first_element))
;
else if (! vect_analyze_slp_instance (vinfo, bst_map, first_element,
+ slp_inst_kind_reduc_chain,
max_tree_size))
{
/* Dissolve reduction chain group. */
/* Find SLP sequences starting from groups of reductions. */
if (loop_vinfo->reductions.length () > 1)
vect_analyze_slp_instance (vinfo, bst_map, loop_vinfo->reductions[0],
- max_tree_size);
+ slp_inst_kind_reduc_group, max_tree_size);
}
/* The map keeps a reference on SLP nodes built, release that. */
|| uniform_vector_p (rhs))
continue;
+ unsigned j;
+ tree val;
+ FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (rhs), j, val)
+ if (TREE_CODE (val) != SSA_NAME
+ || !bb_vinfo->lookup_def (val))
+ break;
+ if (j != CONSTRUCTOR_NELTS (rhs))
+ continue;
+
stmt_vec_info stmt_info = bb_vinfo->lookup_stmt (assign);
BB_VINFO_GROUPED_STORES (bb_vinfo).safe_push (stmt_info);
}