On 2024/10/24 15:13, Yangyu Chen wrote:
This patch implements the TARGET_GENERATE_VERSION_DISPATCHER_BODY and
TARGET_GET_FUNCTION_VERSIONS_DISPATCHER for RISC-V. This is used to
generate the dispatcher function and get the dispatcher function for
function multiversioning.
This patch copies many codes from commit 0cfde688e213 ("[aarch64]
Add function multiversioning support") and modifies them to fit the
RISC-V port. A key difference is the data structure of feature bits in
RISC-V C-API is a array of unsigned long long, while in AArch64 is not
a array. So we need to generate the array reference for each feature
bits element in the dispatcher function.
gcc/ChangeLog:
* config/riscv/riscv.cc (add_condition_to_bb): New function.
(dispatch_function_versions): New function.
(get_suffixed_assembler_name): New function.
(make_resolver_func): New function.
(riscv_generate_version_dispatcher_body): New function.
(riscv_get_function_versions_dispatcher): New function.
(TARGET_GENERATE_VERSION_DISPATCHER_BODY): Implement it.
(TARGET_GET_FUNCTION_VERSIONS_DISPATCHER): Implement it.
---
gcc/config/riscv/riscv.cc | 582 ++++++++++++++++++++++++++++++++++++++
1 file changed, 582 insertions(+)
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 46961360096..c8dbe5333ec 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
+static int
+dispatch_function_versions (tree dispatch_decl,
+ void *fndecls_p,
+ basic_block *empty_bb)
+{
+ gimple *ifunc_cpu_init_stmt;
+ gimple_seq gseq;
+ vec<tree> *fndecls;
+
+ gcc_assert (dispatch_decl != NULL
+ && fndecls_p != NULL
+ && empty_bb != NULL);
+
+ push_cfun (DECL_STRUCT_FUNCTION (dispatch_decl));
+
+ gseq = bb_seq (*empty_bb);
+ /* Function version dispatch is via IFUNC. IFUNC resolvers fire before
+ constructors, so explicity call __init_riscv_feature_bits here. */
+ tree init_fn_type = build_function_type_list (void_type_node,
+ long_unsigned_type_node,
+ ptr_type_node,
+ NULL);
+ tree init_fn_id = get_identifier ("__init_riscv_feature_bits");
+ tree init_fn_decl = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL,
+ init_fn_id, init_fn_type);
Here should add `DECL_EXTERNAL (init_fn_decl) = 1;` to avoid link error
with LTO.
Similar patch on aarch64 by me:
https://patchwork.sourceware.org/project/gcc/patch/[email protected]/
I'm waiting for other reviews before submitting the next revision.
+ ifunc_cpu_init_stmt = gimple_build_call (init_fn_decl, 0);