refactor SLP analysis
This passes down the graph entry kind down to vect_analyze_slp_instance which simplifies it and makes it a shallow wrapper around vect_build_slp_instance. 2020-11-06 Richard Biener <rguenther@suse.de> * tree-vect-slp.c (vect_analyze_slp): Pass down the SLP graph entry kind. (vect_analyze_slp_instance): Simplify. (vect_build_slp_instance): Adjust. (vect_slp_check_for_constructors): Perform more eligibility checks here.
This commit is contained in:
parent
7144270e2d
commit
b88fdcc1c3
1 changed files with 45 additions and 60 deletions
|
@ -2174,7 +2174,8 @@ calculate_unrolling_factor (poly_uint64 nunits, unsigned int group_size)
|
|||
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. */
|
||||
|
@ -2375,7 +2376,7 @@ vect_build_slp_instance (vec_info *vinfo,
|
|||
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. */
|
||||
|
@ -2386,14 +2387,14 @@ vect_build_slp_instance (vec_info *vinfo,
|
|||
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;
|
||||
}
|
||||
}
|
||||
|
@ -2418,10 +2419,10 @@ vect_build_slp_instance (vec_info *vinfo,
|
|||
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;
|
||||
}
|
||||
|
@ -2444,59 +2445,34 @@ vect_build_slp_instance (vec_info *vinfo,
|
|||
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
|
||||
|
@ -2511,30 +2487,23 @@ vect_analyze_slp_instance (vec_info *vinfo,
|
|||
{
|
||||
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))
|
||||
|
@ -2543,13 +2512,16 @@ vect_analyze_slp_instance (vec_info *vinfo,
|
|||
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. */
|
||||
|
@ -2573,7 +2545,10 @@ vect_analyze_slp (vec_info *vinfo, unsigned max_tree_size)
|
|||
|
||||
/* 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))
|
||||
{
|
||||
|
@ -2583,6 +2558,7 @@ vect_analyze_slp (vec_info *vinfo, unsigned max_tree_size)
|
|||
&& ! 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. */
|
||||
|
@ -2604,7 +2580,7 @@ vect_analyze_slp (vec_info *vinfo, unsigned max_tree_size)
|
|||
/* 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. */
|
||||
|
@ -4033,6 +4009,15 @@ vect_slp_check_for_constructors (bb_vec_info bb_vinfo)
|
|||
|| 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);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue