HI Robin: I was a bit concerned about the stmt_vec_info -> slp_tree hash map at first, but I realized that it’s just a temporary hack, so LGTM :)
On Thu, Jul 24, 2025 at 9:09 PM Richard Biener <richard.guent...@gmail.com> wrote: > > On Tue, Jul 22, 2025 at 11:46 AM Robin Dapp <rdapp....@gmail.com> wrote: > > > > Hi, > > > > This patch prepares the dynamic LMUL vector costing to use the coming > > SLP_TREE_TYPE instead of the (to-be-removed) STMT_VINFO_TYPE. > > > > Even though the whole approach should be reviewed and adjusted at some > > point, the patch chooses the path of least resistance and uses a hash > > map for the stmt_info -> slp node relationship. A node is mapped to the > > accompanying stmt_info during add_stmt_cost. In finish_cost we go > > through all statements as before and obtain the corresponding slp nodes > > as well as their types. > > > > This allows us to operate largely as before. We don't yet do the switch > > over from STMT_VINFO_TYPE to SLP_TREE_TYPE, though but only take care > > of the necessary refactoring upfront. > > > > Regtested on rv64gcv_zvl512b with -mrvv-max-lmul=dynamic. There are a > > few minor regressions but nothing worse than what we already have. I'd > > rather accept these now and take it as an incentive to work on the > > heuristic later than block the SLP work until it is fixed. > > Note this is blocking me right now (I'll find some other things to work on, > for sure). Can you discuss how you want to go forward on this part of > RVV costing in the near future? > > Thanks, > Richard. > > > Regards > > Robin > > > > gcc/ChangeLog: > > > > * config/riscv/riscv-vector-costs.cc (get_live_range): > > Move compute_local_program_points to cost class. > > (variable_vectorized_p): Add slp node parameter. > > (need_additional_vector_vars_p): Move from here... > > (costs::need_additional_vector_vars_p): ... to here and add slp > > parameter. > > (compute_estimated_lmul): Move update_local_live_ranges to cost > > class. > > (has_unexpected_spills_p): Move from here... > > (costs::has_unexpected_spills_p): ... to here. > > (costs::record_lmul_spills): New function. > > (costs::add_stmt_cost): Add stmt_info, slp mapping. > > (costs::finish_cost): Analyze loop. > > * config/riscv/riscv-vector-costs.h: Move declarations to class. > > --- > > gcc/config/riscv/riscv-vector-costs.cc | 71 +++++++++++++++++--------- > > gcc/config/riscv/riscv-vector-costs.h | 16 ++++++ > > 2 files changed, 62 insertions(+), 25 deletions(-) > > > > diff --git a/gcc/config/riscv/riscv-vector-costs.cc > > b/gcc/config/riscv/riscv-vector-costs.cc > > index 4d8170de9b2..df924fafd8e 100644 > > --- a/gcc/config/riscv/riscv-vector-costs.cc > > +++ b/gcc/config/riscv/riscv-vector-costs.cc > > @@ -178,8 +178,8 @@ get_live_range (hash_map<tree, pair> *live_ranges, tree > > arg) > > STMT 5 (be vectorized) -- point 2 > > ... > > */ > > -static void > > -compute_local_program_points ( > > +void > > +costs::compute_local_program_points ( > > vec_info *vinfo, > > hash_map<basic_block, vec<stmt_point>> &program_points_per_bb) > > { > > @@ -274,14 +274,14 @@ loop_invariant_op_p (class loop *loop, > > > > /* Return true if the variable should be counted into liveness. */ > > static bool > > -variable_vectorized_p (class loop *loop, stmt_vec_info stmt_info, tree var, > > - bool lhs_p) > > +variable_vectorized_p (class loop *loop, stmt_vec_info stmt_info, > > + slp_tree node ATTRIBUTE_UNUSED, tree var, bool lhs_p) > > { > > if (!var) > > return false; > > gimple *stmt = STMT_VINFO_STMT (stmt_info); > > - enum stmt_vec_info_type type > > - = STMT_VINFO_TYPE (vect_stmt_to_vectorize (stmt_info)); > > + stmt_info = vect_stmt_to_vectorize (stmt_info); > > + enum stmt_vec_info_type type = STMT_VINFO_TYPE (stmt_info); > > if (is_gimple_call (stmt) && gimple_call_internal_p (stmt)) > > { > > if (gimple_call_internal_fn (stmt) == IFN_MASK_STORE > > @@ -357,8 +357,8 @@ variable_vectorized_p (class loop *loop, stmt_vec_info > > stmt_info, tree var, > > > > The live range of SSA 1 is [1, 3] in bb 2. > > The live range of SSA 2 is [0, 4] in bb 3. */ > > -static machine_mode > > -compute_local_live_ranges ( > > +machine_mode > > +costs::compute_local_live_ranges ( > > loop_vec_info loop_vinfo, > > const hash_map<basic_block, vec<stmt_point>> &program_points_per_bb, > > hash_map<basic_block, hash_map<tree, pair>> &live_ranges_per_bb) > > @@ -388,8 +388,11 @@ compute_local_live_ranges ( > > unsigned int point = program_point.point; > > gimple *stmt = program_point.stmt; > > tree lhs = gimple_get_lhs (stmt); > > - if (variable_vectorized_p (loop, program_point.stmt_info, lhs, > > - true)) > > + slp_tree *node = vinfo_slp_map.get (program_point.stmt_info); > > + if (!node) > > + continue; > > + if (variable_vectorized_p (loop, program_point.stmt_info, > > + *node, lhs, true)) > > { > > biggest_mode = get_biggest_mode (biggest_mode, > > TYPE_MODE (TREE_TYPE > > (lhs))); > > @@ -406,8 +409,8 @@ compute_local_live_ranges ( > > for (i = 0; i < gimple_num_args (stmt); i++) > > { > > tree var = gimple_arg (stmt, i); > > - if (variable_vectorized_p (loop, program_point.stmt_info, > > var, > > - false)) > > + if (variable_vectorized_p (loop, program_point.stmt_info, > > + *node, var, false)) > > { > > biggest_mode > > = get_biggest_mode (biggest_mode, > > @@ -597,11 +600,11 @@ get_store_value (gimple *stmt) > > } > > > > /* Return true if additional vector vars needed. */ > > -static bool > > -need_additional_vector_vars_p (stmt_vec_info stmt_info) > > +bool > > +costs::need_additional_vector_vars_p (stmt_vec_info stmt_info, > > + slp_tree node ATTRIBUTE_UNUSED) > > { > > - enum stmt_vec_info_type type > > - = STMT_VINFO_TYPE (vect_stmt_to_vectorize (stmt_info)); > > + enum stmt_vec_info_type type = STMT_VINFO_TYPE (stmt_info); > > if (type == load_vec_info_type || type == store_vec_info_type) > > { > > if (STMT_VINFO_GATHER_SCATTER_P (stmt_info) > > @@ -657,8 +660,8 @@ compute_estimated_lmul (loop_vec_info loop_vinfo, > > machine_mode mode) > > > > Then, after this function, we update SSA 1 live range in bb 2 > > into [2, 4] since SSA 1 is live out into bb 3. */ > > -static void > > -update_local_live_ranges ( > > +void > > +costs::update_local_live_ranges ( > > vec_info *vinfo, > > hash_map<basic_block, vec<stmt_point>> &program_points_per_bb, > > hash_map<basic_block, hash_map<tree, pair>> &live_ranges_per_bb, > > @@ -685,8 +688,13 @@ update_local_live_ranges ( > > { > > gphi *phi = psi.phi (); > > stmt_vec_info stmt_info = vinfo->lookup_stmt (phi); > > - if (STMT_VINFO_TYPE (vect_stmt_to_vectorize (stmt_info)) > > - == undef_vec_info_type) > > + stmt_info = vect_stmt_to_vectorize (stmt_info); > > + slp_tree *node = vinfo_slp_map.get (stmt_info); > > + > > + if (!node) > > + continue; > > + > > + if (STMT_VINFO_TYPE (stmt_info) == undef_vec_info_type) > > continue; > > > > for (j = 0; j < gimple_phi_num_args (phi); j++) > > @@ -761,9 +769,12 @@ update_local_live_ranges ( > > if (!is_gimple_assign_or_call (gsi_stmt (si))) > > continue; > > stmt_vec_info stmt_info = vinfo->lookup_stmt (gsi_stmt (si)); > > - enum stmt_vec_info_type type > > - = STMT_VINFO_TYPE (vect_stmt_to_vectorize (stmt_info)); > > - if (need_additional_vector_vars_p (stmt_info)) > > + stmt_info = vect_stmt_to_vectorize (stmt_info); > > + slp_tree *node = vinfo_slp_map.get (stmt_info); > > + if (!node) > > + continue; > > + enum stmt_vec_info_type type = STMT_VINFO_TYPE (stmt_info); > > + if (need_additional_vector_vars_p (stmt_info, *node)) > > { > > /* For non-adjacent load/store STMT, we will potentially > > convert it into: > > @@ -816,8 +827,8 @@ update_local_live_ranges ( > > } > > > > /* Compute the maximum live V_REGS. */ > > -static bool > > -has_unexpected_spills_p (loop_vec_info loop_vinfo) > > +bool > > +costs::has_unexpected_spills_p (loop_vec_info loop_vinfo) > > { > > /* Compute local program points. > > It's a fast and effective computation. */ > > @@ -899,7 +910,11 @@ costs::analyze_loop_vinfo (loop_vec_info loop_vinfo) > > /* Detect whether we're vectorizing for VLA and should apply the > > unrolling > > heuristic described above m_unrolled_vls_niters. */ > > record_potential_vls_unrolling (loop_vinfo); > > +} > > > > +void > > +costs::record_lmul_spills (loop_vec_info loop_vinfo) > > +{ > > /* Detect whether the LOOP has unexpected spills. */ > > record_potential_unexpected_spills (loop_vinfo); > > } > > @@ -1239,8 +1254,12 @@ costs::add_stmt_cost (int count, vect_cost_for_stmt > > kind, > > int stmt_cost > > = targetm.vectorize.builtin_vectorization_cost (kind, vectype, > > misalign); > > > > + if (stmt_info && node) > > + vinfo_slp_map.put (stmt_info, node); > > + > > /* Do one-time initialization based on the vinfo. */ > > loop_vec_info loop_vinfo = dyn_cast<loop_vec_info> (m_vinfo); > > + > > if (!m_analyzed_vinfo) > > { > > if (loop_vinfo) > > @@ -1326,6 +1345,8 @@ costs::finish_cost (const vector_costs *scalar_costs) > > { > > if (loop_vec_info loop_vinfo = dyn_cast<loop_vec_info> (m_vinfo)) > > { > > + record_lmul_spills (loop_vinfo); > > + > > adjust_vect_cost_per_loop (loop_vinfo); > > } > > vector_costs::finish_cost (scalar_costs); > > diff --git a/gcc/config/riscv/riscv-vector-costs.h > > b/gcc/config/riscv/riscv-vector-costs.h > > index de546a66f5c..b84ceb1d3cf 100644 > > --- a/gcc/config/riscv/riscv-vector-costs.h > > +++ b/gcc/config/riscv/riscv-vector-costs.h > > @@ -91,7 +91,10 @@ private: > > typedef pair_hash <tree_operand_hash, tree_operand_hash> tree_pair_hash; > > hash_set <tree_pair_hash> memrefs; > > > > + hash_map <stmt_vec_info, slp_tree> vinfo_slp_map; > > + > > void analyze_loop_vinfo (loop_vec_info); > > + void record_lmul_spills (loop_vec_info loop_vinfo); > > void record_potential_vls_unrolling (loop_vec_info); > > bool prefer_unrolled_loop () const; > > > > @@ -103,6 +106,19 @@ private: > > bool m_has_unexpected_spills_p = false; > > void record_potential_unexpected_spills (loop_vec_info); > > > > + void compute_local_program_points (vec_info *, > > + hash_map<basic_block, vec<stmt_point>> > > &); > > + void update_local_live_ranges (vec_info *, > > + hash_map<basic_block, vec<stmt_point>> &, > > + hash_map<basic_block, hash_map<tree, > > pair>> &, > > + machine_mode *); > > + machine_mode compute_local_live_ranges > > + (loop_vec_info, const hash_map<basic_block, vec<stmt_point>> &, > > + hash_map<basic_block, hash_map<tree, pair>> &); > > + > > + bool has_unexpected_spills_p (loop_vec_info); > > + bool need_additional_vector_vars_p (stmt_vec_info, slp_tree); > > + > > void adjust_vect_cost_per_loop (loop_vec_info); > > unsigned adjust_stmt_cost (enum vect_cost_for_stmt kind, > > loop_vec_info, > > -- > > 2.50.0 > >