282 lines
8.7 KiB
Diff
282 lines
8.7 KiB
Diff
|
|
From 427d5f10951435241d883a13557f862683046ddd Mon Sep 17 00:00:00 2001
|
||
|
|
From: Yang Yujie <yangyujie@loongson.cn>
|
||
|
|
Date: Mon, 8 Apr 2024 16:45:13 +0800
|
||
|
|
Subject: [PATCH 163/188] LoongArch: Enable switchable target
|
||
|
|
|
||
|
|
This patch fixes the back-end context switching in cases where functions
|
||
|
|
should be built with their own target contexts instead of the
|
||
|
|
global one, such as LTO linking and functions with target attributes (TBD).
|
||
|
|
|
||
|
|
PR target/113233
|
||
|
|
|
||
|
|
gcc/ChangeLog:
|
||
|
|
|
||
|
|
* config/loongarch/loongarch.cc (loongarch_reg_init):
|
||
|
|
Reinitialize the loongarch_regno_mode_ok cache.
|
||
|
|
(loongarch_option_override): Same.
|
||
|
|
(loongarch_save_restore_target_globals): Restore target globals.
|
||
|
|
(loongarch_set_current_function): Restore the target contexts
|
||
|
|
for functions.
|
||
|
|
(TARGET_SET_CURRENT_FUNCTION): Define.
|
||
|
|
* config/loongarch/loongarch.h (SWITCHABLE_TARGET): Enable
|
||
|
|
switchable target context.
|
||
|
|
* config/loongarch/loongarch-builtins.cc (loongarch_init_builtins):
|
||
|
|
Initialize all builtin functions at startup.
|
||
|
|
(loongarch_expand_builtin): Turn assertion of builtin availability
|
||
|
|
into a test.
|
||
|
|
|
||
|
|
gcc/testsuite/ChangeLog:
|
||
|
|
|
||
|
|
* lib/target-supports.exp: Define condition loongarch_sx_as.
|
||
|
|
* gcc.dg/lto/pr113233_0.c: New test.
|
||
|
|
---
|
||
|
|
gcc/config/loongarch/loongarch-builtins.cc | 25 +++---
|
||
|
|
gcc/config/loongarch/loongarch.cc | 91 ++++++++++++++++++++--
|
||
|
|
gcc/config/loongarch/loongarch.h | 2 +
|
||
|
|
gcc/testsuite/gcc.dg/lto/pr113233_0.c | 14 ++++
|
||
|
|
gcc/testsuite/lib/target-supports.exp | 12 +++
|
||
|
|
5 files changed, 127 insertions(+), 17 deletions(-)
|
||
|
|
create mode 100644 gcc/testsuite/gcc.dg/lto/pr113233_0.c
|
||
|
|
|
||
|
|
diff --git a/gcc/config/loongarch/loongarch-builtins.cc b/gcc/config/loongarch/loongarch-builtins.cc
|
||
|
|
index e3b4dbc52..51abba007 100644
|
||
|
|
--- a/gcc/config/loongarch/loongarch-builtins.cc
|
||
|
|
+++ b/gcc/config/loongarch/loongarch-builtins.cc
|
||
|
|
@@ -2507,14 +2507,11 @@ loongarch_init_builtins (void)
|
||
|
|
for (i = 0; i < ARRAY_SIZE (loongarch_builtins); i++)
|
||
|
|
{
|
||
|
|
d = &loongarch_builtins[i];
|
||
|
|
- if (d->avail ())
|
||
|
|
- {
|
||
|
|
- type = loongarch_build_function_type (d->function_type);
|
||
|
|
- loongarch_builtin_decls[i]
|
||
|
|
- = add_builtin_function (d->name, type, i, BUILT_IN_MD, NULL,
|
||
|
|
- NULL);
|
||
|
|
- loongarch_get_builtin_decl_index[d->icode] = i;
|
||
|
|
- }
|
||
|
|
+ type = loongarch_build_function_type (d->function_type);
|
||
|
|
+ loongarch_builtin_decls[i]
|
||
|
|
+ = add_builtin_function (d->name, type, i, BUILT_IN_MD, NULL,
|
||
|
|
+ NULL);
|
||
|
|
+ loongarch_get_builtin_decl_index[d->icode] = i;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
@@ -3100,15 +3097,21 @@ loongarch_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
|
||
|
|
int ignore ATTRIBUTE_UNUSED)
|
||
|
|
{
|
||
|
|
tree fndecl;
|
||
|
|
- unsigned int fcode, avail;
|
||
|
|
+ unsigned int fcode;
|
||
|
|
const struct loongarch_builtin_description *d;
|
||
|
|
|
||
|
|
fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
|
||
|
|
fcode = DECL_MD_FUNCTION_CODE (fndecl);
|
||
|
|
gcc_assert (fcode < ARRAY_SIZE (loongarch_builtins));
|
||
|
|
d = &loongarch_builtins[fcode];
|
||
|
|
- avail = d->avail ();
|
||
|
|
- gcc_assert (avail != 0);
|
||
|
|
+
|
||
|
|
+ if (!d->avail ())
|
||
|
|
+ {
|
||
|
|
+ error_at (EXPR_LOCATION (exp),
|
||
|
|
+ "built-in function %qD is not enabled", fndecl);
|
||
|
|
+ return target;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
switch (d->builtin_type)
|
||
|
|
{
|
||
|
|
case LARCH_BUILTIN_DIRECT:
|
||
|
|
diff --git a/gcc/config/loongarch/loongarch.cc b/gcc/config/loongarch/loongarch.cc
|
||
|
|
index 8d8a50b70..50ab6a82a 100644
|
||
|
|
--- a/gcc/config/loongarch/loongarch.cc
|
||
|
|
+++ b/gcc/config/loongarch/loongarch.cc
|
||
|
|
@@ -7567,15 +7567,19 @@ loongarch_global_init (void)
|
||
|
|
loongarch_dwarf_regno[i] = INVALID_REGNUM;
|
||
|
|
}
|
||
|
|
|
||
|
|
+ /* Function to allocate machine-dependent function status. */
|
||
|
|
+ init_machine_status = &loongarch_init_machine_status;
|
||
|
|
+};
|
||
|
|
+
|
||
|
|
+static void
|
||
|
|
+loongarch_reg_init (void)
|
||
|
|
+{
|
||
|
|
/* Set up loongarch_hard_regno_mode_ok. */
|
||
|
|
for (int mode = 0; mode < MAX_MACHINE_MODE; mode++)
|
||
|
|
for (int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
|
||
|
|
loongarch_hard_regno_mode_ok_p[mode][regno]
|
||
|
|
= loongarch_hard_regno_mode_ok_uncached (regno, (machine_mode) mode);
|
||
|
|
-
|
||
|
|
- /* Function to allocate machine-dependent function status. */
|
||
|
|
- init_machine_status = &loongarch_init_machine_status;
|
||
|
|
-};
|
||
|
|
+}
|
||
|
|
|
||
|
|
static void
|
||
|
|
loongarch_option_override_internal (struct loongarch_target *target,
|
||
|
|
@@ -7602,20 +7606,92 @@ loongarch_option_override_internal (struct loongarch_target *target,
|
||
|
|
|
||
|
|
/* Override some options according to the resolved target. */
|
||
|
|
loongarch_target_option_override (target, opts, opts_set);
|
||
|
|
+
|
||
|
|
+ target_option_default_node = target_option_current_node
|
||
|
|
+ = build_target_option_node (opts, opts_set);
|
||
|
|
+
|
||
|
|
+ loongarch_reg_init ();
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+/* Remember the last target of loongarch_set_current_function. */
|
||
|
|
+
|
||
|
|
+static GTY(()) tree loongarch_previous_fndecl;
|
||
|
|
+
|
||
|
|
+/* Restore or save the TREE_TARGET_GLOBALS from or to new_tree.
|
||
|
|
+ Used by loongarch_set_current_function to
|
||
|
|
+ make sure optab availability predicates are recomputed when necessary. */
|
||
|
|
+
|
||
|
|
+static void
|
||
|
|
+loongarch_save_restore_target_globals (tree new_tree)
|
||
|
|
+{
|
||
|
|
+ if (TREE_TARGET_GLOBALS (new_tree))
|
||
|
|
+ restore_target_globals (TREE_TARGET_GLOBALS (new_tree));
|
||
|
|
+ else if (new_tree == target_option_default_node)
|
||
|
|
+ restore_target_globals (&default_target_globals);
|
||
|
|
+ else
|
||
|
|
+ TREE_TARGET_GLOBALS (new_tree) = save_target_globals_default_opts ();
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
+/* Implement TARGET_SET_CURRENT_FUNCTION. */
|
||
|
|
+
|
||
|
|
+static void
|
||
|
|
+loongarch_set_current_function (tree fndecl)
|
||
|
|
+{
|
||
|
|
+ if (fndecl == loongarch_previous_fndecl)
|
||
|
|
+ return;
|
||
|
|
+
|
||
|
|
+ tree old_tree;
|
||
|
|
+ if (loongarch_previous_fndecl == NULL_TREE)
|
||
|
|
+ old_tree = target_option_current_node;
|
||
|
|
+ else if (DECL_FUNCTION_SPECIFIC_TARGET (loongarch_previous_fndecl))
|
||
|
|
+ old_tree = DECL_FUNCTION_SPECIFIC_TARGET (loongarch_previous_fndecl);
|
||
|
|
+ else
|
||
|
|
+ old_tree = target_option_default_node;
|
||
|
|
+
|
||
|
|
+ if (fndecl == NULL_TREE)
|
||
|
|
+ {
|
||
|
|
+ if (old_tree != target_option_current_node)
|
||
|
|
+ {
|
||
|
|
+ loongarch_previous_fndecl = NULL_TREE;
|
||
|
|
+ cl_target_option_restore (&global_options, &global_options_set,
|
||
|
|
+ TREE_TARGET_OPTION
|
||
|
|
+ (target_option_current_node));
|
||
|
|
+ }
|
||
|
|
+ return;
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ tree new_tree = DECL_FUNCTION_SPECIFIC_TARGET (fndecl);
|
||
|
|
+ if (new_tree == NULL_TREE)
|
||
|
|
+ new_tree = target_option_default_node;
|
||
|
|
+
|
||
|
|
+ loongarch_previous_fndecl = fndecl;
|
||
|
|
+
|
||
|
|
+ if (new_tree == old_tree)
|
||
|
|
+ return;
|
||
|
|
+
|
||
|
|
+ cl_target_option_restore (&global_options, &global_options_set,
|
||
|
|
+ TREE_TARGET_OPTION (new_tree));
|
||
|
|
+
|
||
|
|
+ loongarch_reg_init ();
|
||
|
|
+
|
||
|
|
+ loongarch_save_restore_target_globals (new_tree);
|
||
|
|
}
|
||
|
|
|
||
|
|
+
|
||
|
|
+
|
||
|
|
/* Implement TARGET_OPTION_OVERRIDE. */
|
||
|
|
|
||
|
|
static void
|
||
|
|
loongarch_option_override (void)
|
||
|
|
{
|
||
|
|
+ /* Global initializations. */
|
||
|
|
+ loongarch_global_init ();
|
||
|
|
+
|
||
|
|
/* Setting up the target configuration. */
|
||
|
|
loongarch_option_override_internal (&la_target,
|
||
|
|
&global_options,
|
||
|
|
&global_options_set);
|
||
|
|
|
||
|
|
- /* Global initializations. */
|
||
|
|
- loongarch_global_init ();
|
||
|
|
}
|
||
|
|
|
||
|
|
/* Implement TARGET_OPTION_SAVE. */
|
||
|
|
@@ -10931,6 +11007,9 @@ loongarch_asm_code_end (void)
|
||
|
|
#undef TARGET_OPTION_RESTORE
|
||
|
|
#define TARGET_OPTION_RESTORE loongarch_option_restore
|
||
|
|
|
||
|
|
+#undef TARGET_SET_CURRENT_FUNCTION
|
||
|
|
+#define TARGET_SET_CURRENT_FUNCTION loongarch_set_current_function
|
||
|
|
+
|
||
|
|
#undef TARGET_LEGITIMIZE_ADDRESS
|
||
|
|
#define TARGET_LEGITIMIZE_ADDRESS loongarch_legitimize_address
|
||
|
|
|
||
|
|
diff --git a/gcc/config/loongarch/loongarch.h b/gcc/config/loongarch/loongarch.h
|
||
|
|
index 221e8b286..089206605 100644
|
||
|
|
--- a/gcc/config/loongarch/loongarch.h
|
||
|
|
+++ b/gcc/config/loongarch/loongarch.h
|
||
|
|
@@ -23,6 +23,8 @@ along with GCC; see the file COPYING3. If not see
|
||
|
|
|
||
|
|
#include "config/loongarch/loongarch-opts.h"
|
||
|
|
|
||
|
|
+#define SWITCHABLE_TARGET 1
|
||
|
|
+
|
||
|
|
#define TARGET_SUPPORTS_WIDE_INT 1
|
||
|
|
|
||
|
|
/* Macros to silence warnings about numbers being signed in traditional
|
||
|
|
diff --git a/gcc/testsuite/gcc.dg/lto/pr113233_0.c b/gcc/testsuite/gcc.dg/lto/pr113233_0.c
|
||
|
|
new file mode 100644
|
||
|
|
index 000000000..0a045c519
|
||
|
|
--- /dev/null
|
||
|
|
+++ b/gcc/testsuite/gcc.dg/lto/pr113233_0.c
|
||
|
|
@@ -0,0 +1,14 @@
|
||
|
|
+/* { dg-require-effective-target loongarch_sx_as } */
|
||
|
|
+/* { dg-lto-do link } */
|
||
|
|
+/* { dg-skip-if "" { ! { loongarch*-linux-* } } } */
|
||
|
|
+/* { dg-lto-options { {-mlsx } } } */
|
||
|
|
+/* { dg-suppress-ld-options { -mlsx } } */
|
||
|
|
+
|
||
|
|
+#include <lsxintrin.h>
|
||
|
|
+
|
||
|
|
+int main (void)
|
||
|
|
+{
|
||
|
|
+ __m128i a, b, c;
|
||
|
|
+ c = __lsx_vand_v (a, b);
|
||
|
|
+ return 0;
|
||
|
|
+}
|
||
|
|
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
|
||
|
|
index 20fbd43ee..b673c92b5 100644
|
||
|
|
--- a/gcc/testsuite/lib/target-supports.exp
|
||
|
|
+++ b/gcc/testsuite/lib/target-supports.exp
|
||
|
|
@@ -10549,6 +10549,18 @@ proc check_vect_support_and_set_flags { } {
|
||
|
|
return 1
|
||
|
|
}
|
||
|
|
|
||
|
|
+proc check_effective_target_loongarch_sx_as { } {
|
||
|
|
+ return [check_no_compiler_messages loongarch_sx_as object {
|
||
|
|
+ #include <lsxintrin.h>
|
||
|
|
+ int main (void)
|
||
|
|
+ {
|
||
|
|
+ __m128i a, b, c;
|
||
|
|
+ c = __lsx_vand_v (a, b);
|
||
|
|
+ return 0;
|
||
|
|
+ }
|
||
|
|
+ } "-mlsx"]
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
proc check_effective_target_loongarch_sx_hw { } {
|
||
|
|
return [check_runtime loongarch_sx_hw {
|
||
|
|
#include <lsxintrin.h>
|
||
|
|
--
|
||
|
|
2.43.0
|
||
|
|
|