refactor SLP constant insertion and provde entry insert helper

Message ID nycvar.YFH.7.76.2007031015510.4397@zhemvz.fhfr.qr
State New
Headers show
Series
  • refactor SLP constant insertion and provde entry insert helper
Related show

Commit Message

Richard Biener July 3, 2020, 8:16 a.m.
This provides helpers to insert stmts on region entry abstracted
from loop/basic-block split out from vec_init_vector and used
from the SLP constant code generation path.  The SLP constant
code generation path is also changed to avoid needless SSA
copying since we can store VECTOR_CSTs directly in the vectorized
defs array, improving the IL from the vectorizer.

Bootstrap & regtest running on x86_64-unknown-linux-gnu.

2020-07-03  Richard Biener  <rguenther@suse.de>

	* tree-vectorizer.h (vec_info::insert_on_entry): New.
	(vec_info::insert_seq_on_entry): Likewise.
	* tree-vectorizer.c (vec_info::insert_on_entry): Implement.
	(vec_info::insert_seq_on_entry): Likewise.
	* tree-vect-stmts.c (vect_init_vector_1): Use
	vec_info::insert_on_entry.
	(vect_finish_stmt_generation): Set modified bit after
	adjusting VUSE.
	* tree-vect-slp.c (vect_create_constant_vectors): Simplify
	by using vec_info::insert_seq_on_entry and bypassing
	vec_init_vector.
	(vect_schedule_slp_instance): Deal with all-constant
	children later.
---
 gcc/tree-vect-slp.c   | 35 +++++++++++++++--------------------
 gcc/tree-vect-stmts.c | 25 ++-----------------------
 gcc/tree-vectorizer.c | 40 ++++++++++++++++++++++++++++++++++++++++
 gcc/tree-vectorizer.h |  2 ++
 4 files changed, 59 insertions(+), 43 deletions(-)

-- 
2.26.2

Patch

diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c
index eff68f76bc3..727eba0b12f 100644
--- a/gcc/tree-vect-slp.c
+++ b/gcc/tree-vect-slp.c
@@ -3786,26 +3786,20 @@  vect_create_constant_vectors (vec_info *vinfo, slp_tree op_node)
 					      permute_results);
 		  vec_cst = permute_results[number_of_vectors - j - 1];
 		}
-	      tree init;
-	      if (insert_after)
+	      if (!gimple_seq_empty_p (ctor_seq))
 		{
-		  gimple_stmt_iterator gsi = gsi_for_stmt (insert_after->stmt);
-		  /* vect_init_vector inserts before.  */
-		  gsi_next (&gsi);
-		  init = vect_init_vector (vinfo, NULL, vec_cst,
-					   vector_type, &gsi);
-		}
-	      else
-		init = vect_init_vector (vinfo, NULL, vec_cst,
-					 vector_type, NULL);
-	      if (ctor_seq != NULL)
-		{
-		  gimple_stmt_iterator gsi
-		    = gsi_for_stmt (SSA_NAME_DEF_STMT (init));
-		  gsi_insert_seq_before (&gsi, ctor_seq, GSI_SAME_STMT);
+		  if (insert_after)
+		    {
+		      gimple_stmt_iterator gsi
+			= gsi_for_stmt (insert_after->stmt);
+		      gsi_insert_seq_after (&gsi, ctor_seq,
+					    GSI_CONTINUE_LINKING);
+		    }
+		  else
+		    vinfo->insert_seq_on_entry (NULL, ctor_seq);
 		  ctor_seq = NULL;
 		}
-	      voprnds.quick_push (init);
+	      voprnds.quick_push (vec_cst);
 	      insert_after = NULL;
               number_of_places_left_in_vector = nunits;
 	      constant_p = true;
@@ -4418,10 +4412,11 @@  vect_schedule_slp_instance (vec_info *vinfo,
 		      || vect_stmt_dominates_stmt_p (last_stmt, vstmt))
 		    last_stmt = vstmt;
 		}
-	    /* This can happen when all children are pre-existing vectors.  */
-	    if (!last_stmt)
-	      last_stmt = vect_find_first_scalar_stmt_in_slp (node)->stmt;
 	  }
+      /* This can happen when all children are pre-existing vectors or
+	 constants.  */
+      if (!last_stmt)
+	last_stmt = vect_find_first_scalar_stmt_in_slp (node)->stmt;
       if (is_a <gphi *> (last_stmt))
 	si = gsi_after_labels (gimple_bb (last_stmt));
       else
diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c
index d68547ed1b5..9228f9cde4a 100644
--- a/gcc/tree-vect-stmts.c
+++ b/gcc/tree-vect-stmts.c
@@ -1315,29 +1315,7 @@  vect_init_vector_1 (vec_info *vinfo, stmt_vec_info stmt_vinfo, gimple *new_stmt,
   if (gsi)
     vect_finish_stmt_generation (vinfo, stmt_vinfo, new_stmt, gsi);
   else
-    {
-      loop_vec_info loop_vinfo = dyn_cast <loop_vec_info> (vinfo);
-
-      if (loop_vinfo)
-        {
-	  class loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
-	  basic_block new_bb;
-	  edge pe;
-
-	  if (stmt_vinfo && nested_in_vect_loop_p (loop, stmt_vinfo))
-	    loop = loop->inner;
-
-	  pe = loop_preheader_edge (loop);
-          new_bb = gsi_insert_on_edge_immediate (pe, new_stmt);
-          gcc_assert (!new_bb);
-	}
-      else
-       {
-          bb_vec_info bb_vinfo = dyn_cast <bb_vec_info> (vinfo);
-	  gimple_stmt_iterator gsi_region_begin = bb_vinfo->region_begin;
-	  gsi_insert_before (&gsi_region_begin, new_stmt, GSI_SAME_STMT);
-       }
-    }
+    vinfo->insert_on_entry (stmt_vinfo, new_stmt);
 
   if (dump_enabled_p ())
     dump_printf_loc (MSG_NOTE, vect_location,
@@ -1592,6 +1570,7 @@  vect_finish_stmt_generation (vec_info *vinfo,
 	{
 	  tree vdef = gimple_vdef (at_stmt);
 	  gimple_set_vuse (vec_stmt, gimple_vuse (at_stmt));
+	  gimple_set_modified (vec_stmt, true);
 	  /* If we have an SSA vuse and insert a store, update virtual
 	     SSA form to avoid triggering the renamer.  Do so only
 	     if we can easily see all uses - which is what almost always
diff --git a/gcc/tree-vectorizer.c b/gcc/tree-vectorizer.c
index 78d9da689c8..26a184696aa 100644
--- a/gcc/tree-vectorizer.c
+++ b/gcc/tree-vectorizer.c
@@ -625,6 +625,46 @@  vec_info::replace_stmt (gimple_stmt_iterator *gsi, stmt_vec_info stmt_info,
   gsi_replace (gsi, new_stmt, true);
 }
 
+/* Insert stmts in SEQ on the VEC_INFO region entry.  If CONTEXT is
+   not NULL it specifies whether to use the sub-region entry
+   determined by it, currently used for loop vectorization to insert
+   on the inner loop entry vs. the outer loop entry.  */
+
+void
+vec_info::insert_seq_on_entry (stmt_vec_info context, gimple_seq seq)
+{
+  if (loop_vec_info loop_vinfo = dyn_cast <loop_vec_info> (this))
+    {
+      class loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
+      basic_block new_bb;
+      edge pe;
+
+      if (context && nested_in_vect_loop_p (loop, context))
+	loop = loop->inner;
+
+      pe = loop_preheader_edge (loop);
+      new_bb = gsi_insert_seq_on_edge_immediate (pe, seq);
+      gcc_assert (!new_bb);
+    }
+  else
+    {
+      bb_vec_info bb_vinfo = as_a <bb_vec_info> (this);
+      gimple_stmt_iterator gsi_region_begin = bb_vinfo->region_begin;
+      gsi_insert_seq_before (&gsi_region_begin, seq, GSI_SAME_STMT);
+    }
+}
+
+/* Like insert_seq_on_entry but just inserts the single stmt NEW_STMT.  */
+
+void
+vec_info::insert_on_entry (stmt_vec_info context, gimple *new_stmt)
+{
+  gimple_seq seq = NULL;
+  gimple_stmt_iterator gsi = gsi_start (seq);
+  gsi_insert_before_without_update (&gsi, new_stmt, GSI_SAME_STMT);
+  insert_seq_on_entry (context, seq);
+}
+
 /* Create and initialize a new stmt_vec_info struct for STMT.  */
 
 stmt_vec_info
diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h
index dfe88cc8af3..7c6de8397b3 100644
--- a/gcc/tree-vectorizer.h
+++ b/gcc/tree-vectorizer.h
@@ -334,6 +334,8 @@  public:
   void move_dr (stmt_vec_info, stmt_vec_info);
   void remove_stmt (stmt_vec_info);
   void replace_stmt (gimple_stmt_iterator *, stmt_vec_info, gimple *);
+  void insert_on_entry (stmt_vec_info, gimple *);
+  void insert_seq_on_entry (stmt_vec_info, gimple_seq);
 
   /* The type of vectorization.  */
   vec_kind kind;