public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] First refactor of vect_analyze_loop
@ 2021-10-27 12:10 Richard Biener
  2021-10-27 16:27 ` Richard Sandiford
  0 siblings, 1 reply; 4+ messages in thread
From: Richard Biener @ 2021-10-27 12:10 UTC (permalink / raw)
  To: gcc-patches; +Cc: richard.sandiford, andre.simoesdiasvieira

This refactors the main loop analysis part in vect_analyze_loop,
re-purposing the existing vect_reanalyze_as_main_loop for this
to reduce code duplication.  Failure flow is a bit tricky since
we want to extract info from the analyzed loop but I wanted to
share the destruction part.  Thus I add some std::function and
lambda to funnel post-analysis for the case we want that
(when analyzing from the main iteration but not when re-analyzing
an epilogue as main).

I realize this probably doesn't help the unroll case yet, but it
looked like an improvement.

Bootstrapped and tested on x86_64-unknown-linux-gnu.

OK?

Thanks,
Richard.

2021-10-27  Richard Biener  <rguenther@suse.de>

	* tree-vect-loop.c: Include <functional>.
	(vect_reanalyze_as_main_loop): Rename to...
	(vect_analyze_loop_1): ... this and generalize to be
	able to use it twice ...
	(vect_analyze_loop): ... here.
---
 gcc/tree-vect-loop.c | 202 ++++++++++++++++++++++---------------------
 1 file changed, 102 insertions(+), 100 deletions(-)

diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c
index 961c1623f81..9a62475a69f 100644
--- a/gcc/tree-vect-loop.c
+++ b/gcc/tree-vect-loop.c
@@ -20,6 +20,7 @@ along with GCC; see the file COPYING3.  If not see
 <http://www.gnu.org/licenses/>.  */
 
 #define INCLUDE_ALGORITHM
+#define INCLUDE_FUNCTIONAL
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
@@ -2898,43 +2899,63 @@ vect_joust_loop_vinfos (loop_vec_info new_loop_vinfo,
   return true;
 }
 
-/* If LOOP_VINFO is already a main loop, return it unmodified.  Otherwise
-   try to reanalyze it as a main loop.  Return the loop_vinfo on success
-   and null on failure.  */
+/* Analyze LOOP with VECTOR_MODE and as epilogue if MAIN_LOOP_VINFO is
+   not NULL.  Process the analyzed loop with PROCESS even if analysis
+   failed.  Sets *N_STMTS and FATAL according to the analysis.
+   Return the loop_vinfo on success and wrapped null on failure.  */
 
-static loop_vec_info
-vect_reanalyze_as_main_loop (loop_vec_info loop_vinfo, unsigned int *n_stmts)
+static opt_loop_vec_info
+vect_analyze_loop_1 (class loop *loop, vec_info_shared *shared,
+		     machine_mode vector_mode, loop_vec_info main_loop_vinfo,
+		     unsigned int *n_stmts, bool &fatal,
+		     std::function<void(loop_vec_info)> process = nullptr)
 {
-  if (!LOOP_VINFO_EPILOGUE_P (loop_vinfo))
-    return loop_vinfo;
+  /* Check the CFG characteristics of the loop (nesting, entry/exit).  */
+  opt_loop_vec_info loop_vinfo = vect_analyze_loop_form (loop, shared);
+  if (!loop_vinfo)
+    {
+      if (dump_enabled_p ())
+	dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+			 "bad loop form.\n");
+      gcc_checking_assert (main_loop_vinfo == NULL);
+      return loop_vinfo;
+    }
+  loop_vinfo->vector_mode = vector_mode;
 
-  if (dump_enabled_p ())
-    dump_printf_loc (MSG_NOTE, vect_location,
-		     "***** Reanalyzing as a main loop with vector mode %s\n",
-		     GET_MODE_NAME (loop_vinfo->vector_mode));
+  if (main_loop_vinfo)
+    LOOP_VINFO_ORIG_LOOP_INFO (loop_vinfo) = main_loop_vinfo;
 
-  struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
-  vec_info_shared *shared = loop_vinfo->shared;
-  opt_loop_vec_info main_loop_vinfo = vect_analyze_loop_form (loop, shared);
-  gcc_assert (main_loop_vinfo);
+  /* Run the main analysis.  */
+  fatal = false;
+  opt_result res = vect_analyze_loop_2 (loop_vinfo, fatal, n_stmts);
+  loop->aux = NULL;
 
-  main_loop_vinfo->vector_mode = loop_vinfo->vector_mode;
+  /* Process info before we destroy loop_vinfo upon analysis failure.  */
+  if (process)
+    process (loop_vinfo);
 
-  bool fatal = false;
-  bool res = vect_analyze_loop_2 (main_loop_vinfo, fatal, n_stmts);
-  loop->aux = NULL;
-  if (!res)
+  if (dump_enabled_p ())
     {
-      if (dump_enabled_p ())
+      if (res)
 	dump_printf_loc (MSG_NOTE, vect_location,
-			 "***** Failed to analyze main loop with vector"
-			 " mode %s\n",
+			 "***** Analysis succeeded with vector mode %s\n",
 			 GET_MODE_NAME (loop_vinfo->vector_mode));
-      delete main_loop_vinfo;
-      return NULL;
+      else
+	dump_printf_loc (MSG_NOTE, vect_location,
+			 "***** Analysis failed with vector mode %s\n",
+			 GET_MODE_NAME (loop_vinfo->vector_mode));
+    }
+
+  if (!res)
+    {
+      delete loop_vinfo;
+      if (fatal)
+	gcc_checking_assert (main_loop_vinfo == NULL);
+      return opt_loop_vec_info::propagate_failure (res);
     }
-  LOOP_VINFO_VECTORIZABLE_P (main_loop_vinfo) = 1;
-  return main_loop_vinfo;
+
+  LOOP_VINFO_VECTORIZABLE_P (loop_vinfo) = 1;
+  return loop_vinfo;
 }
 
 /* Function vect_analyze_loop.
@@ -2981,20 +3002,6 @@ vect_analyze_loop (class loop *loop, vec_info_shared *shared)
   unsigned HOST_WIDE_INT simdlen = loop->simdlen;
   while (1)
     {
-      /* Check the CFG characteristics of the loop (nesting, entry/exit).  */
-      opt_loop_vec_info loop_vinfo = vect_analyze_loop_form (loop, shared);
-      if (!loop_vinfo)
-	{
-	  if (dump_enabled_p ())
-	    dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
-			     "bad loop form.\n");
-	  gcc_checking_assert (first_loop_vinfo == NULL);
-	  return loop_vinfo;
-	}
-      loop_vinfo->vector_mode = next_vector_mode;
-
-      bool fatal = false;
-
       /* When pick_lowest_cost_p is true, we should in principle iterate
 	 over all the loop_vec_infos that LOOP_VINFO could replace and
 	 try to vectorize LOOP_VINFO under the same conditions.
@@ -3023,41 +3030,35 @@ vect_analyze_loop (class loop *loop, vec_info_shared *shared)
 	 LOOP_VINFO fails when treated as an epilogue loop, succeeds when
 	 treated as a standalone loop, and ends up being genuinely cheaper
 	 than FIRST_LOOP_VINFO.  */
-      if (vect_epilogues)
-	LOOP_VINFO_ORIG_LOOP_INFO (loop_vinfo) = first_loop_vinfo;
 
-      res = vect_analyze_loop_2 (loop_vinfo, fatal, &n_stmts);
-      if (mode_i == 0)
-	autodetected_vector_mode = loop_vinfo->vector_mode;
-      if (dump_enabled_p ())
+      bool fatal;
+      auto cb = [&] (loop_vec_info loop_vinfo)
 	{
-	  if (res)
-	    dump_printf_loc (MSG_NOTE, vect_location,
-			     "***** Analysis succeeded with vector mode %s\n",
-			     GET_MODE_NAME (loop_vinfo->vector_mode));
-	  else
-	    dump_printf_loc (MSG_NOTE, vect_location,
-			     "***** Analysis failed with vector mode %s\n",
-			     GET_MODE_NAME (loop_vinfo->vector_mode));
-	}
-
-      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 (mode_i ==0)
+	    autodetected_vector_mode = loop_vinfo->vector_mode;
+	  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;
+	      }
+	};
+      opt_loop_vec_info loop_vinfo
+	= vect_analyze_loop_1 (loop, shared, next_vector_mode,
+			       vect_epilogues
+			       ? (loop_vec_info)first_loop_vinfo : NULL,
+			       &n_stmts, fatal, cb);
+      if (fatal)
+	break;
 
-      if (res)
+      if (loop_vinfo)
 	{
-	  LOOP_VINFO_VECTORIZABLE_P (loop_vinfo) = 1;
 	  vectorized_loops++;
 
 	  /* Once we hit the desired simdlen for the first time,
@@ -3084,33 +3085,44 @@ vect_analyze_loop (class loop *loop, vec_info_shared *shared)
 	      if (vinfos.is_empty ()
 		  && vect_joust_loop_vinfos (loop_vinfo, first_loop_vinfo))
 		{
-		  loop_vec_info main_loop_vinfo
-		    = vect_reanalyze_as_main_loop (loop_vinfo, &n_stmts);
-		  if (main_loop_vinfo == loop_vinfo)
-		    {
-		      delete first_loop_vinfo;
-		      first_loop_vinfo = opt_loop_vec_info::success (NULL);
-		    }
-		  else if (main_loop_vinfo
-			   && vect_joust_loop_vinfos (main_loop_vinfo,
-						      first_loop_vinfo))
+		  if (!vect_epilogues)
 		    {
 		      delete first_loop_vinfo;
 		      first_loop_vinfo = opt_loop_vec_info::success (NULL);
-		      delete loop_vinfo;
-		      loop_vinfo
-			= opt_loop_vec_info::success (main_loop_vinfo);
 		    }
 		  else
 		    {
 		      if (dump_enabled_p ())
 			dump_printf_loc (MSG_NOTE, vect_location,
-					 "***** No longer preferring vector"
-					 " mode %s after reanalyzing the loop"
-					 " as a main loop\n",
+					 "***** Reanalyzing as a main loop "
+					 "with vector mode %s\n",
 					 GET_MODE_NAME
-					   (main_loop_vinfo->vector_mode));
-		      delete main_loop_vinfo;
+					   (loop_vinfo->vector_mode));
+		      opt_loop_vec_info main_loop_vinfo
+			= vect_analyze_loop_1 (loop, shared,
+					       loop_vinfo->vector_mode,
+					       NULL, &n_stmts, fatal);
+		      if (main_loop_vinfo
+			  && vect_joust_loop_vinfos (main_loop_vinfo,
+						     first_loop_vinfo))
+			{
+			  delete first_loop_vinfo;
+			  first_loop_vinfo = opt_loop_vec_info::success (NULL);
+			  delete loop_vinfo;
+			  loop_vinfo
+			    = opt_loop_vec_info::success (main_loop_vinfo);
+			}
+		      else
+			{
+			  if (dump_enabled_p ())
+			    dump_printf_loc (MSG_NOTE, vect_location,
+					     "***** No longer preferring vector"
+					     " mode %s after reanalyzing the "
+					     " loop as a main loop\n",
+					     GET_MODE_NAME
+					       (loop_vinfo->vector_mode));
+			  delete main_loop_vinfo;
+			}
 		    }
 		}
 	    }
@@ -3159,16 +3171,6 @@ vect_analyze_loop (class loop *loop, vec_info_shared *shared)
 	  if (!simdlen && !vect_epilogues && !pick_lowest_cost_p)
 	    break;
 	}
-      else
-	{
-	  delete loop_vinfo;
-	  loop_vinfo = opt_loop_vec_info::success (NULL);
-	  if (fatal)
-	    {
-	      gcc_checking_assert (first_loop_vinfo == NULL);
-	      break;
-	    }
-	}
 
       /* Handle the case that the original loop can use partial
 	 vectorization, but want to only adopt it for the epilogue.
-- 
2.31.1

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2021-11-04 17:59 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-10-27 12:10 [PATCH] First refactor of vect_analyze_loop Richard Biener
2021-10-27 16:27 ` Richard Sandiford
2021-11-04 12:12   ` Richard Biener
2021-11-04 17:59     ` Richard Sandiford

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).