This applies a scalar/vector unit ratio to integer vector body costs,
which helps the cost model better match the actual hardware throughput.

Take an int64 vadd at VLEN=128 for example: 4 scalar units and 2 vector
units can both process 4 elements per cycle. Without this ratio, both
vector and scalar stmts just get a cost of 1, which ends up making
vectorization look too cheap.

Skip applying this ratio for:
- reduction stmts
- gather/scatter stmts

Add scalar_units and vector_units fields to riscv_tune_param.  A zero
value for either field disables the scaling.

For generic-ooo, use a 4:2 scalar/vector unit ratio.
Other uarch are left unconfig since I dont know their unit number.
They can be tuned individually later.

BTW, this is still a rough cost model adjustment,
we’re trying to make progress one small piece at a time.

gcc/ChangeLog:

        * config/riscv/riscv-protos.h (get_vector_units): New.
        (get_scalar_units): New.
        * config/riscv/riscv-vector-costs.cc (costs::add_stmt_cost):
        Scale ordinary integer vector body costs using the current tune's
        scalar/vector unit ratio.
        * config/riscv/riscv.cc (riscv_tune_param): Add scalar_units and
        vector_units.
        (generic_ooo_tune_info): Set scalar_units to 4 and vector_units to 2.
        (get_vector_units): New.
        (get_scalar_units): New.

Signed-off-by: Zhongyao Chen <[email protected]>
---
 gcc/config/riscv/riscv-protos.h        |  2 ++
 gcc/config/riscv/riscv-vector-costs.cc | 16 ++++++++++++++++
 gcc/config/riscv/riscv.cc              | 25 +++++++++++++++++++++++++
 3 files changed, 43 insertions(+)

diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
index e9612cca1a1..f879680f787 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ b/gcc/config/riscv/riscv-protos.h
@@ -940,6 +940,8 @@ struct riscv_tune_info {
 const struct riscv_tune_info *
 riscv_parse_tune (const char *, bool);
 const cpu_vector_cost *get_vector_costs ();
+unsigned int get_vector_units ();
+unsigned int get_scalar_units ();
 int get_gr2vr_cost ();
 int get_vr2gr_cost ();
 int get_fr2vr_cost ();
diff --git a/gcc/config/riscv/riscv-vector-costs.cc 
b/gcc/config/riscv/riscv-vector-costs.cc
index bfb8a0ca63b..468d59230da 100644
--- a/gcc/config/riscv/riscv-vector-costs.cc
+++ b/gcc/config/riscv/riscv-vector-costs.cc
@@ -1617,6 +1617,22 @@ costs::add_stmt_cost (int count, vect_cost_for_stmt kind,
     stmt_cost = adjust_stmt_cost (kind, loop_vinfo, stmt_info, node, vectype,
                                  stmt_cost);
 
+  unsigned int scalar_units = get_scalar_units ();
+  unsigned int vector_units = get_vector_units ();
+
+  /* Scale integer vector body costs by the scalar/vector unit ratio.  */
+  if (!costing_for_scalar ()
+      && loop_vinfo
+      && where == vect_body
+      && kind == vector_stmt
+      && !is_reduction (stmt_info, node)
+      && !(stmt_info && STMT_VINFO_GATHER_SCATTER_P (stmt_info))
+      && !(node && mat_gather_scatter_p (SLP_TREE_MEMORY_ACCESS_TYPE (node)))
+      && vectype
+      && VECTOR_INTEGER_TYPE_P (vectype)
+      && scalar_units != 0 && vector_units != 0)
+    stmt_cost = CEIL (stmt_cost * scalar_units, vector_units);
+
   return record_stmt_cost (stmt_info, where, count * stmt_cost);
 }
 
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 62fa062cf58..798dc04770b 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -310,6 +310,10 @@ struct riscv_tune_param
     AUTOPREFETCHER_OFF,
     AUTOPREFETCHER_WEAK
   } autoprefetcher_model = AUTOPREFETCHER_OFF;
+  /* scalar and vector units used for vector costing.
+     A zero value disables the scaling.  */
+  unsigned short scalar_units;
+  unsigned short vector_units;
 };
 
 
@@ -726,6 +730,11 @@ static const struct riscv_tune_param generic_ooo_tune_info 
= {
   2,                                           /* int_reassoc_width.  */
   2,                                           /* fp_reassoc_width.  */
   1,                                           /* vec_reassoc_width.  */
+  4,                                           /* small_loop_unroll_ninsns.  */
+  2,                                           /* small_loop_unroll_factor.  */
+  riscv_tune_param::AUTOPREFETCHER_OFF,                /* 
autoprefetcher_model.  */
+  4,                                           /* scalar_units.  */
+  2,                                           /* vector_units.  */
 };
 
 static const common_vector_cost xt_c9501_vls_vector_cost = {
@@ -14165,6 +14174,22 @@ get_vector_costs ()
   return costs;
 }
 
+/* Return the number of vector units.  */
+
+unsigned int
+get_vector_units ()
+{
+  return tune_param->vector_units;
+}
+
+/* Return the number of scalar units.  */
+
+unsigned int
+get_scalar_units ()
+{
+  return tune_param->scalar_units;
+}
+
 /* Return the cost of operation that move from gpr to vr.
    It will take the value of --param=gpr2vr_cost if it is provided.
    Or the default regmove->GR2VR will be returned.  */
-- 
2.43.0


Reply via email to