Message ID | 20240408084512.226082-2-yangyujie@loongson.cn |
---|---|
State | New |
Headers | show |
Series | [v2] LoongArch: Enable switchable target | expand |
v1 -> v2: Remove spaces from changelog.
On Mon, 2024-04-08 at 16:46 +0800, Yang Yujie wrote: > v1 -> v2: > Remove spaces from changelog. I've rebuilt the base system with a GCC including this patch. LTO+PGO bootstrap fine, regtested fine, and no issues observed. I do usually include the optimization flags into LDFLAGS when I do LTO, so I don't really rely on this patch though.
On Mon, Apr 08, 2024 at 04:49:58PM +0800, Xi Ruoyao wrote: > On Mon, 2024-04-08 at 16:46 +0800, Yang Yujie wrote: > > v1 -> v2: > > Remove spaces from changelog. > > I've rebuilt the base system with a GCC including this patch. LTO+PGO > bootstrap fine, regtested fine, and no issues observed. > > I do usually include the optimization flags into LDFLAGS when I do LTO, > so I don't really rely on this patch though. > > -- > Xi Ruoyao <xry111@xry111.site> > School of Aerospace Science and Technology, Xidian University Thanks for the testing! Respecting the options from compile time seems to be the convention though. And it would be a natural consequence of implementing target attributes, which is not here yet for LoongArch. With this patch, we can have this build issue solved: https://gitlab.freedesktop.org/pixman/pixman/-/merge_requests/83
Pushed to r14-9866. 在 2024/4/8 下午4:45, Yang Yujie 写道: > 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 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>
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>