aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJuzhe-Zhong <juzhe.zhong@rivai.ai>2024-01-12 17:28:44 +0800
committerPan Li <pan2.li@intel.com>2024-01-12 20:15:51 +0800
commit0acb63670bf1058fce00a75bd318c40be3bfa222 (patch)
tree65c43fe3e1430701918510faf52ab58a1b142d0a
parentc75579169eba269a7c339d80b5ac0239f36a58b3 (diff)
downloadgcc-0acb63670bf1058fce00a75bd318c40be3bfa222.zip
gcc-0acb63670bf1058fce00a75bd318c40be3bfa222.tar.gz
gcc-0acb63670bf1058fce00a75bd318c40be3bfa222.tar.bz2
RISC-V: Adjust scalar_to_vec cost
1. Introduce vector regmove new tune info. 2. Adjust scalar_to_vec cost in add_stmt_cost. We will get optimal codegen after this patch with -march=rv64gcv_zvl256b: lui a5,%hi(a) li a4,19 sb a4,%lo(a)(a5) li a0,0 ret Tested on both RV32/RV64 no regression, Ok for trunk ? PR target/113281 gcc/ChangeLog: * config/riscv/riscv-protos.h (struct regmove_vector_cost): New struct. (struct cpu_vector_cost): Add regmove struct. (get_vector_costs): Export as global. * config/riscv/riscv-vector-costs.cc (adjust_stmt_cost): Adjust scalar_to_vec cost. (costs::add_stmt_cost): Ditto. * config/riscv/riscv.cc (get_common_costs): Export global function. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/autovec/pr113209.c: Adapt test. * gcc.dg/vect/costmodel/riscv/rvv/pr113281-1.c: New test. * gcc.dg/vect/costmodel/riscv/rvv/pr113281-2.c: New test.
-rw-r--r--gcc/config/riscv/riscv-protos.h11
-rw-r--r--gcc/config/riscv/riscv-vector-costs.cc23
-rw-r--r--gcc/config/riscv/riscv.cc25
-rw-r--r--gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/pr113281-1.c18
-rw-r--r--gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/pr113281-2.c18
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/pr113209.c2
6 files changed, 87 insertions, 10 deletions
diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
index e8c54c5..4f3b677 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ b/gcc/config/riscv/riscv-protos.h
@@ -250,6 +250,13 @@ struct scalable_vector_cost : common_vector_cost
E.g. fold_left reduction cost, lanes load/store cost, ..., etc. */
};
+/* Additional costs for register copies. Cost is for one register. */
+struct regmove_vector_cost
+{
+ const int GR2VR;
+ const int FR2VR;
+};
+
/* Cost for vector insn classes. */
struct cpu_vector_cost
{
@@ -276,6 +283,9 @@ struct cpu_vector_cost
/* Cost of an VLA modes operations. */
const scalable_vector_cost *vla;
+
+ /* Cost of vector register move operations. */
+ const regmove_vector_cost *regmove;
};
/* Routines implemented in riscv-selftests.cc. */
@@ -764,5 +774,6 @@ struct riscv_tune_info {
const struct riscv_tune_info *
riscv_parse_tune (const char *, bool);
+const cpu_vector_cost *get_vector_costs ();
#endif /* ! GCC_RISCV_PROTOS_H */
diff --git a/gcc/config/riscv/riscv-vector-costs.cc b/gcc/config/riscv/riscv-vector-costs.cc
index 58ec0b9..1c3708f 100644
--- a/gcc/config/riscv/riscv-vector-costs.cc
+++ b/gcc/config/riscv/riscv-vector-costs.cc
@@ -1055,6 +1055,26 @@ costs::better_main_loop_than_p (const vector_costs *uncast_other) const
return vector_costs::better_main_loop_than_p (other);
}
+/* Adjust vectorization cost after calling riscv_builtin_vectorization_cost.
+ For some statement, we would like to further fine-grain tweak the cost on
+ top of riscv_builtin_vectorization_cost handling which doesn't have any
+ information on statement operation codes etc. */
+
+static unsigned
+adjust_stmt_cost (enum vect_cost_for_stmt kind, tree vectype, int stmt_cost)
+{
+ const cpu_vector_cost *costs = get_vector_costs ();
+ switch (kind)
+ {
+ case scalar_to_vec:
+ return stmt_cost += (FLOAT_TYPE_P (vectype) ? costs->regmove->FR2VR
+ : costs->regmove->GR2VR);
+ default:
+ break;
+ }
+ return stmt_cost;
+}
+
unsigned
costs::add_stmt_cost (int count, vect_cost_for_stmt kind,
stmt_vec_info stmt_info, slp_tree, tree vectype,
@@ -1082,6 +1102,9 @@ costs::add_stmt_cost (int count, vect_cost_for_stmt kind,
as one iteration of the VLA loop. */
if (where == vect_body && m_unrolled_vls_niters)
m_unrolled_vls_stmts += count * m_unrolled_vls_niters;
+
+ if (vectype)
+ stmt_cost = adjust_stmt_cost (kind, vectype, stmt_cost);
}
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 f829014..ee1a57b 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -391,17 +391,24 @@ static const scalable_vector_cost rvv_vla_vector_cost = {
},
};
+/* RVV register move cost. */
+static const regmove_vector_cost rvv_regmove_vector_cost = {
+ 2, /* GR2VR */
+ 2, /* FR2VR */
+};
+
/* Generic costs for vector insn classes. It is supposed to be the vector cost
models used by default if no other cost model was specified. */
static const struct cpu_vector_cost generic_vector_cost = {
- 1, /* scalar_int_stmt_cost */
- 1, /* scalar_fp_stmt_cost */
- 1, /* scalar_load_cost */
- 1, /* scalar_store_cost */
- 3, /* cond_taken_branch_cost */
- 1, /* cond_not_taken_branch_cost */
- &rvv_vls_vector_cost, /* vls */
- &rvv_vla_vector_cost, /* vla */
+ 1, /* scalar_int_stmt_cost */
+ 1, /* scalar_fp_stmt_cost */
+ 1, /* scalar_load_cost */
+ 1, /* scalar_store_cost */
+ 3, /* cond_taken_branch_cost */
+ 1, /* cond_not_taken_branch_cost */
+ &rvv_vls_vector_cost, /* vls */
+ &rvv_vla_vector_cost, /* vla */
+ &rvv_regmove_vector_cost, /* regmove */
};
/* Costs to use when optimizing for rocket. */
@@ -10443,7 +10450,7 @@ get_common_costs (const cpu_vector_cost *costs, tree vectype)
/* Return the CPU vector costs according to -mtune if tune info has non-NULL
vector cost. Otherwide, return the default generic vector costs. */
-static const cpu_vector_cost *
+const cpu_vector_cost *
get_vector_costs ()
{
const cpu_vector_cost *costs = tune_param->vec_costs;
diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/pr113281-1.c b/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/pr113281-1.c
new file mode 100644
index 0000000..fdf6ed0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/pr113281-1.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvl256b -mabi=lp64d -O3 -ftree-vectorize" } */
+
+unsigned char a;
+
+int main() {
+ short b = a = 0;
+ for (; a != 19; a++)
+ if (a)
+ b = 32872 >> a;
+
+ if (b == 0)
+ return 0;
+ else
+ return 1;
+}
+
+/* { dg-final { scan-assembler-not {vset} } } */
diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/pr113281-2.c b/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/pr113281-2.c
new file mode 100644
index 0000000..31cecec
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/costmodel/riscv/rvv/pr113281-2.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv_zvl256b -mabi=lp64d -O3 -ftree-vectorize --param=riscv-autovec-preference=fixed-vlmax" } */
+
+unsigned char a;
+
+int main() {
+ short b = a = 0;
+ for (; a != 19; a++)
+ if (a)
+ b = 32872 >> a;
+
+ if (b == 0)
+ return 0;
+ else
+ return 1;
+}
+
+/* { dg-final { scan-assembler-not {vset} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr113209.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr113209.c
index 081ee36..70aae15 100644
--- a/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr113209.c
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/pr113209.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-march=rv64gcv_zvl256b -mabi=lp64d -O3" } */
+/* { dg-options "-march=rv64gcv_zvl256b -mabi=lp64d -O3 -fno-vect-cost-model" } */
int b, c, d, f, i, a;
int e[1] = {0};