Avoid recomputing data references in BB SLP
authorRichard Sandiford <richard.sandiford@arm.com>
Sun, 20 Oct 2019 12:58:22 +0000 (12:58 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Sun, 20 Oct 2019 12:58:22 +0000 (12:58 +0000)
If the first attempt at applying BB SLP to a region fails, the main loop
in vect_slp_bb recomputes the region's bounds and datarefs for the next
vector size.  AFAICT this isn't needed any more; we should be able
to reuse the datarefs from the first attempt instead.

2019-10-20  Richard Sandiford  <richard.sandiford@arm.com>

gcc/
* tree-vect-slp.c (vect_slp_analyze_bb_1): Call save_datarefs
when processing the given datarefs for the first time and
check_datarefs subsequently.
(vect_slp_bb_region): New function, split out of...
(vect_slp_bb): ...here.  Don't recompute the region bounds and
dataref sets when retrying with a different vector size.

From-SVN: r277210

gcc/ChangeLog
gcc/tree-vect-slp.c

index 49195396b0d2bebb54413a9777c5e059a9c2efb4..42cba4b99957936d5607d689e74a8bcf9ec642a3 100644 (file)
@@ -1,3 +1,12 @@
+2019-10-20  Richard Sandiford  <richard.sandiford@arm.com>
+
+       * tree-vect-slp.c (vect_slp_analyze_bb_1): Call save_datarefs
+       when processing the given datarefs for the first time and
+       check_datarefs subsequently.
+       (vect_slp_bb_region): New function, split out of...
+       (vect_slp_bb): ...here.  Don't recompute the region bounds and
+       dataref sets when retrying with a different vector size.
+
 2019-10-19  Jakub Jelinek  <jakub@redhat.com>
            Uroš Bizjak  <ubizjak@gmail.com>
 
index 77b18ba36d02dc7b5fc92ab5a56ecc40fbab390a..d21d18f0cc255c9726a6830c7cd423550cf97336 100644 (file)
@@ -2852,6 +2852,7 @@ vect_slp_analyze_bb_1 (gimple_stmt_iterator region_begin,
   slp_instance instance;
   int i;
   poly_uint64 min_vf = 2;
+  bool first_time_p = shared->datarefs.is_empty ();
 
   /* The first group of checks is independent of the vector size.  */
   fatal = true;
@@ -2871,7 +2872,10 @@ vect_slp_analyze_bb_1 (gimple_stmt_iterator region_begin,
     return NULL;
 
   BB_VINFO_DATAREFS (bb_vinfo) = datarefs;
-  bb_vinfo->shared->save_datarefs ();
+  if (first_time_p)
+    bb_vinfo->shared->save_datarefs ();
+  else
+    bb_vinfo->shared->check_datarefs ();
 
   /* Analyze the data references.  */
 
@@ -3007,16 +3011,18 @@ vect_slp_analyze_bb_1 (gimple_stmt_iterator region_begin,
   return bb_vinfo;
 }
 
+/* Subroutine of vect_slp_bb.  Try to vectorize the statements between
+   REGION_BEGIN (inclusive) and REGION_END (exclusive), returning true
+   on success.  The region has N_STMTS statements and has the datarefs
+   given by DATAREFS.  */
 
-/* Main entry for the BB vectorizer.  Analyze and transform BB, returns
-   true if anything in the basic-block was vectorized.  */
-
-bool
-vect_slp_bb (basic_block bb)
+static bool
+vect_slp_bb_region (gimple_stmt_iterator region_begin,
+                   gimple_stmt_iterator region_end,
+                   vec<data_reference_p> datarefs,
+                   unsigned int n_stmts)
 {
   bb_vec_info bb_vinfo;
-  gimple_stmt_iterator gsi;
-  bool any_vectorized = false;
   auto_vector_sizes vector_sizes;
 
   /* Autodetect first vector size we try.  */
@@ -3024,46 +3030,15 @@ vect_slp_bb (basic_block bb)
   targetm.vectorize.autovectorize_vector_sizes (&vector_sizes, false);
   unsigned int next_size = 0;
 
-  gsi = gsi_start_bb (bb);
+  vec_info_shared shared;
 
   poly_uint64 autodetected_vector_size = 0;
   while (1)
     {
-      if (gsi_end_p (gsi))
-       break;
-
-      gimple_stmt_iterator region_begin = gsi;
-      vec<data_reference_p> datarefs = vNULL;
-      int insns = 0;
-
-      for (; !gsi_end_p (gsi); gsi_next (&gsi))
-       {
-         gimple *stmt = gsi_stmt (gsi);
-         if (is_gimple_debug (stmt))
-           continue;
-         insns++;
-
-         if (gimple_location (stmt) != UNKNOWN_LOCATION)
-           vect_location = stmt;
-
-         if (!vect_find_stmt_data_reference (NULL, stmt, &datarefs))
-           break;
-       }
-
-      /* Skip leading unhandled stmts.  */
-      if (gsi_stmt (region_begin) == gsi_stmt (gsi))
-       {
-         gsi_next (&gsi);
-         continue;
-       }
-
-      gimple_stmt_iterator region_end = gsi;
-
       bool vectorized = false;
       bool fatal = false;
-      vec_info_shared shared;
       bb_vinfo = vect_slp_analyze_bb_1 (region_begin, region_end,
-                                       datarefs, insns, fatal, &shared);
+                                       datarefs, n_stmts, fatal, &shared);
       if (bb_vinfo
          && dbg_cnt (vect_slp))
        {
@@ -3090,8 +3065,6 @@ vect_slp_bb (basic_block bb)
        }
       delete bb_vinfo;
 
-      any_vectorized |= vectorized;
-
       if (next_size == 0)
        autodetected_vector_size = current_vector_size;
 
@@ -3105,33 +3078,68 @@ vect_slp_bb (basic_block bb)
          /* If vect_slp_analyze_bb_1 signaled that analysis for all
             vector sizes will fail do not bother iterating.  */
          || fatal)
+       return vectorized;
+
+      /* Try the next biggest vector size.  */
+      current_vector_size = vector_sizes[next_size++];
+      if (dump_enabled_p ())
        {
-         if (gsi_end_p (region_end))
-           break;
+         dump_printf_loc (MSG_NOTE, vect_location,
+                          "***** Re-trying analysis with "
+                          "vector size ");
+         dump_dec (MSG_NOTE, current_vector_size);
+         dump_printf (MSG_NOTE, "\n");
+       }
+    }
+}
 
-         /* Skip the unhandled stmt.  */
-         gsi_next (&gsi);
+/* Main entry for the BB vectorizer.  Analyze and transform BB, returns
+   true if anything in the basic-block was vectorized.  */
 
-         /* And reset vector sizes.  */
-         current_vector_size = 0;
-         next_size = 0;
-       }
-      else
+bool
+vect_slp_bb (basic_block bb)
+{
+  gimple_stmt_iterator gsi;
+  bool any_vectorized = false;
+
+  gsi = gsi_start_bb (bb);
+  while (!gsi_end_p (gsi))
+    {
+      gimple_stmt_iterator region_begin = gsi;
+      vec<data_reference_p> datarefs = vNULL;
+      int insns = 0;
+
+      for (; !gsi_end_p (gsi); gsi_next (&gsi))
        {
-         /* Try the next biggest vector size.  */
-         current_vector_size = vector_sizes[next_size++];
-         if (dump_enabled_p ())
-           {
-             dump_printf_loc (MSG_NOTE, vect_location,
-                              "***** Re-trying analysis with "
-                              "vector size ");
-             dump_dec (MSG_NOTE, current_vector_size);
-             dump_printf (MSG_NOTE, "\n");
-           }
+         gimple *stmt = gsi_stmt (gsi);
+         if (is_gimple_debug (stmt))
+           continue;
+         insns++;
+
+         if (gimple_location (stmt) != UNKNOWN_LOCATION)
+           vect_location = stmt;
+
+         if (!vect_find_stmt_data_reference (NULL, stmt, &datarefs))
+           break;
+       }
 
-         /* Start over.  */
-         gsi = region_begin;
+      /* Skip leading unhandled stmts.  */
+      if (gsi_stmt (region_begin) == gsi_stmt (gsi))
+       {
+         gsi_next (&gsi);
+         continue;
        }
+
+      gimple_stmt_iterator region_end = gsi;
+
+      if (vect_slp_bb_region (region_begin, region_end, datarefs, insns))
+       any_vectorized = true;
+
+      if (gsi_end_p (region_end))
+       break;
+
+      /* Skip the unhandled stmt.  */
+      gsi_next (&gsi);
     }
 
   return any_vectorized;