refactor SLP analysis
authorRichard Biener <rguenther@suse.de>
Fri, 6 Nov 2020 11:44:47 +0000 (12:44 +0100)
committerRichard Biener <rguenther@suse.de>
Fri, 6 Nov 2020 12:33:19 +0000 (13:33 +0100)
This passes down the graph entry kind down to vect_analyze_slp_instance
which simplifies it and makes it a shallow wrapper around
vect_build_slp_instance.

2020-11-06  Richard Biener  <rguenther@suse.de>

* tree-vect-slp.c (vect_analyze_slp): Pass down the
SLP graph entry kind.
(vect_analyze_slp_instance): Simplify.
(vect_build_slp_instance): Adjust.
(vect_slp_check_for_constructors): Perform more
eligibility checks here.

gcc/tree-vect-slp.c

index 4d1f17bd3fa22daf778e56bcc32d045931ed32cf..88e637e30dc3c596da24393b2ac8a4b6f4e3f392 100644 (file)
@@ -2174,7 +2174,8 @@ calculate_unrolling_factor (poly_uint64 nunits, unsigned int group_size)
 static bool
 vect_analyze_slp_instance (vec_info *vinfo,
                           scalar_stmts_to_slp_tree_map_t *bst_map,
-                          stmt_vec_info stmt_info, unsigned max_tree_size);
+                          stmt_vec_info stmt_info, slp_instance_kind kind,
+                          unsigned max_tree_size);
 
 /* Analyze an SLP instance starting from SCALAR_STMTS which are a group
    of KIND.  Return true if successful.  */
@@ -2375,7 +2376,7 @@ vect_build_slp_instance (vec_info *vinfo,
              stmt_vec_info rest = vect_split_slp_store_group (stmt_info,
                                                               group1_size);
              bool res = vect_analyze_slp_instance (vinfo, bst_map, stmt_info,
-                                                   max_tree_size);
+                                                   kind, max_tree_size);
              /* Split the rest at the failure point and possibly
                 re-analyze the remaining matching part if it has
                 at least two lanes.  */
@@ -2386,14 +2387,14 @@ vect_build_slp_instance (vec_info *vinfo,
                  stmt_vec_info rest2 = rest;
                  rest = vect_split_slp_store_group (rest, i - group1_size);
                  if (i - group1_size > 1)
-                   res |= vect_analyze_slp_instance (vinfo, bst_map,
-                                                     rest2, max_tree_size);
+                   res |= vect_analyze_slp_instance (vinfo, bst_map, rest2,
+                                                     kind, max_tree_size);
                }
              /* Re-analyze the non-matching tail if it has at least
                 two lanes.  */
              if (i + 1 < group_size)
                res |= vect_analyze_slp_instance (vinfo, bst_map,
-                                                 rest, max_tree_size);
+                                                 rest, kind, max_tree_size);
              return res;
            }
        }
@@ -2418,10 +2419,10 @@ vect_build_slp_instance (vec_info *vinfo,
          DR_GROUP_GAP (stmt_info) = 0;
 
          bool res = vect_analyze_slp_instance (vinfo, bst_map, stmt_info,
-                                               max_tree_size);
+                                               kind, max_tree_size);
          if (i + 1 < group_size)
            res |= vect_analyze_slp_instance (vinfo, bst_map,
-                                             rest, max_tree_size);
+                                             rest, kind, max_tree_size);
 
          return res;
        }
@@ -2444,59 +2445,34 @@ vect_build_slp_instance (vec_info *vinfo,
 static bool
 vect_analyze_slp_instance (vec_info *vinfo,
                           scalar_stmts_to_slp_tree_map_t *bst_map,
-                          stmt_vec_info stmt_info, unsigned max_tree_size)
+                          stmt_vec_info stmt_info,
+                          slp_instance_kind kind,
+                          unsigned max_tree_size)
 {
-  unsigned int group_size;
   unsigned int i;
-  struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info);
   vec<stmt_vec_info> scalar_stmts;
-  slp_instance_kind kind;
 
   if (is_a <bb_vec_info> (vinfo))
     vect_location = stmt_info->stmt;
-  if (STMT_VINFO_GROUPED_ACCESS (stmt_info))
-    {
-      kind = slp_inst_kind_store;
-      group_size = DR_GROUP_SIZE (stmt_info);
-    }
-  else if (!dr && REDUC_GROUP_FIRST_ELEMENT (stmt_info))
-    {
-      kind = slp_inst_kind_reduc_chain;
-      gcc_assert (is_a <loop_vec_info> (vinfo));
-      group_size = REDUC_GROUP_SIZE (stmt_info);
-    }
-  else if (is_gimple_assign (stmt_info->stmt)
-           && gimple_assign_rhs_code (stmt_info->stmt) == CONSTRUCTOR)
-    {
-      kind = slp_inst_kind_ctor;
-      group_size = CONSTRUCTOR_NELTS (gimple_assign_rhs1 (stmt_info->stmt));
-    }
-  else
-    {
-      kind = slp_inst_kind_reduc_group;
-      gcc_assert (is_a <loop_vec_info> (vinfo));
-      group_size = as_a <loop_vec_info> (vinfo)->reductions.length ();
-    }
 
-  /* Create a node (a root of the SLP tree) for the packed grouped stores.  */
-  scalar_stmts.create (group_size);
   stmt_vec_info next_info = stmt_info;
-  if (STMT_VINFO_GROUPED_ACCESS (stmt_info))
+  if (kind == slp_inst_kind_store)
     {
-      /* Collect the stores and store them in SLP_TREE_SCALAR_STMTS.  */
+      /* Collect the stores and store them in scalar_stmts.  */
+      scalar_stmts.create (DR_GROUP_SIZE (stmt_info));
       while (next_info)
        {
-         scalar_stmts.safe_push (vect_stmt_to_vectorize (next_info));
+         scalar_stmts.quick_push (vect_stmt_to_vectorize (next_info));
          next_info = DR_GROUP_NEXT_ELEMENT (next_info);
        }
     }
-  else if (!dr && REDUC_GROUP_FIRST_ELEMENT (stmt_info))
+  else if (kind == slp_inst_kind_reduc_chain)
     {
-      /* Collect the reduction stmts and store them in
-        SLP_TREE_SCALAR_STMTS.  */
+      /* Collect the reduction stmts and store them in scalar_stmts.  */
+      scalar_stmts.create (REDUC_GROUP_SIZE (stmt_info));
       while (next_info)
        {
-         scalar_stmts.safe_push (vect_stmt_to_vectorize (next_info));
+         scalar_stmts.quick_push (vect_stmt_to_vectorize (next_info));
          next_info = REDUC_GROUP_NEXT_ELEMENT (next_info);
        }
       /* Mark the first element of the reduction chain as reduction to properly
@@ -2511,30 +2487,23 @@ vect_analyze_slp_instance (vec_info *vinfo,
     {
       tree rhs = gimple_assign_rhs1 (stmt_info->stmt);
       tree val;
+      scalar_stmts.create (CONSTRUCTOR_NELTS (rhs));
       FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (rhs), i, val)
        {
-         if (TREE_CODE (val) == SSA_NAME)
-           {
-             gimple* def = SSA_NAME_DEF_STMT (val);
-             stmt_vec_info def_info = vinfo->lookup_stmt (def);
-             /* Value is defined in another basic block.  */
-             if (!def_info)
-               return false;
-             def_info = vect_stmt_to_vectorize (def_info);
-             scalar_stmts.safe_push (def_info);
-           }
-         else
-           return false;
+         stmt_vec_info def_info = vinfo->lookup_def (val);
+         def_info = vect_stmt_to_vectorize (def_info);
+         scalar_stmts.quick_push (def_info);
        }
       if (dump_enabled_p ())
        dump_printf_loc (MSG_NOTE, vect_location,
                         "Analyzing vectorizable constructor: %G\n",
                         stmt_info->stmt);
     }
-  else
+  else if (kind == slp_inst_kind_reduc_group)
     {
       /* Collect reduction statements.  */
       vec<stmt_vec_info> reductions = as_a <loop_vec_info> (vinfo)->reductions;
+      scalar_stmts.create (reductions.length ());
       for (i = 0; reductions.iterate (i, &next_info); i++)
        if (STMT_VINFO_RELEVANT_P (next_info)
            || STMT_VINFO_LIVE_P (next_info))
@@ -2543,13 +2512,16 @@ vect_analyze_slp_instance (vec_info *vinfo,
       if (scalar_stmts.length () < 2)
        return false;
     }
+  else
+    gcc_unreachable ();
 
   /* Build the tree for the SLP instance.  */
   bool res = vect_build_slp_instance (vinfo, kind, scalar_stmts,
                                      kind == slp_inst_kind_ctor
                                      ? stmt_info : NULL,
-                                     max_tree_size,
-                                     bst_map, stmt_info);
+                                     max_tree_size, bst_map,
+                                     kind == slp_inst_kind_store
+                                     ? stmt_info : NULL);
 
   /* ???  If this is slp_inst_kind_store and the above succeeded here's
      where we should do store group splitting.  */
@@ -2573,7 +2545,10 @@ vect_analyze_slp (vec_info *vinfo, unsigned max_tree_size)
 
   /* Find SLP sequences starting from groups of grouped stores.  */
   FOR_EACH_VEC_ELT (vinfo->grouped_stores, i, first_element)
-    vect_analyze_slp_instance (vinfo, bst_map, first_element, max_tree_size);
+    vect_analyze_slp_instance (vinfo, bst_map, first_element,
+                              STMT_VINFO_GROUPED_ACCESS (first_element)
+                              ? slp_inst_kind_store : slp_inst_kind_ctor,
+                              max_tree_size);
 
   if (loop_vec_info loop_vinfo = dyn_cast <loop_vec_info> (vinfo))
     {
@@ -2583,6 +2558,7 @@ vect_analyze_slp (vec_info *vinfo, unsigned max_tree_size)
            && ! STMT_VINFO_LIVE_P (first_element))
          ;
        else if (! vect_analyze_slp_instance (vinfo, bst_map, first_element,
+                                             slp_inst_kind_reduc_chain,
                                              max_tree_size))
          {
            /* Dissolve reduction chain group.  */
@@ -2604,7 +2580,7 @@ vect_analyze_slp (vec_info *vinfo, unsigned max_tree_size)
       /* Find SLP sequences starting from groups of reductions.  */
       if (loop_vinfo->reductions.length () > 1)
        vect_analyze_slp_instance (vinfo, bst_map, loop_vinfo->reductions[0],
-                                  max_tree_size);
+                                  slp_inst_kind_reduc_group, max_tree_size);
     }
 
   /* The map keeps a reference on SLP nodes built, release that.  */
@@ -4033,6 +4009,15 @@ vect_slp_check_for_constructors (bb_vec_info bb_vinfo)
          || uniform_vector_p (rhs))
        continue;
 
+      unsigned j;
+      tree val;
+      FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (rhs), j, val)
+       if (TREE_CODE (val) != SSA_NAME
+           || !bb_vinfo->lookup_def (val))
+         break;
+      if (j != CONSTRUCTOR_NELTS (rhs))
+       continue;
+
       stmt_vec_info stmt_info = bb_vinfo->lookup_stmt (assign);
       BB_VINFO_GROUPED_STORES (bb_vinfo).safe_push (stmt_info);
     }