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

Reply via email to