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);

Reply via email to