]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Add vector_costs::add_slp_cost grouping hook
authorRichard Biener <rguenther@suse.de>
Wed, 6 May 2026 08:39:18 +0000 (10:39 +0200)
committerRichard Biener <rguenther@suse.de>
Fri, 15 May 2026 08:50:28 +0000 (10:50 +0200)
The following simplifies the earlier RFC for making it easier
for the target to correlate multiple cost events created from
a single SLP operation.  Instead of changing where we record
costs this patch only adjusts the submission part.

Targets wanting to take advantage of this can implement
add_slp_cost and handle all or select cases and resort
to the default implementation to get add_stmt_cost events
for unhandled groups.

* tree-vectorizer.h (vector_costs::add_slp_cost): New.
* tree-vectorizer.cc (vector_costs::add_slp_cost): New
default version.
* tree-vect-slp.cc (add_slp_costs): Helper for dispatching
a cost vector in SLP chunks.
(vect_slp_analyze_operations): Adjust.
(li_cost_vec_cmp): Likewise.
(vect_bb_vectorization_profitable_p): Likewise.

gcc/tree-vect-slp.cc
gcc/tree-vectorizer.cc
gcc/tree-vectorizer.h

index 8a052c9baf147409b8d922e5cc395e5c2dd8c05a..ea49c32b7809f05df7762cd4c9e6f27c014edd9c 100644 (file)
@@ -9167,6 +9167,24 @@ vect_slp_prune_covered_roots (slp_tree node, hash_set<stmt_vec_info> &roots,
       vect_slp_prune_covered_roots (child, roots, visited);
 }
 
+/* Hand over COST_VEC to the target COSTS grouped by SLP node.  */
+
+static void
+add_slp_costs (vector_costs *costs, stmt_vector_for_cost& cost_vec)
+{
+  for (unsigned start = 0; start < cost_vec.length ();)
+    {
+      unsigned end = start + 1;
+      while (end < cost_vec.length ()
+            && cost_vec[start].node == cost_vec[end].node)
+       end++;
+      costs->add_slp_cost (cost_vec[start].node,
+                          array_slice<stmt_info_for_cost>
+                            (cost_vec.begin () + start, end - start));
+      start = end;
+    }
+}
+
 /* Analyze statements in SLP instances of VINFO.  Return true if the
    operations are supported. */
 
@@ -9252,7 +9270,7 @@ vect_slp_analyze_operations (vec_info *vinfo)
          i++;
          if (loop_vec_info loop_vinfo = dyn_cast<loop_vec_info> (vinfo))
            {
-             add_stmt_costs (loop_vinfo->vector_costs, &cost_vec);
+             add_slp_costs (loop_vinfo->vector_costs, cost_vec);
              cost_vec.release ();
            }
          else
@@ -9520,7 +9538,7 @@ vect_bb_slp_scalar_cost (bb_vec_info vinfo,
 /* Comparator for the loop-index sorted cost vectors.  */
 
 static int
-li_cost_vec_cmp (const void *a_, const void *b_)
+li_cost_vec_cmp (const void *a_, const void *b_, void *)
 {
   auto *a = (const std::pair<unsigned, stmt_info_for_cost *> *)a_;
   auto *b = (const std::pair<unsigned, stmt_info_for_cost *> *)b_;
@@ -9610,8 +9628,8 @@ vect_bb_vectorization_profitable_p (bb_vec_info bb_vinfo,
        l = gimple_bb (cost->stmt_info->stmt)->loop_father->num;
       li_vector_costs.quick_push (std::make_pair (l, cost));
     }
-  li_scalar_costs.qsort (li_cost_vec_cmp);
-  li_vector_costs.qsort (li_cost_vec_cmp);
+  li_scalar_costs.stablesort (li_cost_vec_cmp, NULL);
+  li_vector_costs.stablesort (li_cost_vec_cmp, NULL);
 
   /* Now cost the portions individually.  */
   unsigned vi = 0;
@@ -9651,13 +9669,15 @@ vect_bb_vectorization_profitable_p (bb_vec_info bb_vinfo,
 
       /* Complete the target-specific vector cost calculation.  */
       class vector_costs *vect_target_cost_data = init_cost (bb_vinfo, false);
+      auto_vec<stmt_info_for_cost> tem;
       do
        {
-         add_stmt_cost (vect_target_cost_data, li_vector_costs[vi].second);
+         tem.safe_push (*li_vector_costs[vi].second);
          vi++;
        }
       while (vi < li_vector_costs.length ()
             && li_vector_costs[vi].first == vl);
+      add_slp_costs (vect_target_cost_data, tem);
       vect_target_cost_data->finish_cost (scalar_target_cost_data);
       vec_prologue_cost = vect_target_cost_data->prologue_cost ();
       vec_inside_cost = vect_target_cost_data->body_cost ();
index 9e71f71fab7355d4efa071a908a9f60315d13184..205a07b0be57f81737362339649c42d15f763d90 100644 (file)
@@ -1845,6 +1845,17 @@ vector_costs::add_stmt_cost (int count, vect_cost_for_stmt kind,
   return record_stmt_cost (stmt_info, where, cost);
 }
 
+unsigned int
+vector_costs::add_slp_cost (slp_tree,
+                           const array_slice<stmt_info_for_cost> &cost_vec)
+{
+  unsigned int sum = 0;
+  for (auto item : cost_vec)
+    sum += ::add_stmt_cost (this, item.count, item.kind, item.stmt_info,
+                           item.node, item.vectype, item.misalign, item.where);
+  return sum;
+}
+
 /* See the comment above the declaration for details.  */
 
 void
index de50ed3277c475c130cbe223ade6501a7bb22045..3a01e1be0f15dcf982eeaed2177915ad6f55e473 100644 (file)
@@ -1777,6 +1777,11 @@ public:
                                      tree vectype, int misalign,
                                      vect_cost_model_location where);
 
+  /* Update the costs in response to adding costs in V which are all from
+     vectorizing NODE to the respective part.  */
+  virtual unsigned int add_slp_cost (slp_tree node,
+                                    const array_slice<stmt_info_for_cost> &v);
+
   /* Finish calculating the cost of the code.  The results can be
      read back using the functions below.