aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-vect-data-refs.c
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@arm.com>2021-11-30 09:52:29 +0000
committerRichard Sandiford <richard.sandiford@arm.com>2021-11-30 09:52:29 +0000
commit10833849b55401a52f2334eb032a70beb688e9fc (patch)
treea2556da822f071f9f927e85f9f4ecb668bac4d07 /gcc/tree-vect-data-refs.c
parent6f798618c070e2ca505e39c3fcc0c3ca478ac81b (diff)
downloadgcc-10833849b55401a52f2334eb032a70beb688e9fc.zip
gcc-10833849b55401a52f2334eb032a70beb688e9fc.tar.gz
gcc-10833849b55401a52f2334eb032a70beb688e9fc.tar.bz2
vect: Support gather loads with SLP
This patch adds SLP support for IFN_GATHER_LOAD. Like the SLP support for IFN_MASK_LOAD, it works by treating only some of the arguments as child nodes. Unlike IFN_MASK_LOAD, it requires the other arguments (base, scale, and extension type) to be the same for all calls in the group. It does not require/expect the loads to be in a group (which probably wouldn't make sense for gathers). I was worried about the possible alias effect of moving gathers around to be part of the same SLP group. The patch therefore makes vect_analyze_data_ref_dependence treat gathers and scatters as a top-level concern, punting if the accesses aren't completely independent and if the user hasn't told us that a particular VF is safe. I think in practice we already punted in the same circumstances; the idea is just to make it more explicit. gcc/ PR tree-optimization/102467 * doc/sourcebuild.texi (vect_gather_load_ifn): Document. * tree-vect-data-refs.c (vect_analyze_data_ref_dependence): Commonize safelen handling. Punt for anything involving gathers and scatters unless safelen says otherwise. * tree-vect-slp.c (arg1_map): New variable. (vect_get_operand_map): Handle IFN_GATHER_LOAD. (vect_build_slp_tree_1): Likewise. (vect_build_slp_tree_2): Likewise. (compatible_calls_p): If vect_get_operand_map returns nonnull, check that any skipped arguments are equal. (vect_slp_analyze_node_operations_1): Tighten reduction check. * tree-vect-stmts.c (check_load_store_for_partial_vectors): Take an ncopies argument. (vect_get_gather_scatter_ops): Take slp_node and ncopies arguments. Handle SLP nodes. (vectorizable_store, vectorizable_load): Adjust accordingly. gcc/testsuite/ * lib/target-supports.exp (check_effective_target_vect_gather_load_ifn): New target test. * gcc.dg/vect/vect-gather-1.c: New test. * gcc.dg/vect/vect-gather-2.c: Likewise. * gcc.target/aarch64/sve/gather_load_11.c: Likewise.
Diffstat (limited to 'gcc/tree-vect-data-refs.c')
-rw-r--r--gcc/tree-vect-data-refs.c64
1 files changed, 30 insertions, 34 deletions
diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c
index 888ad72..12a82cd 100644
--- a/gcc/tree-vect-data-refs.c
+++ b/gcc/tree-vect-data-refs.c
@@ -359,6 +359,20 @@ vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr,
lambda_vector dist_v;
unsigned int loop_depth;
+ /* If user asserted safelen consecutive iterations can be
+ executed concurrently, assume independence. */
+ auto apply_safelen = [&]()
+ {
+ if (loop->safelen >= 2)
+ {
+ if ((unsigned int) loop->safelen < *max_vf)
+ *max_vf = loop->safelen;
+ LOOP_VINFO_NO_DATA_DEPENDENCIES (loop_vinfo) = false;
+ return true;
+ }
+ return false;
+ };
+
/* In loop analysis all data references should be vectorizable. */
if (!STMT_VINFO_VECTORIZABLE (stmtinfo_a)
|| !STMT_VINFO_VECTORIZABLE (stmtinfo_b))
@@ -393,26 +407,23 @@ vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr,
get_alias_set (DR_REF (drb))))
return opt_result::success ();
+ if (STMT_VINFO_GATHER_SCATTER_P (stmtinfo_a)
+ || STMT_VINFO_GATHER_SCATTER_P (stmtinfo_b))
+ {
+ if (apply_safelen ())
+ return opt_result::success ();
+
+ return opt_result::failure_at
+ (stmtinfo_a->stmt,
+ "possible alias involving gather/scatter between %T and %T\n",
+ DR_REF (dra), DR_REF (drb));
+ }
+
/* Unknown data dependence. */
if (DDR_ARE_DEPENDENT (ddr) == chrec_dont_know)
{
- /* If user asserted safelen consecutive iterations can be
- executed concurrently, assume independence. */
- if (loop->safelen >= 2)
- {
- if ((unsigned int) loop->safelen < *max_vf)
- *max_vf = loop->safelen;
- LOOP_VINFO_NO_DATA_DEPENDENCIES (loop_vinfo) = false;
- return opt_result::success ();
- }
-
- if (STMT_VINFO_GATHER_SCATTER_P (stmtinfo_a)
- || STMT_VINFO_GATHER_SCATTER_P (stmtinfo_b))
- return opt_result::failure_at
- (stmtinfo_a->stmt,
- "versioning for alias not supported for: "
- "can't determine dependence between %T and %T\n",
- DR_REF (dra), DR_REF (drb));
+ if (apply_safelen ())
+ return opt_result::success ();
if (dump_enabled_p ())
dump_printf_loc (MSG_MISSED_OPTIMIZATION, stmtinfo_a->stmt,
@@ -427,23 +438,8 @@ vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr,
/* Known data dependence. */
if (DDR_NUM_DIST_VECTS (ddr) == 0)
{
- /* If user asserted safelen consecutive iterations can be
- executed concurrently, assume independence. */
- if (loop->safelen >= 2)
- {
- if ((unsigned int) loop->safelen < *max_vf)
- *max_vf = loop->safelen;
- LOOP_VINFO_NO_DATA_DEPENDENCIES (loop_vinfo) = false;
- return opt_result::success ();
- }
-
- if (STMT_VINFO_GATHER_SCATTER_P (stmtinfo_a)
- || STMT_VINFO_GATHER_SCATTER_P (stmtinfo_b))
- return opt_result::failure_at
- (stmtinfo_a->stmt,
- "versioning for alias not supported for: "
- "bad dist vector for %T and %T\n",
- DR_REF (dra), DR_REF (drb));
+ if (apply_safelen ())
+ return opt_result::success ();
if (dump_enabled_p ())
dump_printf_loc (MSG_MISSED_OPTIMIZATION, stmtinfo_a->stmt,