https://gcc.gnu.org/g:1d91dbe68778ac2496469320d8bfcf0c3099b675
commit r17-526-g1d91dbe68778ac2496469320d8bfcf0c3099b675 Author: Richard Biener <[email protected]> Date: Wed May 6 10:39:18 2026 +0200 Add vector_costs::add_slp_cost grouping hook 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. Diff: --- gcc/tree-vect-slp.cc | 30 +++++++++++++++++++++++++----- gcc/tree-vectorizer.cc | 11 +++++++++++ gcc/tree-vectorizer.h | 5 +++++ 3 files changed, 41 insertions(+), 5 deletions(-) diff --git a/gcc/tree-vect-slp.cc b/gcc/tree-vect-slp.cc index 8a052c9baf14..ea49c32b7809 100644 --- a/gcc/tree-vect-slp.cc +++ b/gcc/tree-vect-slp.cc @@ -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 (); diff --git a/gcc/tree-vectorizer.cc b/gcc/tree-vectorizer.cc index 9e71f71fab73..205a07b0be57 100644 --- a/gcc/tree-vectorizer.cc +++ b/gcc/tree-vectorizer.cc @@ -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 diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h index de50ed3277c4..3a01e1be0f15 100644 --- a/gcc/tree-vectorizer.h +++ b/gcc/tree-vectorizer.h @@ -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.
