Implement TARGET_OPTION_VALID_VERSION_ATTRIBUTE_P for LoongArch.
This is used to determine whether the attribute ((target_version ("...")))
is valid and process it.
Define TARGET_HAS_FMV_TARGET_ATTRIBUTE to 0 to use "target_version"
for function versioning.
gcc/ChangeLog:
* config/loongarch/loongarch.cc
(loongarch_process_target_version_attr): New function.
(loongarch_option_valid_version_attribute_p): New function.
(TARGET_OPTION_VALID_VERSION_ATTRIBUTE_P): Define.
* config/loongarch/loongarch.h
(TARGET_HAS_FMV_TARGET_ATTRIBUTE): Define it to 0.
Change-Id: I9e8243b00d2308664ef46ea615c813057240e791
---
gcc/config/loongarch/loongarch.cc | 92 +++++++++++++++++++++++++++++++
gcc/config/loongarch/loongarch.h | 2 +
2 files changed, 94 insertions(+)
diff --git a/gcc/config/loongarch/loongarch.cc
b/gcc/config/loongarch/loongarch.cc
index c782cac0ff9..4382deb9e79 100644
--- a/gcc/config/loongarch/loongarch.cc
+++ b/gcc/config/loongarch/loongarch.cc
@@ -11308,6 +11308,94 @@ loongarch_can_inline_p (tree caller, tree callee)
return true;
}
+/* Parse the tree in ARGS that contains the target_version attribute
+ information and update the global target options space. If LOC is nonnull,
+ report diagnostics against *LOC, otherwise remain silent. */
+
+bool
+loongarch_process_target_version_attr (tree args, tree fndecl)
+{
+ location_t loc = DECL_SOURCE_LOCATION (fndecl);
+
+ if (TREE_CODE (args) == TREE_LIST)
+ {
+ if (TREE_CHAIN (args))
+ {
+ if (loc)
+ error_at (loc, "attribute %<target_version%> "
+ "has multiple values");
+ return false;
+ }
+ args = TREE_VALUE (args);
+ }
+
+ if (!args || TREE_CODE (args) != STRING_CST)
+ {
+ if (loc)
+ error_at (loc, "attribute %<target_version%> argument not a string");
+ return false;
+ }
+
+ string_slice str = TREE_STRING_POINTER (args);
+
+ if (str == "default")
+ return true;
+
+ return loongarch_process_target_attr (args, fndecl);
+}
+
+/* Implement TARGET_OPTION_VALID_VERSION_ATTRIBUTE_P. This is used to
+ process attribute ((target_version ("..."))). */
+
+static bool
+loongarch_option_valid_version_attribute_p (tree fndecl, tree, tree args, int)
+{
+ struct cl_target_option cur_target;
+ bool ret;
+ tree new_target;
+ tree existing_target = DECL_FUNCTION_SPECIFIC_TARGET (fndecl);
+
+ /* Save the current target options to restore at the end. */
+ cl_target_option_save (&cur_target, &global_options, &global_options_set);
+
+ /* If fndecl already has some target attributes applied to it, unpack
+ them so that we add this attribute on top of them, rather than
+ overwriting them. */
+ if (existing_target)
+ {
+ struct cl_target_option *existing_options
+ = TREE_TARGET_OPTION (existing_target);
+
+ if (existing_options)
+ cl_target_option_restore (&global_options, &global_options_set,
+ existing_options);
+ }
+ else
+ cl_target_option_restore (&global_options, &global_options_set,
+ TREE_TARGET_OPTION (target_option_current_node));
+
+ ret = loongarch_process_target_version_attr (args, fndecl);
+
+ /* Set up any additional state. */
+ if (ret)
+ {
+ loongarch_option_override_internal (&la_target,
+ &global_options,
+ &global_options_set);
+ new_target = build_target_option_node (&global_options,
+ &global_options_set);
+ }
+ else
+ new_target = NULL;
+
+ if (fndecl && ret)
+ DECL_FUNCTION_SPECIFIC_TARGET (fndecl) = new_target;
+
+ cl_target_option_restore (&global_options, &global_options_set, &cur_target);
+
+ return ret;
+}
+
/* Initialize the GCC target structure. */
#undef TARGET_ASM_ALIGNED_HI_OP
#define TARGET_ASM_ALIGNED_HI_OP "\t.half\t"
@@ -11595,6 +11683,10 @@ loongarch_can_inline_p (tree caller, tree callee)
#undef TARGET_CAN_INLINE_P
#define TARGET_CAN_INLINE_P loongarch_can_inline_p
+#undef TARGET_OPTION_VALID_VERSION_ATTRIBUTE_P
+#define TARGET_OPTION_VALID_VERSION_ATTRIBUTE_P \
+ loongarch_option_valid_version_attribute_p
+
struct gcc_target targetm = TARGET_INITIALIZER;
#include "gt-loongarch.h"
diff --git a/gcc/config/loongarch/loongarch.h b/gcc/config/loongarch/loongarch.h
index e8819bf1480..b3fb4828057 100644
--- a/gcc/config/loongarch/loongarch.h
+++ b/gcc/config/loongarch/loongarch.h
@@ -1293,3 +1293,5 @@ struct GTY (()) machine_function
#define TARGET_EXPLICIT_RELOCS \
(la_opt_explicit_relocs == EXPLICIT_RELOCS_ALWAYS)
+
+#define TARGET_HAS_FMV_TARGET_ATTRIBUTE 0
--
2.34.1