LoongArch: Enable switchable target

Message ID 20240407074743.2747877-2-yangyujie@loongson.cn
State New
Headers
Series LoongArch: Enable switchable target |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gcc_build--master-arm success Testing passed
linaro-tcwg-bot/tcwg_gcc_check--master-arm success Testing passed
linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 success Testing passed
linaro-tcwg-bot/tcwg_gcc_check--master-aarch64 success Testing passed

Commit Message

Yang Yujie April 7, 2024, 7:47 a.m. UTC
  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
  

Comments

Yang Yujie April 7, 2024, 8:23 a.m. UTC | #1
On Sun, Apr 07, 2024 at 04:23:53PM +0800, Xi Ruoyao wrote:
> On Sun, 2024-04-07 at 15:47 +0800, Yang Yujie wrote:
> > 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
> 
> Oops, so this PR isn't fixed with r14-7134 "LoongArch: Implement option
> save/restore"?  Should I reopen it?
> 
> -- 
> Xi Ruoyao <xry111@xry111.site>
> School of Aerospace Science and Technology, Xidian University

Yes, the issue was not fixed with that patch. This one should do.
  
Xi Ruoyao April 7, 2024, 8:23 a.m. UTC | #2
On Sun, 2024-04-07 at 15:47 +0800, Yang Yujie wrote:
> 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

Oops, so this PR isn't fixed with r14-7134 "LoongArch: Implement option
save/restore"?  Should I reopen it?
  
Xi Ruoyao April 7, 2024, 8:38 a.m. UTC | #3
On Sun, 2024-04-07 at 16:23 +0800, Yang Yujie wrote:
> On Sun, Apr 07, 2024 at 04:23:53PM +0800, Xi Ruoyao wrote:
> > On Sun, 2024-04-07 at 15:47 +0800, Yang Yujie wrote:
> > > 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
> > 
> > Oops, so this PR isn't fixed with r14-7134 "LoongArch: Implement option
> > save/restore"?  Should I reopen it?
> > 
> > -- 
> > Xi Ruoyao <xry111@xry111.site>
> > School of Aerospace Science and Technology, Xidian University
> 
> Yes, the issue was not fixed with that patch. This one should do.

So reopened the PR.
  
Xi Ruoyao April 7, 2024, 12:56 p.m. UTC | #4
On Sun, 2024-04-07 at 15:47 +0800, Yang Yujie wrote:
> 	* config/loongarch/loongarch-builtins.cc
> (loongarch_init_builtins):
>         Initialize all builtin functions at startup.

git gcc-verify complains that tab should be used instead of space for
this line.

> 	(loongarch_expand_builtin): Turn assertion of builtin
> availability
>         into a test.

and this line.
  
Yang Yujie April 8, 2024, 1:57 a.m. UTC | #5
On Sun, Apr 07, 2024 at 08:56:53PM +0800, Xi Ruoyao wrote:
> On Sun, 2024-04-07 at 15:47 +0800, Yang Yujie wrote:
> > 	* config/loongarch/loongarch-builtins.cc
> > (loongarch_init_builtins):
> >         Initialize all builtin functions at startup.
> 
> git gcc-verify complains that tab should be used instead of space for
> this line.
> 
> > 	(loongarch_expand_builtin): Turn assertion of builtin
> > availability
> >         into a test.
> 
> and this line.
> 
> -- 
> Xi Ruoyao <xry111@xry111.site>
> School of Aerospace Science and Technology, Xidian University

Thanks! I will fix it soon.
  

Patch

diff --git a/gcc/config/loongarch/loongarch-builtins.cc b/gcc/config/loongarch/loongarch-builtins.cc
index efe7e5e5ebc..fbe46833c9b 100644
--- a/gcc/config/loongarch/loongarch-builtins.cc
+++ b/gcc/config/loongarch/loongarch-builtins.cc
@@ -2512,14 +2512,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;
     }
 }
 
@@ -3105,15 +3102,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 c90b701a533..6b92e7034c5 100644
--- a/gcc/config/loongarch/loongarch.cc
+++ b/gcc/config/loongarch/loongarch.cc
@@ -7570,15 +7570,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,
@@ -7605,20 +7609,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.  */
@@ -10935,6 +11011,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 23bb3254883..db8a9eb9516 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 00000000000..0a045c51966
--- /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 45435586de2..0122440e8d9 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -13402,6 +13402,18 @@  proc check_effective_target_loongarch_sx { } {
     } "-mlsx"]
 }
 
+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>