diff options
author | Alejandro Martinez <alejandro.martinezvicente@arm.com> | 2019-05-28 13:48:44 +0000 |
---|---|---|
committer | Alejandro Martinez <alejandro@gcc.gnu.org> | 2019-05-28 13:48:44 +0000 |
commit | 997636716c5dde7d59d026726a6f58918069f122 (patch) | |
tree | d18d1d7f5388bc0bb743583ce506e284c8eb60d3 /gcc/tree-vect-loop.c | |
parent | 8b4e7143550cd1f3f4b1dca005a5e656506979d9 (diff) | |
download | gcc-997636716c5dde7d59d026726a6f58918069f122.zip gcc-997636716c5dde7d59d026726a6f58918069f122.tar.gz gcc-997636716c5dde7d59d026726a6f58918069f122.tar.bz2 |
Current vectoriser doesn't support masked loads for SLP.
Current vectoriser doesn't support masked loads for SLP. We should add that, to
allow things like:
void
f (int *restrict x, int *restrict y, int *restrict z, int n)
{
for (int i = 0; i < n; i += 2)
{
x[i] = y[i] ? z[i] : 1;
x[i + 1] = y[i + 1] ? z[i + 1] : 2;
}
}
to be vectorized using contiguous loads rather than LD2 and ST2.
This patch was motivated by SVE, but it is completely generic and should apply
to any architecture with masked loads.
From-SVN: r271704
Diffstat (limited to 'gcc/tree-vect-loop.c')
-rw-r--r-- | gcc/tree-vect-loop.c | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c index e1229a5..4942c69 100644 --- a/gcc/tree-vect-loop.c +++ b/gcc/tree-vect-loop.c @@ -1774,6 +1774,50 @@ vect_get_datarefs_in_loop (loop_p loop, basic_block *bbs, return opt_result::success (); } +/* Look for SLP-only access groups and turn each individual access into its own + group. */ +static void +vect_dissolve_slp_only_groups (loop_vec_info loop_vinfo) +{ + unsigned int i; + struct data_reference *dr; + + DUMP_VECT_SCOPE ("vect_dissolve_slp_only_groups"); + + vec<data_reference_p> datarefs = loop_vinfo->shared->datarefs; + FOR_EACH_VEC_ELT (datarefs, i, dr) + { + gcc_assert (DR_REF (dr)); + stmt_vec_info stmt_info = loop_vinfo->lookup_stmt (DR_STMT (dr)); + + /* Check if the load is a part of an interleaving chain. */ + if (STMT_VINFO_GROUPED_ACCESS (stmt_info)) + { + stmt_vec_info first_element = DR_GROUP_FIRST_ELEMENT (stmt_info); + unsigned int group_size = DR_GROUP_SIZE (first_element); + + /* Check if SLP-only groups. */ + if (!STMT_SLP_TYPE (stmt_info) + && STMT_VINFO_SLP_VECT_ONLY (first_element)) + { + /* Dissolve the group. */ + STMT_VINFO_SLP_VECT_ONLY (first_element) = false; + + stmt_vec_info vinfo = first_element; + while (vinfo) + { + stmt_vec_info next = DR_GROUP_NEXT_ELEMENT (vinfo); + DR_GROUP_FIRST_ELEMENT (vinfo) = vinfo; + DR_GROUP_NEXT_ELEMENT (vinfo) = NULL; + DR_GROUP_SIZE (vinfo) = 1; + DR_GROUP_GAP (vinfo) = group_size - 1; + vinfo = next; + } + } + } + } +} + /* Function vect_analyze_loop_2. Apply a set of analyses on LOOP, and create a loop_vec_info struct @@ -1990,6 +2034,9 @@ start_over: } } + /* Dissolve SLP-only groups. */ + vect_dissolve_slp_only_groups (loop_vinfo); + /* Scan all the remaining operations in the loop that are not subject to SLP and make sure they are vectorizable. */ ok = vect_analyze_loop_operations (loop_vinfo); |