Avoid retrying with the same vector modes
authorRichard Sandiford <richard.sandiford@arm.com>
Thu, 14 Nov 2019 15:14:33 +0000 (15:14 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Thu, 14 Nov 2019 15:14:33 +0000 (15:14 +0000)
A later patch makes the AArch64 port add four entries to
autovectorize_vector_modes.  Each entry describes a different
vector mode assignment for vector code that mixes 8-bit, 16-bit,
32-bit and 64-bit elements.  But if (as usual) the vector code has
fewer element sizes than that, we could end up trying the same
combination of vector modes multiple times.  This patch adds a
check to prevent that.

2019-11-14  Richard Sandiford  <richard.sandiford@arm.com>

gcc/
* tree-vectorizer.h (vec_info::mode_set): New typedef.
(vec_info::used_vector_mode): New member variable.
(vect_chooses_same_modes_p): Declare.
* tree-vect-stmts.c (get_vectype_for_scalar_type): Record each
chosen vector mode in vec_info::used_vector_mode.
(vect_chooses_same_modes_p): New function.
* tree-vect-loop.c (vect_analyze_loop): Use it to avoid trying
the same vector statements multiple times.
* tree-vect-slp.c (vect_slp_bb_region): Likewise.

From-SVN: r278242

gcc/ChangeLog
gcc/tree-vect-loop.c
gcc/tree-vect-slp.c
gcc/tree-vect-stmts.c
gcc/tree-vectorizer.h

index 680aa85121af39dd1742e40500c1255cef324e0e..6b7e9d5477df3e24d959426f0c9bf0c2826e2f19 100644 (file)
@@ -1,3 +1,15 @@
+2019-11-14  Richard Sandiford  <richard.sandiford@arm.com>
+
+       * tree-vectorizer.h (vec_info::mode_set): New typedef.
+       (vec_info::used_vector_mode): New member variable.
+       (vect_chooses_same_modes_p): Declare.
+       * tree-vect-stmts.c (get_vectype_for_scalar_type): Record each
+       chosen vector mode in vec_info::used_vector_mode.
+       (vect_chooses_same_modes_p): New function.
+       * tree-vect-loop.c (vect_analyze_loop): Use it to avoid trying
+       the same vector statements multiple times.
+       * tree-vect-slp.c (vect_slp_bb_region): Likewise.
+
 2019-11-14  Richard Sandiford  <richard.sandiford@arm.com>
 
        * machmode.h (opt_machine_mode::operator==): New function.
index e60c159d11ac4bd45346a6be84f138df261be9c9..567fcc75e2b9e015cefcd0e8ef4ad24d6068e162 100644 (file)
@@ -2448,6 +2448,19 @@ vect_analyze_loop (class loop *loop, vec_info_shared *shared)
        }
 
       loop->aux = NULL;
+
+      if (!fatal)
+       while (mode_i < vector_modes.length ()
+              && vect_chooses_same_modes_p (loop_vinfo, vector_modes[mode_i]))
+         {
+           if (dump_enabled_p ())
+             dump_printf_loc (MSG_NOTE, vect_location,
+                              "***** The result for vector mode %s would"
+                              " be the same\n",
+                              GET_MODE_NAME (vector_modes[mode_i]));
+           mode_i += 1;
+         }
+
       if (res)
        {
          LOOP_VINFO_VECTORIZABLE_P (loop_vinfo) = 1;
index 1e00db5a326c99c6bea1e653c05b6b07fe93996a..a46bba5ec6032f43fbba2bd7ae8ca03861ae44d1 100644 (file)
@@ -3239,6 +3239,18 @@ vect_slp_bb_region (gimple_stmt_iterator region_begin,
       if (mode_i == 0)
        autodetected_vector_mode = bb_vinfo->vector_mode;
 
+      if (!fatal)
+       while (mode_i < vector_modes.length ()
+              && vect_chooses_same_modes_p (bb_vinfo, vector_modes[mode_i]))
+         {
+           if (dump_enabled_p ())
+             dump_printf_loc (MSG_NOTE, vect_location,
+                              "***** The result for vector mode %s would"
+                              " be the same\n",
+                              GET_MODE_NAME (vector_modes[mode_i]));
+           mode_i += 1;
+         }
+
       delete bb_vinfo;
 
       if (mode_i < vector_modes.length ()
index 36f832bb5224910fa75ecca658c60b60a5df397f..e1fa0756f2665321c455c6bce75d022042ef03c3 100644 (file)
@@ -11263,6 +11263,10 @@ get_vectype_for_scalar_type (vec_info *vinfo, tree scalar_type)
                                                      scalar_type);
   if (vectype && vinfo->vector_mode == VOIDmode)
     vinfo->vector_mode = TYPE_MODE (vectype);
+
+  if (vectype)
+    vinfo->used_vector_modes.add (TYPE_MODE (vectype));
+
   return vectype;
 }
 
@@ -11302,6 +11306,20 @@ get_same_sized_vectype (tree scalar_type, tree vector_type)
                                              scalar_type, nunits);
 }
 
+/* Return true if replacing LOOP_VINFO->vector_mode with VECTOR_MODE
+   would not change the chosen vector modes.  */
+
+bool
+vect_chooses_same_modes_p (vec_info *vinfo, machine_mode vector_mode)
+{
+  for (vec_info::mode_set::iterator i = vinfo->used_vector_modes.begin ();
+       i != vinfo->used_vector_modes.end (); ++i)
+    if (!VECTOR_MODE_P (*i)
+       || related_vector_mode (vector_mode, GET_MODE_INNER (*i), 0) != *i)
+      return false;
+  return true;
+}
+
 /* Function vect_is_simple_use.
 
    Input:
index fadc4d89d1644d081bcb0bfedcbb84b61b4f8248..b029266f24e47af6e9a223186814ec2ac1b32600 100644 (file)
@@ -298,6 +298,7 @@ public:
 /* Vectorizer state common between loop and basic-block vectorization.  */
 class vec_info {
 public:
+  typedef hash_set<int_hash<machine_mode, E_VOIDmode, E_BLKmode> > mode_set;
   enum vec_kind { bb, loop };
 
   vec_info (vec_kind, void *, vec_info_shared *);
@@ -335,6 +336,9 @@ public:
   /* Cost data used by the target cost model.  */
   void *target_cost_data;
 
+  /* The set of vector modes used in the vectorized region.  */
+  mode_set used_vector_modes;
+
   /* The argument we should pass to related_vector_mode when looking up
      the vector mode for a scalar mode, or VOIDmode if we haven't yet
      made any decisions about which vector modes to use.  */
@@ -1630,6 +1634,7 @@ extern tree get_related_vectype_for_scalar_type (machine_mode, tree,
 extern tree get_vectype_for_scalar_type (vec_info *, tree);
 extern tree get_mask_type_for_scalar_type (vec_info *, tree);
 extern tree get_same_sized_vectype (tree, tree);
+extern bool vect_chooses_same_modes_p (vec_info *, machine_mode);
 extern bool vect_get_loop_mask_type (loop_vec_info);
 extern bool vect_is_simple_use (tree, vec_info *, enum vect_def_type *,
                                stmt_vec_info * = NULL, gimple ** = NULL);