Refactor vect_analyze_slp_instance a bit

In preparation for a larger change this refactors vect_analyze_slp_instance
so it doesn't need to know a vector type early.

2020-10-22  Richard Biener  <rguenther@suse.de>

	* tree-vect-slp.c (vect_analyze_slp_instance): Refactor so
	computing a vector type early is not needed, for store group
	splitting compute a new vector type based on the desired
	group size.
This commit is contained in:
Richard Biener 2020-10-22 12:57:25 +02:00
parent b960a9c83a
commit 655f7f0fb7
1 changed files with 38 additions and 47 deletions

View File

@ -2009,7 +2009,6 @@ vect_analyze_slp_instance (vec_info *vinfo,
slp_instance new_instance;
slp_tree node;
unsigned int group_size;
tree vectype, scalar_type = NULL_TREE;
unsigned int i;
struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info);
vec<stmt_vec_info> scalar_stmts;
@ -2019,41 +2018,25 @@ vect_analyze_slp_instance (vec_info *vinfo,
vect_location = stmt_info->stmt;
if (STMT_VINFO_GROUPED_ACCESS (stmt_info))
{
scalar_type = TREE_TYPE (DR_REF (dr));
group_size = DR_GROUP_SIZE (stmt_info);
vectype = get_vectype_for_scalar_type (vinfo, scalar_type, group_size);
}
else if (!dr && REDUC_GROUP_FIRST_ELEMENT (stmt_info))
{
gcc_assert (is_a <loop_vec_info> (vinfo));
vectype = STMT_VINFO_VECTYPE (stmt_info);
group_size = REDUC_GROUP_SIZE (stmt_info);
}
else if (is_gimple_assign (stmt_info->stmt)
&& gimple_assign_rhs_code (stmt_info->stmt) == CONSTRUCTOR)
{
vectype = TREE_TYPE (gimple_assign_rhs1 (stmt_info->stmt));
group_size = CONSTRUCTOR_NELTS (gimple_assign_rhs1 (stmt_info->stmt));
constructor = true;
}
else
{
gcc_assert (is_a <loop_vec_info> (vinfo));
vectype = STMT_VINFO_VECTYPE (stmt_info);
group_size = as_a <loop_vec_info> (vinfo)->reductions.length ();
}
if (!vectype)
{
if (dump_enabled_p ())
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
"Build SLP failed: unsupported data-type %T\n",
scalar_type);
return false;
}
poly_uint64 nunits = TYPE_VECTOR_SUBPARTS (vectype);
/* 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;
@ -2127,7 +2110,7 @@ vect_analyze_slp_instance (vec_info *vinfo,
/* Build the tree for the SLP instance. */
bool *matches = XALLOCAVEC (bool, group_size);
unsigned npermutes = 0;
poly_uint64 max_nunits = nunits;
poly_uint64 max_nunits = 1;
unsigned tree_size = 0;
node = vect_build_slp_tree (vinfo, scalar_stmts, group_size,
&max_nunits, matches, &npermutes,
@ -2201,7 +2184,9 @@ vect_analyze_slp_instance (vec_info *vinfo,
instructions do not generate this SLP instance. */
if (is_a <loop_vec_info> (vinfo)
&& loads_permuted
&& dr && vect_store_lanes_supported (vectype, group_size, false))
&& dr
&& vect_store_lanes_supported
(STMT_VINFO_VECTYPE (scalar_stmts[0]), group_size, false))
{
slp_tree load_node;
FOR_EACH_VEC_ELT (SLP_INSTANCE_LOADS (new_instance), i, load_node)
@ -2284,51 +2269,57 @@ vect_analyze_slp_instance (vec_info *vinfo,
}
/* Try to break the group up into pieces. */
unsigned HOST_WIDE_INT const_nunits;
if (STMT_VINFO_GROUPED_ACCESS (stmt_info)
&& DR_IS_WRITE (STMT_VINFO_DATA_REF (stmt_info))
&& nunits.is_constant (&const_nunits))
&& DR_IS_WRITE (STMT_VINFO_DATA_REF (stmt_info)))
{
for (i = 0; i < group_size; i++)
if (!matches[i])
break;
/* For basic block SLP, try to break the group up into multiples of the
vector size. */
/* For basic block SLP, try to break the group up into multiples of
a vector size. */
if (is_a <bb_vec_info> (vinfo)
&& (i >= const_nunits && i < group_size))
&& (i > 1 && i < group_size))
{
/* Split into two groups at the first vector boundary before i. */
gcc_assert ((const_nunits & (const_nunits - 1)) == 0);
unsigned group1_size = i & ~(const_nunits - 1);
if (dump_enabled_p ())
dump_printf_loc (MSG_NOTE, vect_location,
"Splitting SLP group at stmt %u\n", i);
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);
/* If the first non-match was in the middle of a vector,
skip the rest of that vector. Do not bother to re-analyze
single stmt groups. */
if (group1_size < i)
tree scalar_type
= TREE_TYPE (DR_REF (STMT_VINFO_DATA_REF (stmt_info)));
tree vectype = get_vectype_for_scalar_type (vinfo, scalar_type,
least_bit_hwi (i));
unsigned HOST_WIDE_INT const_nunits;
if (vectype
&& TYPE_VECTOR_SUBPARTS (vectype).is_constant (&const_nunits))
{
i = group1_size + const_nunits;
/* Split into two groups at the first vector boundary. */
gcc_assert ((const_nunits & (const_nunits - 1)) == 0);
unsigned group1_size = i & ~(const_nunits - 1);
if (dump_enabled_p ())
dump_printf_loc (MSG_NOTE, vect_location,
"Splitting SLP group at stmt %u\n", i);
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);
/* If the first non-match was in the middle of a vector,
skip the rest of that vector. Do not bother to re-analyze
single stmt groups. */
if (group1_size < i)
{
i = group1_size + const_nunits;
if (i + 1 < group_size)
rest = vect_split_slp_store_group (rest, const_nunits);
}
if (i + 1 < group_size)
rest = vect_split_slp_store_group (rest, const_nunits);
res |= vect_analyze_slp_instance (vinfo, bst_map,
rest, max_tree_size);
return res;
}
if (i + 1 < group_size)
res |= vect_analyze_slp_instance (vinfo, bst_map,
rest, max_tree_size);
return res;
}
/* For loop vectorization split into arbitrary pieces of size > 1. */
if (is_a <loop_vec_info> (vinfo)
&& (i > 1 && i < group_size))
{
gcc_assert ((const_nunits & (const_nunits - 1)) == 0);
unsigned group1_size = i;
if (dump_enabled_p ())