Moved existing code to determine the partial vector style for a load or
store into a new function that will be reused for BB SLP with predicated
tails.
Instead of reusing the existing enum vect_partial_vector_style, a new
enum type has been defined to represent the return value of the new
function because the new function only tells its caller whether a mask or
length can be used to limit the amount of data loaded or stored; it
cannot tell what variety of masks will be generated (or whether mask
generation will succeed).
gcc/ChangeLog:
* tree-vect-stmts.cc (vect_get_load_store_partial_vector_style):
Define a new function to get the partial vectors style supported
by the target.
(check_load_store_for_partial_vectors): Use the new function in
place of existing custom code to do the same thing.
---
gcc/tree-vect-stmts.cc | 79 +++++++++++++++++++++++++++++++++++-------
1 file changed, 66 insertions(+), 13 deletions(-)
diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc
index 83adb17735f..8bf62074baa 100644
--- a/gcc/tree-vect-stmts.cc
+++ b/gcc/tree-vect-stmts.cc
@@ -1386,6 +1386,63 @@ vectorizable_internal_function (combined_fn cfn, tree
fndecl,
static tree permute_vec_elements (vec_info *, tree, tree, tree, stmt_vec_info,
gimple_stmt_iterator *);
+enum vect_load_store_partial_vector_style {
+ vect_load_store_partial_vectors_none,
+ vect_load_store_partial_vectors_mask,
+ vect_load_store_partial_vectors_len
+};
+
+/* If target supports vector load/store (determined by IS_LOAD) with length for
+ VECTYPE, return VECT_LOAD_STORE_PARTIAL_VECTORS_LEN; otherwise, if it
+ supports vector masked load/store for mode for VECTYPE, return
+ VECT_LOAD_STORE_PARTIAL_VECTORS_MASK; otherwise, return
+ VECT_LOAD_STORE_PARTIAL_VECTORS_NONE. If load/store with length or mask is
+ supported and ELSVALS is not null, store the possible else values in the
+ vector it points to. Unless FACTOR is null, *FACTOR is set to the number of
+ separate subelements that each element of VECTYPE should be split into.
+ (This is always 1 except in the case of VECT_LOAD_STORE_PARTIAL_VECTORS_LEN
+ when the machine mode of VECTYPE can only be supported by using a length in
+ bytes instead of a length in lanes.)
+ */
+static enum vect_load_store_partial_vector_style
+vect_get_load_store_partial_vector_style (tree vectype, bool is_load,
+ unsigned *factor = nullptr,
+ vec<int> *elsvals = nullptr)
+{
+ machine_mode vecmode = TYPE_MODE (vectype);
+
+ /* TYPE_MODE tries to map vector modes that are unsupported by the target to
+ same-sized scalar modes, so reject scalar modes here. */
+ if (VECTOR_MODE_P (vecmode))
+ {
+ machine_mode mask_mode, vmode;
+ if (get_len_load_store_mode (vecmode, is_load, nullptr, elsvals)
+ .exists (&vmode))
+ {
+ if (factor)
+ *factor = (vecmode == vmode) ? 1 : GET_MODE_UNIT_SIZE (vecmode);
+ return vect_load_store_partial_vectors_len;
+ }
+
+ if (factor)
+ *factor = 1;
+
+ if (targetm.vectorize.get_mask_mode (vecmode).exists (&mask_mode)
+ && can_vec_mask_load_store_p (vecmode, mask_mode, is_load, NULL,
+ elsvals))
+ {
+ return vect_load_store_partial_vectors_mask;
+ }
+ }
+
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "the target doesn't have the appropriate partial"
+ " vectorization %s for vector data type %T.\n",
+ is_load ? "load" : "store", vectype);
+ return vect_load_store_partial_vectors_none;
+}
+
/* Check whether a load or store statement in the loop described by
LOOP_VINFO is possible in a loop using partial vectors. This is
testing whether the vectorizer pass has the appropriate support,
@@ -1548,28 +1605,24 @@ check_load_store_for_partial_vectors (loop_vec_info
loop_vinfo, tree vectype,
poly_uint64 nunits = TYPE_VECTOR_SUBPARTS (vectype);
poly_uint64 vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
- machine_mode mask_mode;
- machine_mode vmode;
- bool using_partial_vectors_p = false;
- if (get_len_load_store_mode
- (vecmode, is_load, nullptr, elsvals).exists (&vmode))
+ unsigned factor;
+ vect_load_store_partial_vector_style partial_vector_style
+ = vect_get_load_store_partial_vector_style (vectype, is_load, &factor,
+ elsvals);
+
+ if (partial_vector_style == vect_load_store_partial_vectors_len)
{
nvectors = group_memory_nvectors (group_size * vf, nunits);
- unsigned factor = (vecmode == vmode) ? 1 : GET_MODE_UNIT_SIZE (vecmode);
vect_record_len (loop_vinfo, nvectors, vectype, factor);
- using_partial_vectors_p = true;
}
- else if (targetm.vectorize.get_mask_mode (vecmode).exists (&mask_mode)
- && can_vec_mask_load_store_p (vecmode, mask_mode, is_load, NULL,
- elsvals))
+ else if (partial_vector_style == vect_load_store_partial_vectors_mask)
{
nvectors = group_memory_nvectors (group_size * vf, nunits);
vect_record_mask (loop_vinfo, nvectors, vectype, scalar_mask);
- using_partial_vectors_p = true;
}
-
- if (!using_partial_vectors_p)
+ else
{
+ gcc_assert (partial_vector_style ==
vect_load_store_partial_vectors_none);
if (dump_enabled_p ())
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
"can't operate on partial vectors because the"
--
2.43.0