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/tencent_d088823cda488e50b88a31b5212c8d4d7...@qq.com/ I'm waiting for other reviews before submitting the next revision.
+ ifunc_cpu_init_stmt = gimple_build_call (init_fn_decl, 0);