gcc/ChangeLog:
* config/loongarch/loongarch.cc
(loongarch_option_same_function_versions): Compare the target
attributes in two functions to determine which function’s
features get higher priority.
(TARGET_OPTION_SAME_FUNCTION_VERSIONS): Define.
Change-Id: I2ce16a2b0422af1a9ac8e367876b0a0d01a0482c
---
gcc/config/loongarch/loongarch.cc | 41 ++++++++++++++++++++++++++++---
1 file changed, 38 insertions(+), 3 deletions(-)
diff --git a/gcc/config/loongarch/loongarch.cc
b/gcc/config/loongarch/loongarch.cc
index 5beb5cc6166..b62f7c644a1 100644
--- a/gcc/config/loongarch/loongarch.cc
+++ b/gcc/config/loongarch/loongarch.cc
@@ -11543,15 +11543,29 @@ get_feature_mask_for_version (tree decl,
{
tree version_attr = lookup_attribute ("target_version",
DECL_ATTRIBUTES (decl));
+
+ /* When a function is added with "__attribute__((target_version(**)))" to
+ define multiple versions, it is allowed to define this function without
+ adding the "__attribute__((target_version("default")))" attribute.
+ In this case, the function without the attribute will be compiled as the
+ default version.
+ If version_attr is empty, it is the default version of the function.
+ Set the feature_mask of this function to 0 and the priority to
+ LA_PRIO_NONE. */
if (version_attr == NULL)
- return;
+ {
+ if (feature_mask)
+ feature_mask = 0ULL;
+
+ if (feature_priority)
+ feature_priority->safe_push (0);
+ return;
+ }
string_slice version_string
= TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (version_attr)));
loongarch_parse_fmv_features (decl, version_string, feature_mask,
feature_priority);
-
- return;
}
/* This adds a condition to the basic_block NEW_BB in function FUNCTION_DECL
@@ -11899,6 +11913,23 @@ loongarch_generate_version_dispatcher_body (void
*node_p)
return resolver_decl;
}
+/* 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. */
+
+bool
+loongarch_option_same_function_versions (string_slice str1, string_slice str2)
+{
+ loongarch_fmv_feature_mask feature_mask1;
+ loongarch_fmv_feature_mask feature_mask2;
+ loongarch_parse_fmv_features (NULL, str1,
+ &feature_mask1, NULL);
+ loongarch_parse_fmv_features (NULL, str2,
+ &feature_mask2, NULL);
+
+ return feature_mask1 == feature_mask2;
+}
+
/* Initialize the GCC target structure. */
#undef TARGET_ASM_ALIGNED_HI_OP
#define TARGET_ASM_ALIGNED_HI_OP "\t.half\t"
@@ -12206,6 +12237,10 @@ loongarch_generate_version_dispatcher_body (void
*node_p)
#define TARGET_COMPARE_VERSION_PRIORITY \
loongarch_compare_version_priority
+#undef TARGET_OPTION_SAME_FUNCTION_VERSIONS
+#define TARGET_OPTION_SAME_FUNCTION_VERSIONS \
+ loongarch_option_same_function_versions
+
struct gcc_target targetm = TARGET_INITIALIZER;
#include "gt-loongarch.h"
--
2.34.1