diff --git a/gcc/common/config/aarch64/aarch64-common.cc b/gcc/common/config/aarch64/aarch64-common.cc index ef4458fb693..500bf784983 100644 --- a/gcc/common/config/aarch64/aarch64-common.cc +++ b/gcc/common/config/aarch64/aarch64-common.cc @@ -157,6 +157,8 @@ struct aarch64_extension_info aarch64_feature_flags flags_on; /* If this feature is turned off, these bits also need to be turned off. */ aarch64_feature_flags flags_off; + /* If this feature remains enabled, these bits must also remain enabled. */ + aarch64_feature_flags flags_required; }; /* ISA extensions in AArch64. */ @@ -164,9 +166,10 @@ static constexpr aarch64_extension_info all_extensions[] = { #define AARCH64_OPT_EXTENSION(NAME, IDENT, C, D, E, FEATURE_STRING) \ {NAME, AARCH64_FL_##IDENT, feature_deps::IDENT ().explicit_on, \ - feature_deps::get_flags_off (feature_deps::root_off_##IDENT)}, + feature_deps::get_flags_off (feature_deps::root_off_##IDENT), \ + feature_deps::IDENT ().enable}, #include "config/aarch64/aarch64-option-extensions.def" - {NULL, 0, 0, 0} + {NULL, 0, 0, 0, 0} }; struct aarch64_arch_info @@ -204,6 +207,18 @@ static constexpr aarch64_processor_info all_cores[] = {NULL, aarch64_no_cpu, aarch64_no_arch, 0} }; +/* Return the set of feature flags that are required to be enabled when the + features in FLAGS are enabled. */ + +aarch64_feature_flags +aarch64_get_required_features (aarch64_feature_flags flags) +{ + const struct aarch64_extension_info *opt; + for (opt = all_extensions; opt->name != NULL; opt++) + if (flags & opt->flag_canonical) + flags |= opt->flags_required; + return flags; +} /* Print a list of CANDIDATES for an argument, and try to suggest a specific close match. */ diff --git a/gcc/config/aarch64/aarch64-builtins.cc b/gcc/config/aarch64/aarch64-builtins.cc index 128cc365d3d..93f939a9c83 100644 --- a/gcc/config/aarch64/aarch64-builtins.cc +++ b/gcc/config/aarch64/aarch64-builtins.cc @@ -43,6 +43,7 @@ #include "langhooks.h" #include "gimple-iterator.h" #include "case-cfn-macros.h" +#include "regs.h" #include "emit-rtl.h" #include "stringpool.h" #include "attribs.h" @@ -1877,23 +1878,42 @@ aarch64_scalar_builtin_type_p (aarch64_simd_type t) return (t == Poly8_t || t == Poly16_t || t == Poly64_t || t == Poly128_t); } -/* Enable AARCH64_FL_* flags EXTRA_FLAGS on top of the base Advanced SIMD - set. */ -aarch64_simd_switcher::aarch64_simd_switcher (aarch64_feature_flags extra_flags) +/* Temporarily set FLAGS as the enabled target features. */ +aarch64_target_switcher::aarch64_target_switcher (aarch64_feature_flags flags) : m_old_asm_isa_flags (aarch64_asm_isa_flags), - m_old_general_regs_only (TARGET_GENERAL_REGS_ONLY) + m_old_general_regs_only (TARGET_GENERAL_REGS_ONLY), + m_old_target_pragma (current_target_pragma) { - /* Changing the ISA flags should be enough here. We shouldn't need to - pay the compile-time cost of a full target switch. */ - global_options.x_target_flags &= ~MASK_GENERAL_REGS_ONLY; - aarch64_set_asm_isa_flags (AARCH64_FL_FP | AARCH64_FL_SIMD | extra_flags); + /* Include all dependencies. */ + flags = aarch64_get_required_features (flags); + + /* Changing the ISA flags and have_regs_of_mode should be enough here. We + shouldn't need to pay the compile-time cost of a full target switch. */ + if (flags & AARCH64_FL_FP) + global_options.x_target_flags &= ~MASK_GENERAL_REGS_ONLY; + aarch64_set_asm_isa_flags (flags); + + /* Target pragmas are irrelevant when defining intrinsics artificially. */ + current_target_pragma = NULL_TREE; + + /* Ensure SVE regs are available if SVE or SME is enabled. */ + memcpy (m_old_have_regs_of_mode, have_regs_of_mode, sizeof + (have_regs_of_mode)); + if (flags & (AARCH64_FL_SVE | AARCH64_FL_SME)) + for (int i = 0; i < NUM_MACHINE_MODES; ++i) + if (aarch64_sve_mode_p ((machine_mode) i)) + have_regs_of_mode[i] = true; } -aarch64_simd_switcher::~aarch64_simd_switcher () +aarch64_target_switcher::~aarch64_target_switcher () { if (m_old_general_regs_only) global_options.x_target_flags |= MASK_GENERAL_REGS_ONLY; aarch64_set_asm_isa_flags (m_old_asm_isa_flags); + current_target_pragma = m_old_target_pragma; + + memcpy (have_regs_of_mode, m_old_have_regs_of_mode, + sizeof (have_regs_of_mode)); } /* Implement #pragma GCC aarch64 "arm_neon.h". @@ -1903,7 +1923,7 @@ aarch64_simd_switcher::~aarch64_simd_switcher () void handle_arm_neon_h (void) { - aarch64_simd_switcher simd; + aarch64_target_switcher switcher (AARCH64_FL_SIMD); /* Register the AdvSIMD vector tuple types. */ for (unsigned int i = 0; i < ARM_NEON_H_TYPES_LAST; i++) @@ -2353,6 +2373,8 @@ aarch64_init_data_intrinsics (void) void handle_arm_acle_h (void) { + aarch64_target_switcher switcher; + aarch64_init_ls64_builtins (); aarch64_init_tme_builtins (); aarch64_init_memtag_builtins (); @@ -2446,7 +2468,7 @@ aarch64_general_init_builtins (void) aarch64_init_bf16_types (); { - aarch64_simd_switcher simd; + aarch64_target_switcher switcher (AARCH64_FL_SIMD); aarch64_init_simd_builtins (); } diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h index 0291a8aa761..8f44aea2367 100644 --- a/gcc/config/aarch64/aarch64-protos.h +++ b/gcc/config/aarch64/aarch64-protos.h @@ -733,15 +733,17 @@ const unsigned int AARCH64_BUILTIN_CLASS = (1 << AARCH64_BUILTIN_SHIFT) - 1; /* RAII class for enabling enough features to define built-in types and implement the arm_neon.h pragma. */ -class aarch64_simd_switcher +class aarch64_target_switcher { public: - aarch64_simd_switcher (aarch64_feature_flags extra_flags = 0); - ~aarch64_simd_switcher (); + aarch64_target_switcher (aarch64_feature_flags flags = 0); + ~aarch64_target_switcher (); private: aarch64_feature_flags m_old_asm_isa_flags; bool m_old_general_regs_only; + tree m_old_target_pragma; + bool m_old_have_regs_of_mode[MAX_MACHINE_MODE]; }; /* Represents the ISA requirements of an intrinsic function, or of some @@ -1190,6 +1192,7 @@ void aarch64_set_asm_isa_flags (aarch64_feature_flags); 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); +aarch64_feature_flags aarch64_get_required_features (aarch64_feature_flags); void aarch64_print_hint_for_extensions (const char *); void aarch64_print_hint_for_arch (const char *); void aarch64_print_hint_for_core (const char *); diff --git a/gcc/config/aarch64/aarch64-sve-builtins.cc b/gcc/config/aarch64/aarch64-sve-builtins.cc index 5d2062726d6..44e4807325a 100644 --- a/gcc/config/aarch64/aarch64-sve-builtins.cc +++ b/gcc/config/aarch64/aarch64-sve-builtins.cc @@ -42,7 +42,6 @@ #include "emit-rtl.h" #include "tree-vector-builder.h" #include "stor-layout.h" -#include "regs.h" #include "alias.h" #include "gimple-fold.h" #include "langhooks.h" @@ -1296,26 +1295,14 @@ registered_function_hasher::equal (value_type value, const compare_type &key) return value->instance == key; } -sve_switcher::sve_switcher (aarch64_feature_flags flags) - : aarch64_simd_switcher (AARCH64_FL_F16 | AARCH64_FL_SVE | flags) +sve_alignment_switcher::sve_alignment_switcher () { - /* Changing the ISA flags and have_regs_of_mode should be enough here. - We shouldn't need to pay the compile-time cost of a full target - switch. */ m_old_maximum_field_alignment = maximum_field_alignment; maximum_field_alignment = 0; - - memcpy (m_old_have_regs_of_mode, have_regs_of_mode, - sizeof (have_regs_of_mode)); - for (int i = 0; i < NUM_MACHINE_MODES; ++i) - if (aarch64_sve_mode_p ((machine_mode) i)) - have_regs_of_mode[i] = true; } -sve_switcher::~sve_switcher () +sve_alignment_switcher::~sve_alignment_switcher () { - memcpy (have_regs_of_mode, m_old_have_regs_of_mode, - sizeof (have_regs_of_mode)); maximum_field_alignment = m_old_maximum_field_alignment; } @@ -4652,6 +4639,8 @@ register_type_decl (tree type, const char *name) static void register_builtin_types () { + sve_alignment_switcher switcher; + #define DEF_SVE_TYPE(ACLE_NAME, NCHARS, ABI_NAME, SCALAR_TYPE) \ scalar_types[VECTOR_TYPE_ ## ACLE_NAME] = SCALAR_TYPE; #include "aarch64-sve-builtins.def" @@ -4726,7 +4715,7 @@ register_builtin_types () void init_builtins () { - sve_switcher sve; + aarch64_target_switcher switcher (AARCH64_FL_SVE); register_builtin_types (); if (in_lto_p) { @@ -4842,7 +4831,8 @@ handle_arm_sve_h (bool function_nulls_p) return; } - sve_switcher sve; + aarch64_target_switcher switcher (AARCH64_FL_SVE); + sve_alignment_switcher alignment_switcher; /* Define the vector and tuple types. */ for (unsigned int type_i = 0; type_i < NUM_VECTOR_TYPES; ++type_i) @@ -4873,6 +4863,8 @@ handle_arm_neon_sve_bridge_h (bool function_nulls_p) if (initial_indexes[arm_sme_handle] == 0) handle_arm_sme_h (true); + aarch64_target_switcher switcher; + /* Define the functions. */ function_builder builder (arm_neon_sve_handle, function_nulls_p); for (unsigned int i = 0; i < ARRAY_SIZE (neon_sve_function_groups); ++i) @@ -4900,7 +4892,7 @@ handle_arm_sme_h (bool function_nulls_p) return; } - sme_switcher sme; + aarch64_target_switcher switcher (AARCH64_FL_SME); function_builder builder (arm_sme_handle, function_nulls_p); for (unsigned int i = 0; i < ARRAY_SIZE (sme_function_groups); ++i) diff --git a/gcc/config/aarch64/aarch64-sve-builtins.h b/gcc/config/aarch64/aarch64-sve-builtins.h index 54d213dfe6e..c145b8065ae 100644 --- a/gcc/config/aarch64/aarch64-sve-builtins.h +++ b/gcc/config/aarch64/aarch64-sve-builtins.h @@ -822,24 +822,17 @@ public: virtual bool check (function_checker &) const { return true; } }; -/* RAII class for enabling enough SVE features to define the built-in - types and implement the arm_sve.h pragma. */ -class sve_switcher : public aarch64_simd_switcher +/* RAII class for temporarily disabling the effect of any -fpack-struct option. + This is used to ensure that sve vector tuple types are defined with the + correct alignment. */ +class sve_alignment_switcher { public: - sve_switcher (aarch64_feature_flags = 0); - ~sve_switcher (); + sve_alignment_switcher (); + ~sve_alignment_switcher (); private: unsigned int m_old_maximum_field_alignment; - bool m_old_have_regs_of_mode[MAX_MACHINE_MODE]; -}; - -/* Extends sve_switch enough for defining arm_sme.h. */ -class sme_switcher : public sve_switcher -{ -public: - sme_switcher () : sve_switcher (AARCH64_FL_SME) {} }; extern const type_suffix_info type_suffixes[NUM_TYPE_SUFFIXES + 1]; diff --git a/gcc/config/aarch64/t-aarch64 b/gcc/config/aarch64/t-aarch64 index 5aa77809948..59571948479 100644 --- a/gcc/config/aarch64/t-aarch64 +++ b/gcc/config/aarch64/t-aarch64 @@ -50,7 +50,7 @@ endif s-mddeps: s-aarch64-tune-md aarch64-builtins.o: $(srcdir)/config/aarch64/aarch64-builtins.cc $(CONFIG_H) \ - $(SYSTEM_H) coretypes.h $(TM_H) \ + $(SYSTEM_H) coretypes.h $(TM_H) $(REGS_H) \ $(RTL_H) $(TREE_H) expr.h $(TM_P_H) $(RECOG_H) langhooks.h \ $(DIAGNOSTIC_CORE_H) $(OPTABS_H) \ $(srcdir)/config/aarch64/aarch64-simd-builtins.def \ @@ -69,7 +69,7 @@ aarch64-sve-builtins.o: $(srcdir)/config/aarch64/aarch64-sve-builtins.cc \ $(TM_P_H) memmodel.h insn-codes.h $(OPTABS_H) $(RECOG_H) $(DIAGNOSTIC_H) \ $(EXPR_H) $(BASIC_BLOCK_H) $(FUNCTION_H) fold-const.h $(GIMPLE_H) \ gimple-iterator.h gimplify.h explow.h $(EMIT_RTL_H) tree-vector-builder.h \ - stor-layout.h $(REG_H) alias.h gimple-fold.h langhooks.h \ + stor-layout.h alias.h gimple-fold.h langhooks.h \ stringpool.h \ $(srcdir)/config/aarch64/aarch64-sve-builtins.h \ $(srcdir)/config/aarch64/aarch64-sve-builtins-shapes.h \