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.
---
 gcc/tree-vect-stmts.cc | 71 ++++++++++++++++++++++++++++++++++--------
 1 file changed, 58 insertions(+), 13 deletions(-)

diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc
index 5ec65b2b2de..f9905652295 100644
--- a/gcc/tree-vect-stmts.cc
+++ b/gcc/tree-vect-stmts.cc
@@ -1489,6 +1489,56 @@ vect_get_len (vec_info *vinfo, slp_tree slp_node, 
gimple_stmt_iterator *gsi,
 static tree permute_vec_elements (vec_info *, tree, tree, tree, stmt_vec_info,
                                  gimple_stmt_iterator *);
 
+/* If target supports vector load/store (determined by IS_LOAD) with length for
+   VECTYPE, return VECT_PARTIAL_VECTORS_LEN; otherwise, if it supports vector
+   masked load/store for mode for VECTYPE, return
+   VECT_PARTIAL_VECTORS_WHILE_ULT; otherwise, return VECT_PARTIAL_VECTORS_NONE.
+   If load/store with length or mask is supported and ELSVALS is nonzero, 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_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_partial_vector_style
+vect_get_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_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_partial_vectors_while_ult;
+       }
+    }
+
+  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_partial_vectors_none;
+}
+
 /* Check whether a load or store statement in the loop or SLP group described 
by
    VINFO is possible using partial vectors.  This is
    testing whether the vectorizer pass has the appropriate support,
@@ -1642,28 +1692,23 @@ check_load_store_for_partial_vectors (vec_info *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_partial_vector_style partial_vector_style
+    = vect_get_partial_vector_style (vectype, is_load, &factor, elsvals);
+
+  if (partial_vector_style == vect_partial_vectors_len)
     {
       nvectors = group_memory_nvectors (group_size * vf, nunits);
-      unsigned factor = (vecmode == vmode) ? 1 : GET_MODE_UNIT_SIZE (vecmode);
       vect_record_len (vinfo, slp_node, 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_partial_vectors_while_ult)
     {
       nvectors = group_memory_nvectors (group_size * vf, nunits);
       vect_record_mask (vinfo, slp_node, nvectors, vectype, scalar_mask);
-      using_partial_vectors_p = true;
     }
-
-  if (!using_partial_vectors_p)
+  else
     {
+      gcc_assert (partial_vector_style == vect_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