This patch implements the TARGET_VERSION_COMPATIBLE macro for RISC-V.
It checks if the versioned callee is compatible with the versioned
caller.

Signed-off-by: Yangyu Chen <c...@cyyself.name>

gcc/ChangeLog:

        * config/riscv/riscv.cc (riscv_version_compatible): New function.
        (TARGET_VERSION_COMPATIBLE): Define to riscv_version_compatible.
---
 gcc/config/riscv/riscv.cc | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 65b82795541..30e980dbc80 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -13213,6 +13213,27 @@ riscv_compare_version_priority (tree decl1, tree decl2)
   return compare_fmv_features (mask1, mask2, prio1, prio2);
 }
 
+
+bool
+riscv_version_compatible (tree caller, tree callee)
+{
+  struct cl_target_option caller_opts;
+  struct cl_target_option callee_opts;
+  bool caller_not_def = parse_features_for_version (caller, caller_opts);
+  bool callee_not_def = parse_features_for_version (callee, callee_opts);
+
+  /* Callee must be compatible with caller when callee is default.  */
+  if (! callee_not_def)
+    return true;
+
+  /* Callee must not be compatible with caller when caller is default but 
callee
+     is not.  */
+  if (! caller_not_def)
+    return false;
+
+  return riscv_ext_is_subset (&caller_opts, &callee_opts);
+}
+
 /* This function returns true if FN1 and FN2 are versions of the same function,
    that is, the target_version attributes of the function decls are different.
    This assumes that FN1 and FN2 have the same signature.  */
@@ -14427,6 +14448,9 @@ bool need_shadow_stack_push_pop_p ()
 #undef TARGET_COMPARE_VERSION_PRIORITY
 #define TARGET_COMPARE_VERSION_PRIORITY riscv_compare_version_priority
 
+#undef TARGET_VERSION_COMPATIBLE
+#define TARGET_VERSION_COMPATIBLE riscv_version_compatible
+
 #undef TARGET_OPTION_FUNCTION_VERSIONS
 #define TARGET_OPTION_FUNCTION_VERSIONS riscv_common_function_versions
 
-- 
2.49.0

Reply via email to