aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2020-10-14 13:44:21 +0200
committerRichard Biener <rguenther@suse.de>2020-10-14 15:07:17 +0200
commitec5e6467091ee0f8de2f894f0c1669465a8440f1 (patch)
treec928f949a7af97b4bc3921ae1a90d5add8870af3 /gcc
parent17d5739a6b103cdd3315f5d0e09fe8faa6620a03 (diff)
downloadgcc-ec5e6467091ee0f8de2f894f0c1669465a8440f1.zip
gcc-ec5e6467091ee0f8de2f894f0c1669465a8440f1.tar.gz
gcc-ec5e6467091ee0f8de2f894f0c1669465a8440f1.tar.bz2
adjust BB SLP build from scalars heuristics
We can end up with { _1, 1.0 } * { 3.0, _2 } which isn't really profitable. The following adjusts things so we reject more than one possibly expensive (non-constant and not uniform) vector CTOR and instead build a CTOR for the scalar operation results. This also moves a check in vect_get_and_check_slp_defs to a better place. 2020-10-14 Richard Biener <rguenther@suse.de> * tree-vect-slp.c (vect_get_and_check_slp_defs): Move check for duplicate/interleave of variable size constants to a place done once and early. (vect_build_slp_tree_2): Adjust heuristics when to build a BB SLP node from scalars.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/tree-vect-slp.c51
1 files changed, 31 insertions, 20 deletions
diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c
index ff0ecda..ba681fe 100644
--- a/gcc/tree-vect-slp.c
+++ b/gcc/tree-vect-slp.c
@@ -457,8 +457,23 @@ again:
if (def_stmt_info && is_pattern_stmt_p (def_stmt_info))
oprnd_info->any_pattern = true;
+ tree type = TREE_TYPE (oprnd);
if (first)
{
+ if ((dt == vect_constant_def
+ || dt == vect_external_def)
+ && !GET_MODE_SIZE (vinfo->vector_mode).is_constant ()
+ && (TREE_CODE (type) == BOOLEAN_TYPE
+ || !can_duplicate_and_interleave_p (vinfo, stmts.length (),
+ type)))
+ {
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "Build SLP failed: invalid type of def "
+ "for variable-length SLP %T\n", oprnd);
+ return -1;
+ }
+
/* For the swapping logic below force vect_reduction_def
for the reduction op in a SLP reduction group. */
if (!STMT_VINFO_DATA_REF (stmt_info)
@@ -467,7 +482,7 @@ again:
&& def_stmt_info)
dt = vect_reduction_def;
oprnd_info->first_dt = dt;
- oprnd_info->first_op_type = TREE_TYPE (oprnd);
+ oprnd_info->first_op_type = type;
}
else
{
@@ -476,7 +491,6 @@ again:
types for reduction chains: the first stmt must be a
vect_reduction_def (a phi node), and the rest
end in the reduction chain. */
- tree type = TREE_TYPE (oprnd);
if ((oprnd_info->first_dt != dt
&& !(oprnd_info->first_dt == vect_reduction_def
&& !STMT_VINFO_DATA_REF (stmt_info)
@@ -514,19 +528,6 @@ again:
return 1;
}
- if ((dt == vect_constant_def
- || dt == vect_external_def)
- && !GET_MODE_SIZE (vinfo->vector_mode).is_constant ()
- && (TREE_CODE (type) == BOOLEAN_TYPE
- || !can_duplicate_and_interleave_p (vinfo, stmts.length (),
- type)))
- {
- if (dump_enabled_p ())
- dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
- "Build SLP failed: invalid type of def "
- "for variable-length SLP %T\n", oprnd);
- return -1;
- }
}
/* Check the types of the definitions. */
@@ -1568,7 +1569,8 @@ fail:
vect_free_oprnd_info (oprnds_info);
/* If we have all children of a child built up from uniform scalars
- then just throw that away, causing it built up from scalars.
+ or does more than one possibly expensive vector construction then
+ just throw that away, causing it built up from scalars.
The exception is the SLP node for the vector store. */
if (is_a <bb_vec_info> (vinfo)
&& !STMT_VINFO_GROUPED_ACCESS (stmt_info)
@@ -1579,11 +1581,20 @@ fail:
{
slp_tree child;
unsigned j;
+ bool all_uniform_p = true;
+ unsigned n_vector_builds = 0;
FOR_EACH_VEC_ELT (children, j, child)
- if (SLP_TREE_DEF_TYPE (child) == vect_internal_def
- || !vect_slp_tree_uniform_p (child))
- break;
- if (!child)
+ {
+ if (SLP_TREE_DEF_TYPE (child) == vect_internal_def)
+ all_uniform_p = false;
+ else if (!vect_slp_tree_uniform_p (child))
+ {
+ all_uniform_p = false;
+ if (SLP_TREE_DEF_TYPE (child) == vect_external_def)
+ n_vector_builds++;
+ }
+ }
+ if (all_uniform_p || n_vector_builds > 1)
{
/* Roll back. */
matches[0] = false;