refactor SLP constant insertion and provde entry insert helper
authorRichard Biener <rguenther@suse.de>
Fri, 3 Jul 2020 08:09:39 +0000 (10:09 +0200)
committerRichard Biener <rguenther@suse.de>
Fri, 3 Jul 2020 09:29:16 +0000 (11:29 +0200)
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.

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
gcc/tree-vect-stmts.c
gcc/tree-vectorizer.c
gcc/tree-vectorizer.h

index eff68f7..727eba0 100644 (file)
@@ -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
index d68547e..9228f9c 100644 (file)
@@ -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
index 78d9da6..26a1846 100644 (file)
@@ -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
index dfe88cc..7c6de83 100644 (file)
@@ -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;