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