This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Avoid computing scalar iteration cost multiple times


This avoids doing $subject in the vectorizer.

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

Richard.

2015-06-22  Richard Biener  <rguenther@suse.de>

	* tree-vectorizer.h (_loop_vec_info): Add scalar_cost_vec
	and single_scalar_iteration_cost members.
	(LOOP_VINFO_SCALAR_ITERATION_COST): New.
	(LOOP_VINFO_SINGLE_SCALAR_ITERATION_COST): Likewise.
	(vect_get_single_scalar_iteration_cost): Remove.
	* tree-vect-data-refs.c (vect_peeling_hash_get_lowest_cost):
	Use LOOP_VINFO_SCALAR_ITERATION_COST.
	* tree-vect-loop.c (destroy_loop_vec_info): Free
	scalar_cost_vec.
	(vect_get_single_scalar_iteration_cost): Compute result into
	LOOP_VINFO_SINGLE_SCALAR_ITERATION_COST and
	LOOP_VINFO_SCALAR_ITERATION_COST.  Make static.
	(vect_analyze_loop_2): Call vect_get_single_scalar_iteration_cost.
	(vect_estimate_min_profitable_iters): Use them.

Index: gcc/tree-vect-data-refs.c
===================================================================
--- gcc/tree-vect-data-refs.c	(revision 224603)
+++ gcc/tree-vect-data-refs.c	(working copy)
@@ -1165,11 +1165,10 @@ vect_peeling_hash_get_lowest_cost (_vect
       SET_DR_MISALIGNMENT (dr, save_misalignment);
     }
 
-  auto_vec<stmt_info_for_cost> scalar_cost_vec;
-  vect_get_single_scalar_iteration_cost (loop_vinfo, &scalar_cost_vec);
   outside_cost += vect_get_known_peeling_cost
     (loop_vinfo, elem->npeel, &dummy,
-     &scalar_cost_vec, &prologue_cost_vec, &epilogue_cost_vec);
+     &LOOP_VINFO_SCALAR_ITERATION_COST (loop_vinfo),
+     &prologue_cost_vec, &epilogue_cost_vec);
 
   /* Prologue and epilogue costs are added to the target model later.
      These costs depend only on the scalar iteration cost, the
Index: gcc/tree-vect-loop.c
===================================================================
--- gcc/tree-vect-loop.c	(revision 224603)
+++ gcc/tree-vect-loop.c	(working copy)
@@ -1095,12 +1095,82 @@ destroy_loop_vec_info (loop_vec_info loo
   LOOP_VINFO_PEELING_HTAB (loop_vinfo) = NULL;
 
   destroy_cost_data (LOOP_VINFO_TARGET_COST_DATA (loop_vinfo));
+  loop_vinfo->scalar_cost_vec.release ();
 
   free (loop_vinfo);
   loop->aux = NULL;
 }
 
 
+/* Calculate the cost of one scalar iteration of the loop.  */
+static void
+vect_get_single_scalar_iteration_cost (loop_vec_info loop_vinfo)
+{
+  struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
+  basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
+  int nbbs = loop->num_nodes, factor, scalar_single_iter_cost = 0;
+  int innerloop_iters, i;
+
+  /* Count statements in scalar loop.  Using this as scalar cost for a single
+     iteration for now.
+
+     TODO: Add outer loop support.
+
+     TODO: Consider assigning different costs to different scalar
+     statements.  */
+
+  /* FORNOW.  */
+  innerloop_iters = 1;
+  if (loop->inner)
+    innerloop_iters = 50; /* FIXME */
+
+  for (i = 0; i < nbbs; i++)
+    {
+      gimple_stmt_iterator si;
+      basic_block bb = bbs[i];
+
+      if (bb->loop_father == loop->inner)
+        factor = innerloop_iters;
+      else
+        factor = 1;
+
+      for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
+        {
+          gimple stmt = gsi_stmt (si);
+          stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
+
+          if (!is_gimple_assign (stmt) && !is_gimple_call (stmt))
+            continue;
+
+          /* Skip stmts that are not vectorized inside the loop.  */
+          if (stmt_info
+              && !STMT_VINFO_RELEVANT_P (stmt_info)
+              && (!STMT_VINFO_LIVE_P (stmt_info)
+                  || !VECTORIZABLE_CYCLE_DEF (STMT_VINFO_DEF_TYPE (stmt_info)))
+	      && !STMT_VINFO_IN_PATTERN_P (stmt_info))
+            continue;
+
+	  vect_cost_for_stmt kind;
+          if (STMT_VINFO_DATA_REF (vinfo_for_stmt (stmt)))
+            {
+              if (DR_IS_READ (STMT_VINFO_DATA_REF (vinfo_for_stmt (stmt))))
+               kind = scalar_load;
+             else
+               kind = scalar_store;
+            }
+          else
+            kind = scalar_stmt;
+
+	  scalar_single_iter_cost
+	    += record_stmt_cost (&LOOP_VINFO_SCALAR_ITERATION_COST (loop_vinfo),
+				 factor, kind, NULL, 0, vect_prologue);
+        }
+    }
+  LOOP_VINFO_SINGLE_SCALAR_ITERATION_COST (loop_vinfo)
+    = scalar_single_iter_cost;
+}
+
+
 /* Function vect_analyze_loop_1.
 
    Apply a set of analyses on LOOP, and create a loop_vec_info struct
@@ -1834,6 +1904,9 @@ vect_analyze_loop_2 (loop_vec_info loop_
       return false;
     }
 
+  /* Compute the scalar iteration cost.  */
+  vect_get_single_scalar_iteration_cost (loop_vinfo);
+
   /* This pass will decide on using loop versioning and/or loop peeling in
      order to enhance the alignment of data references in the loop.  */
 
@@ -2706,74 +2779,6 @@ vect_force_simple_reduction (loop_vec_in
 				     double_reduc, true);
 }
 
-/* Calculate the cost of one scalar iteration of the loop.  */
-int
-vect_get_single_scalar_iteration_cost (loop_vec_info loop_vinfo,
-				       stmt_vector_for_cost *scalar_cost_vec)
-{
-  struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
-  basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
-  int nbbs = loop->num_nodes, factor, scalar_single_iter_cost = 0;
-  int innerloop_iters, i;
-
-  /* Count statements in scalar loop.  Using this as scalar cost for a single
-     iteration for now.
-
-     TODO: Add outer loop support.
-
-     TODO: Consider assigning different costs to different scalar
-     statements.  */
-
-  /* FORNOW.  */
-  innerloop_iters = 1;
-  if (loop->inner)
-    innerloop_iters = 50; /* FIXME */
-
-  for (i = 0; i < nbbs; i++)
-    {
-      gimple_stmt_iterator si;
-      basic_block bb = bbs[i];
-
-      if (bb->loop_father == loop->inner)
-        factor = innerloop_iters;
-      else
-        factor = 1;
-
-      for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
-        {
-          gimple stmt = gsi_stmt (si);
-          stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
-
-          if (!is_gimple_assign (stmt) && !is_gimple_call (stmt))
-            continue;
-
-          /* Skip stmts that are not vectorized inside the loop.  */
-          if (stmt_info
-              && !STMT_VINFO_RELEVANT_P (stmt_info)
-              && (!STMT_VINFO_LIVE_P (stmt_info)
-                  || !VECTORIZABLE_CYCLE_DEF (STMT_VINFO_DEF_TYPE (stmt_info)))
-	      && !STMT_VINFO_IN_PATTERN_P (stmt_info))
-            continue;
-
-	  vect_cost_for_stmt kind;
-          if (STMT_VINFO_DATA_REF (vinfo_for_stmt (stmt)))
-            {
-              if (DR_IS_READ (STMT_VINFO_DATA_REF (vinfo_for_stmt (stmt))))
-               kind = scalar_load;
-             else
-               kind = scalar_store;
-            }
-          else
-            kind = scalar_stmt;
-
-	  scalar_single_iter_cost
-	    += record_stmt_cost (scalar_cost_vec, factor, kind,
-				 NULL, 0, vect_prologue);
-        }
-    }
-  return scalar_single_iter_cost;
-}
-
 /* Calculate cost of peeling the loop PEEL_ITERS_PROLOGUE times.  */
 int
 vect_get_known_peeling_cost (loop_vec_info loop_vinfo, int peel_iters_prologue,
@@ -2901,9 +2906,8 @@ vect_estimate_min_profitable_iters (loop
      TODO: Consider assigning different costs to different scalar
      statements.  */
 
-  auto_vec<stmt_info_for_cost> scalar_cost_vec;
   scalar_single_iter_cost
-     = vect_get_single_scalar_iteration_cost (loop_vinfo, &scalar_cost_vec);
+    = LOOP_VINFO_SINGLE_SCALAR_ITERATION_COST (loop_vinfo);
 
   /* Add additional cost for the peeled instructions in prologue and epilogue
      loop.
@@ -2941,7 +2945,7 @@ vect_estimate_min_profitable_iters (loop
 			    NULL, 0, vect_epilogue);
       stmt_info_for_cost *si;
       int j;
-      FOR_EACH_VEC_ELT (scalar_cost_vec, j, si)
+      FOR_EACH_VEC_ELT (LOOP_VINFO_SCALAR_ITERATION_COST (loop_vinfo), j, si)
 	{
 	  struct _stmt_vec_info *stmt_info
 	    = si->stmt ? vinfo_for_stmt (si->stmt) : NULL;
@@ -2968,7 +2972,8 @@ vect_estimate_min_profitable_iters (loop
 
       (void) vect_get_known_peeling_cost (loop_vinfo, peel_iters_prologue,
 					  &peel_iters_epilogue,
-					  &scalar_cost_vec,
+					  &LOOP_VINFO_SCALAR_ITERATION_COST
+					    (loop_vinfo),
 					  &prologue_cost_vec,
 					  &epilogue_cost_vec);
 
Index: gcc/tree-vectorizer.h
===================================================================
--- gcc/tree-vectorizer.h	(revision 224603)
+++ gcc/tree-vectorizer.h	(working copy)
@@ -328,6 +328,12 @@ typedef struct _loop_vec_info {
   /* Hash table used to choose the best peeling option.  */
   hash_table<peel_info_hasher> *peeling_htab;
 
+  /* Cost vector for a single scalar iteration.  */
+  vec<stmt_info_for_cost> scalar_cost_vec;
+
+  /* Cost of a single scalar iteration.  */
+  int single_scalar_iteration_cost;
+
   /* Cost data used by the target cost model.  */
   void *target_cost_data;
 
@@ -406,6 +412,8 @@ typedef struct _loop_vec_info {
 #define LOOP_VINFO_PEELING_FOR_NITER(L)    (L)->peeling_for_niter
 #define LOOP_VINFO_NO_DATA_DEPENDENCIES(L) (L)->no_data_dependencies
 #define LOOP_VINFO_SCALAR_LOOP(L)	   (L)->scalar_loop
+#define LOOP_VINFO_SCALAR_ITERATION_COST(L) (L)->scalar_cost_vec
+#define LOOP_VINFO_SINGLE_SCALAR_ITERATION_COST(L) (L)->single_scalar_iteration_cost
 
 #define LOOP_REQUIRES_VERSIONING_FOR_ALIGNMENT(L) \
   ((L)->may_misalign_stmts.length () > 0)
@@ -1101,8 +1109,6 @@ extern int vect_get_known_peeling_cost (
 					stmt_vector_for_cost *,
 					stmt_vector_for_cost *,
 					stmt_vector_for_cost *);
-extern int vect_get_single_scalar_iteration_cost (loop_vec_info,
-						  stmt_vector_for_cost *);
 
 /* In tree-vect-slp.c.  */
 extern void vect_free_slp_instance (slp_instance);


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]