371 lines
14 KiB
Diff
371 lines
14 KiB
Diff
From 91f7471cbc7dec42673b58a1896330d64eb6be2a Mon Sep 17 00:00:00 2001
|
|
From: Richard Sandiford <richard.sandiford@arm.com>
|
|
Date: Thu, 29 Sep 2022 11:32:57 +0100
|
|
Subject: [PATCH 025/157] [Backport][SME] aarch64: Tweak handling of
|
|
-mgeneral-regs-only
|
|
|
|
Reference: https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=2a269bda9e7b8f9353699d0c965e7e9246500aa0
|
|
|
|
-mgeneral-regs-only is effectively "+nofp for the compiler without
|
|
changing the assembler's ISA flags". Currently that's implemented
|
|
by making TARGET_FLOAT, TARGET_SIMD and TARGET_SVE depend on
|
|
!TARGET_GENERAL_REGS_ONLY and then making any feature that needs FP
|
|
registers depend (directly or indirectly) on one of those three TARGET
|
|
macros. The problem is that it's easy to forgot to do the last bit.
|
|
|
|
This patch instead represents the distinction between "assemnbler
|
|
ISA flags" and "compiler ISA flags" more directly, funnelling
|
|
all updates through a new function that sets both sets of flags
|
|
together.
|
|
|
|
gcc/
|
|
* config/aarch64/aarch64.opt (aarch64_asm_isa_flags): New variable.
|
|
* config/aarch64/aarch64.h (aarch64_asm_isa_flags)
|
|
(aarch64_isa_flags): Redefine as read-only macros.
|
|
(TARGET_SIMD, TARGET_FLOAT, TARGET_SVE): Don't depend on
|
|
!TARGET_GENERAL_REGS_ONLY.
|
|
* common/config/aarch64/aarch64-common.cc
|
|
(aarch64_set_asm_isa_flags): New function.
|
|
(aarch64_handle_option): Call it when updating -mgeneral-regs.
|
|
* config/aarch64/aarch64-protos.h (aarch64_simd_switcher): Replace
|
|
m_old_isa_flags with m_old_asm_isa_flags.
|
|
(aarch64_set_asm_isa_flags): Declare.
|
|
* config/aarch64/aarch64-builtins.cc
|
|
(aarch64_simd_switcher::aarch64_simd_switcher)
|
|
(aarch64_simd_switcher::~aarch64_simd_switcher): Save and restore
|
|
aarch64_asm_isa_flags instead of aarch64_isa_flags.
|
|
* config/aarch64/aarch64-sve-builtins.cc
|
|
(check_required_extensions): Use aarch64_asm_isa_flags instead
|
|
of aarch64_isa_flags.
|
|
* config/aarch64/aarch64.cc (aarch64_set_asm_isa_flags): New function.
|
|
(aarch64_override_options, aarch64_handle_attr_arch)
|
|
(aarch64_handle_attr_cpu, aarch64_handle_attr_isa_flags): Use
|
|
aarch64_set_asm_isa_flags to set the ISA flags.
|
|
(aarch64_option_print, aarch64_declare_function_name)
|
|
(aarch64_start_file): Use aarch64_asm_isa_flags instead
|
|
of aarch64_isa_flags.
|
|
(aarch64_can_inline_p): Check aarch64_asm_isa_flags as well as
|
|
aarch64_isa_flags.
|
|
---
|
|
gcc/common/config/aarch64/aarch64-common.cc | 12 ++++++
|
|
gcc/config/aarch64/aarch64-builtins.cc | 6 +--
|
|
gcc/config/aarch64/aarch64-protos.h | 5 ++-
|
|
gcc/config/aarch64/aarch64-sve-builtins.cc | 2 +-
|
|
gcc/config/aarch64/aarch64.cc | 45 ++++++++++++++-------
|
|
gcc/config/aarch64/aarch64.h | 17 ++++++--
|
|
gcc/config/aarch64/aarch64.opt | 3 ++
|
|
7 files changed, 68 insertions(+), 22 deletions(-)
|
|
|
|
diff --git a/gcc/common/config/aarch64/aarch64-common.cc b/gcc/common/config/aarch64/aarch64-common.cc
|
|
index 752ba5632..c64b4987e 100644
|
|
--- a/gcc/common/config/aarch64/aarch64-common.cc
|
|
+++ b/gcc/common/config/aarch64/aarch64-common.cc
|
|
@@ -137,6 +137,17 @@ reset_tsv110_option ()
|
|
}
|
|
}
|
|
|
|
+/* Set OPTS->x_aarch64_asm_isa_flags to FLAGS and update
|
|
+ OPTS->x_aarch64_isa_flags accordingly. */
|
|
+void
|
|
+aarch64_set_asm_isa_flags (gcc_options *opts, aarch64_feature_flags flags)
|
|
+{
|
|
+ opts->x_aarch64_asm_isa_flags = flags;
|
|
+ opts->x_aarch64_isa_flags = flags;
|
|
+ if (opts->x_target_flags & MASK_GENERAL_REGS_ONLY)
|
|
+ opts->x_aarch64_isa_flags &= ~feature_deps::get_flags_off (AARCH64_FL_FP);
|
|
+}
|
|
+
|
|
/* Implement TARGET_HANDLE_OPTION.
|
|
This function handles the target specific options for CPU/target selection.
|
|
|
|
@@ -174,6 +185,7 @@ aarch64_handle_option (struct gcc_options *opts,
|
|
|
|
case OPT_mgeneral_regs_only:
|
|
opts->x_target_flags |= MASK_GENERAL_REGS_ONLY;
|
|
+ aarch64_set_asm_isa_flags (opts, opts->x_aarch64_asm_isa_flags);
|
|
return true;
|
|
|
|
case OPT_mfix_cortex_a53_835769:
|
|
diff --git a/gcc/config/aarch64/aarch64-builtins.cc b/gcc/config/aarch64/aarch64-builtins.cc
|
|
index 42276e7ca..015e9d975 100644
|
|
--- a/gcc/config/aarch64/aarch64-builtins.cc
|
|
+++ b/gcc/config/aarch64/aarch64-builtins.cc
|
|
@@ -1336,20 +1336,20 @@ aarch64_scalar_builtin_type_p (aarch64_simd_type t)
|
|
/* Enable AARCH64_FL_* flags EXTRA_FLAGS on top of the base Advanced SIMD
|
|
set. */
|
|
aarch64_simd_switcher::aarch64_simd_switcher (unsigned int extra_flags)
|
|
- : m_old_isa_flags (aarch64_isa_flags),
|
|
+ : m_old_asm_isa_flags (aarch64_asm_isa_flags),
|
|
m_old_general_regs_only (TARGET_GENERAL_REGS_ONLY)
|
|
{
|
|
/* Changing the ISA flags should be enough here. We shouldn't need to
|
|
pay the compile-time cost of a full target switch. */
|
|
- aarch64_isa_flags = AARCH64_FL_FP | AARCH64_FL_SIMD | extra_flags;
|
|
global_options.x_target_flags &= ~MASK_GENERAL_REGS_ONLY;
|
|
+ aarch64_set_asm_isa_flags (AARCH64_FL_FP | AARCH64_FL_SIMD | extra_flags);
|
|
}
|
|
|
|
aarch64_simd_switcher::~aarch64_simd_switcher ()
|
|
{
|
|
if (m_old_general_regs_only)
|
|
global_options.x_target_flags |= MASK_GENERAL_REGS_ONLY;
|
|
- aarch64_isa_flags = m_old_isa_flags;
|
|
+ aarch64_set_asm_isa_flags (m_old_asm_isa_flags);
|
|
}
|
|
|
|
/* Implement #pragma GCC aarch64 "arm_neon.h". */
|
|
diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
|
|
index ef84df731..86e444a60 100644
|
|
--- a/gcc/config/aarch64/aarch64-protos.h
|
|
+++ b/gcc/config/aarch64/aarch64-protos.h
|
|
@@ -747,7 +747,7 @@ public:
|
|
~aarch64_simd_switcher ();
|
|
|
|
private:
|
|
- unsigned long m_old_isa_flags;
|
|
+ unsigned long m_old_asm_isa_flags;
|
|
bool m_old_general_regs_only;
|
|
};
|
|
|
|
@@ -1032,7 +1032,10 @@ extern bool aarch64_classify_address (struct aarch64_address_info *, rtx,
|
|
machine_mode, bool,
|
|
aarch64_addr_query_type = ADDR_QUERY_M);
|
|
|
|
+void aarch64_set_asm_isa_flags (aarch64_feature_flags);
|
|
+
|
|
/* Defined in common/config/aarch64-common.cc. */
|
|
+void aarch64_set_asm_isa_flags (gcc_options *, aarch64_feature_flags);
|
|
bool aarch64_handle_option (struct gcc_options *, struct gcc_options *,
|
|
const struct cl_decoded_option *, location_t);
|
|
const char *aarch64_rewrite_selected_cpu (const char *name);
|
|
diff --git a/gcc/config/aarch64/aarch64-sve-builtins.cc b/gcc/config/aarch64/aarch64-sve-builtins.cc
|
|
index b927a886e..a70e3a6b4 100644
|
|
--- a/gcc/config/aarch64/aarch64-sve-builtins.cc
|
|
+++ b/gcc/config/aarch64/aarch64-sve-builtins.cc
|
|
@@ -696,7 +696,7 @@ static bool
|
|
check_required_extensions (location_t location, tree fndecl,
|
|
aarch64_feature_flags required_extensions)
|
|
{
|
|
- auto missing_extensions = required_extensions & ~aarch64_isa_flags;
|
|
+ auto missing_extensions = required_extensions & ~aarch64_asm_isa_flags;
|
|
if (missing_extensions == 0)
|
|
return check_required_registers (location, fndecl);
|
|
|
|
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
|
|
index 8cb820767..3e83e48ec 100644
|
|
--- a/gcc/config/aarch64/aarch64.cc
|
|
+++ b/gcc/config/aarch64/aarch64.cc
|
|
@@ -18432,10 +18432,19 @@ aarch64_convert_sve_vector_bits (aarch64_sve_vector_bits_enum value)
|
|
return (int) value / 64;
|
|
}
|
|
|
|
+/* Set the global aarch64_asm_isa_flags to FLAGS and update
|
|
+ aarch64_isa_flags accordingly. */
|
|
+
|
|
+void
|
|
+aarch64_set_asm_isa_flags (aarch64_feature_flags flags)
|
|
+{
|
|
+ aarch64_set_asm_isa_flags (&global_options, flags);
|
|
+}
|
|
+
|
|
/* Implement TARGET_OPTION_OVERRIDE. This is called once in the beginning
|
|
and is used to parse the -m{cpu,tune,arch} strings and setup the initial
|
|
tuning structs. In particular it must set selected_tune and
|
|
- aarch64_isa_flags that define the available ISA features and tuning
|
|
+ aarch64_asm_isa_flags that define the available ISA features and tuning
|
|
decisions. It must also set selected_arch as this will be used to
|
|
output the .arch asm tags for each function. */
|
|
|
|
@@ -18444,7 +18453,7 @@ aarch64_override_options (void)
|
|
{
|
|
aarch64_feature_flags cpu_isa = 0;
|
|
aarch64_feature_flags arch_isa = 0;
|
|
- aarch64_isa_flags = 0;
|
|
+ aarch64_set_asm_isa_flags (0);
|
|
|
|
const struct processor *cpu = NULL;
|
|
const struct processor *arch = NULL;
|
|
@@ -18484,25 +18493,25 @@ aarch64_override_options (void)
|
|
}
|
|
|
|
selected_arch = arch->arch;
|
|
- aarch64_isa_flags = arch_isa;
|
|
+ aarch64_set_asm_isa_flags (arch_isa);
|
|
}
|
|
else if (cpu)
|
|
{
|
|
selected_arch = cpu->arch;
|
|
- aarch64_isa_flags = cpu_isa;
|
|
+ aarch64_set_asm_isa_flags (cpu_isa);
|
|
}
|
|
else if (arch)
|
|
{
|
|
cpu = &all_cores[arch->ident];
|
|
selected_arch = arch->arch;
|
|
- aarch64_isa_flags = arch_isa;
|
|
+ aarch64_set_asm_isa_flags (arch_isa);
|
|
}
|
|
else
|
|
{
|
|
/* No -mcpu or -march specified, so use the default CPU. */
|
|
cpu = &all_cores[TARGET_CPU_DEFAULT];
|
|
selected_arch = cpu->arch;
|
|
- aarch64_isa_flags = cpu->flags;
|
|
+ aarch64_set_asm_isa_flags (cpu->flags);
|
|
}
|
|
|
|
selected_tune = tune ? tune->ident : cpu->ident;
|
|
@@ -18644,7 +18653,7 @@ aarch64_option_print (FILE *file, int indent, struct cl_target_option *ptr)
|
|
= aarch64_get_tune_cpu (ptr->x_selected_tune);
|
|
const struct processor *arch = aarch64_get_arch (ptr->x_selected_arch);
|
|
std::string extension
|
|
- = aarch64_get_extension_string_for_isa_flags (ptr->x_aarch64_isa_flags,
|
|
+ = aarch64_get_extension_string_for_isa_flags (ptr->x_aarch64_asm_isa_flags,
|
|
arch->flags);
|
|
|
|
fprintf (file, "%*sselected tune = %s\n", indent, "", cpu->name);
|
|
@@ -18752,13 +18761,15 @@ aarch64_handle_attr_arch (const char *str)
|
|
{
|
|
const struct processor *tmp_arch = NULL;
|
|
std::string invalid_extension;
|
|
+ aarch64_feature_flags tmp_flags;
|
|
enum aarch64_parse_opt_result parse_res
|
|
- = aarch64_parse_arch (str, &tmp_arch, &aarch64_isa_flags, &invalid_extension);
|
|
+ = aarch64_parse_arch (str, &tmp_arch, &tmp_flags, &invalid_extension);
|
|
|
|
if (parse_res == AARCH64_PARSE_OK)
|
|
{
|
|
gcc_assert (tmp_arch);
|
|
selected_arch = tmp_arch->arch;
|
|
+ aarch64_set_asm_isa_flags (tmp_flags);
|
|
return true;
|
|
}
|
|
|
|
@@ -18790,14 +18801,16 @@ aarch64_handle_attr_cpu (const char *str)
|
|
{
|
|
const struct processor *tmp_cpu = NULL;
|
|
std::string invalid_extension;
|
|
+ aarch64_feature_flags tmp_flags;
|
|
enum aarch64_parse_opt_result parse_res
|
|
- = aarch64_parse_cpu (str, &tmp_cpu, &aarch64_isa_flags, &invalid_extension);
|
|
+ = aarch64_parse_cpu (str, &tmp_cpu, &tmp_flags, &invalid_extension);
|
|
|
|
if (parse_res == AARCH64_PARSE_OK)
|
|
{
|
|
gcc_assert (tmp_cpu);
|
|
selected_tune = tmp_cpu->ident;
|
|
selected_arch = tmp_cpu->arch;
|
|
+ aarch64_set_asm_isa_flags (tmp_flags);
|
|
return true;
|
|
}
|
|
|
|
@@ -18891,7 +18904,7 @@ static bool
|
|
aarch64_handle_attr_isa_flags (char *str)
|
|
{
|
|
enum aarch64_parse_opt_result parse_res;
|
|
- auto isa_flags = aarch64_isa_flags;
|
|
+ auto isa_flags = aarch64_asm_isa_flags;
|
|
|
|
/* We allow "+nothing" in the beginning to clear out all architectural
|
|
features if the user wants to handpick specific features. */
|
|
@@ -18906,7 +18919,7 @@ aarch64_handle_attr_isa_flags (char *str)
|
|
|
|
if (parse_res == AARCH64_PARSE_OK)
|
|
{
|
|
- aarch64_isa_flags = isa_flags;
|
|
+ aarch64_set_asm_isa_flags (isa_flags);
|
|
return true;
|
|
}
|
|
|
|
@@ -19328,8 +19341,12 @@ aarch64_can_inline_p (tree caller, tree callee)
|
|
: target_option_default_node);
|
|
|
|
/* Callee's ISA flags should be a subset of the caller's. */
|
|
+ if ((caller_opts->x_aarch64_asm_isa_flags
|
|
+ & callee_opts->x_aarch64_asm_isa_flags)
|
|
+ != callee_opts->x_aarch64_asm_isa_flags)
|
|
+ return false;
|
|
if ((caller_opts->x_aarch64_isa_flags & callee_opts->x_aarch64_isa_flags)
|
|
- != callee_opts->x_aarch64_isa_flags)
|
|
+ != callee_opts->x_aarch64_isa_flags)
|
|
return false;
|
|
|
|
/* Allow non-strict aligned functions inlining into strict
|
|
@@ -22772,7 +22789,7 @@ aarch64_declare_function_name (FILE *stream, const char* name,
|
|
const struct processor *this_arch
|
|
= aarch64_get_arch (targ_options->x_selected_arch);
|
|
|
|
- auto isa_flags = targ_options->x_aarch64_isa_flags;
|
|
+ auto isa_flags = targ_options->x_aarch64_asm_isa_flags;
|
|
std::string extension
|
|
= aarch64_get_extension_string_for_isa_flags (isa_flags,
|
|
this_arch->flags);
|
|
@@ -22902,7 +22919,7 @@ aarch64_start_file (void)
|
|
|
|
const struct processor *default_arch
|
|
= aarch64_get_arch (default_options->x_selected_arch);
|
|
- auto default_isa_flags = default_options->x_aarch64_isa_flags;
|
|
+ auto default_isa_flags = default_options->x_aarch64_asm_isa_flags;
|
|
std::string extension
|
|
= aarch64_get_extension_string_for_isa_flags (default_isa_flags,
|
|
default_arch->flags);
|
|
diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
|
|
index 50a2ef444..521031efe 100644
|
|
--- a/gcc/config/aarch64/aarch64.h
|
|
+++ b/gcc/config/aarch64/aarch64.h
|
|
@@ -22,6 +22,17 @@
|
|
#ifndef GCC_AARCH64_H
|
|
#define GCC_AARCH64_H
|
|
|
|
+/* Make these flags read-only so that all uses go via
|
|
+ aarch64_set_asm_isa_flags. */
|
|
+#ifndef GENERATOR_FILE
|
|
+#undef aarch64_asm_isa_flags
|
|
+#define aarch64_asm_isa_flags \
|
|
+ ((aarch64_feature_flags) global_options.x_aarch64_asm_isa_flags)
|
|
+#undef aarch64_isa_flags
|
|
+#define aarch64_isa_flags \
|
|
+ ((aarch64_feature_flags) global_options.x_aarch64_isa_flags)
|
|
+#endif
|
|
+
|
|
/* Target CPU builtins. */
|
|
#define TARGET_CPU_CPP_BUILTINS() \
|
|
aarch64_cpu_cpp_builtins (pfile)
|
|
@@ -51,8 +62,8 @@
|
|
|
|
/* AdvSIMD is supported in the default configuration, unless disabled by
|
|
-mgeneral-regs-only or by the +nosimd extension. */
|
|
-#define TARGET_SIMD (!TARGET_GENERAL_REGS_ONLY && AARCH64_ISA_SIMD)
|
|
-#define TARGET_FLOAT (!TARGET_GENERAL_REGS_ONLY && AARCH64_ISA_FP)
|
|
+#define TARGET_SIMD (AARCH64_ISA_SIMD)
|
|
+#define TARGET_FLOAT (AARCH64_ISA_FP)
|
|
|
|
#define UNITS_PER_WORD 8
|
|
|
|
@@ -242,7 +253,7 @@ enum class aarch64_feature : unsigned char {
|
|
#define TARGET_DOTPROD (TARGET_SIMD && AARCH64_ISA_DOTPROD)
|
|
|
|
/* SVE instructions, enabled through +sve. */
|
|
-#define TARGET_SVE (!TARGET_GENERAL_REGS_ONLY && AARCH64_ISA_SVE)
|
|
+#define TARGET_SVE (AARCH64_ISA_SVE)
|
|
|
|
/* SVE2 instructions, enabled through +sve2. */
|
|
#define TARGET_SVE2 (TARGET_SVE && AARCH64_ISA_SVE2)
|
|
diff --git a/gcc/config/aarch64/aarch64.opt b/gcc/config/aarch64/aarch64.opt
|
|
index 47ec7824f..5f507abd4 100644
|
|
--- a/gcc/config/aarch64/aarch64.opt
|
|
+++ b/gcc/config/aarch64/aarch64.opt
|
|
@@ -27,6 +27,9 @@ enum aarch64_processor selected_tune = aarch64_none
|
|
TargetVariable
|
|
enum aarch64_arch selected_arch = aarch64_no_arch
|
|
|
|
+TargetVariable
|
|
+aarch64_feature_flags aarch64_asm_isa_flags = 0
|
|
+
|
|
TargetVariable
|
|
aarch64_feature_flags aarch64_isa_flags = 0
|
|
|
|
--
|
|
2.33.0
|
|
|