[gcc r16-6028] aarch64: Cache the PCS value for a function
Alfie Richards
alfierichards@gcc.gnu.org
Thu Dec 11 14:51:52 GMT 2025
https://gcc.gnu.org/g:765ca9133971c94e7a6b94be230aba6d8d00db4b
commit r16-6028-g765ca9133971c94e7a6b94be230aba6d8d00db4b
Author: Alfie Richards <alfie.richards@arm.com>
Date: Tue Nov 18 10:50:04 2025 +0000
aarch64: Cache the PCS value for a function
As aarch64_function_arg_regno_p is a very hot function called many times for a
function it should not call fndecl_abi every time as it is expensive and
unecessasary.
This caches the result and in doing so fixes a regression in compile time
introduced by r16-5076-g7197d8062fddc2.
gcc/ChangeLog:
* config/aarch64/aarch64.cc (aarch64_fndecl_abi): New function.
(aarch64_function_abi): New function.
(aarch64_function_arg_regno_p): Update to use aarch64_fndecl_abi.
(aarch64_output_mi_thunk): Likewise.
(aarch64_is_variant_pcs): Likewise.
(aarch64_set_current_function): Update to initialize pcs value.
* config/aarch64/aarch64.h (enum arm_pcs): Move location earlier in
file.
(machine_function) Add pcs value.
Diff:
---
gcc/config/aarch64/aarch64.cc | 40 ++++++++++++++++++++++++++++++++++++----
gcc/config/aarch64/aarch64.h | 42 ++++++++++++++++++++++--------------------
2 files changed, 58 insertions(+), 24 deletions(-)
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 0ef22e8e52c8..f4bef646a92a 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -736,6 +736,33 @@ aarch64_merge_string_arguments (tree args, tree old_attr,
return !use_old_attr;
}
+/* Get the PCS for a strcut function and store the result to avoid needing to
+ do too many calls to fndecl_abi which can be expensive. */
+
+static arm_pcs
+aarch64_function_abi (struct function *fun)
+{
+ gcc_assert (fun);
+ if (fun->machine->pcs == ARM_PCS_UNKNOWN)
+ fun->machine->pcs = arm_pcs (fndecl_abi (fun->decl).id ());
+
+ return fun->machine->pcs;
+}
+
+/* Get the PCS for a decl and store the result to avoid needing to do
+ too many calls to fndecl_abi which can be expensive. */
+
+static arm_pcs
+aarch64_fndecl_abi (tree fn)
+{
+ gcc_assert (TREE_CODE (fn) == FUNCTION_DECL);
+ struct function *fun = DECL_STRUCT_FUNCTION (fn);
+ if (!fun)
+ return arm_pcs (fndecl_abi (fn).id ());
+
+ return aarch64_function_abi (fun);
+}
+
/* Check whether an 'aarch64_vector_pcs' attribute is valid. */
static tree
@@ -7996,8 +8023,7 @@ function_arg_preserve_none_regno_p (unsigned regno)
bool
aarch64_function_arg_regno_p (unsigned regno)
{
- enum arm_pcs pcs
- = cfun ? (arm_pcs) fndecl_abi (cfun->decl).id () : ARM_PCS_AAPCS64;
+ enum arm_pcs pcs = cfun ? aarch64_function_abi (cfun) : ARM_PCS_AAPCS64;
switch (pcs)
{
@@ -10865,7 +10891,7 @@ aarch64_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
funexp = XEXP (DECL_RTL (function), 0);
funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
auto isa_mode = aarch64_fntype_isa_mode (TREE_TYPE (function));
- auto pcs_variant = arm_pcs (fndecl_abi (function).id ());
+ auto pcs_variant = aarch64_fndecl_abi (function);
bool ir = lookup_attribute ("indirect_return",
TYPE_ATTRIBUTES (TREE_TYPE (function)));
rtx callee_abi = aarch64_gen_callee_cookie (isa_mode, pcs_variant, ir);
@@ -19858,6 +19884,7 @@ aarch64_init_machine_status (void)
{
struct machine_function *machine;
machine = ggc_cleared_alloc<machine_function> ();
+ machine->pcs = ARM_PCS_UNKNOWN;
return machine;
}
@@ -20014,6 +20041,11 @@ aarch64_set_current_function (tree fndecl)
aarch64_previous_fndecl = fndecl;
+ /* Initialize the PCS value to UNKNOWN. */
+ if (fndecl && TREE_CODE (fndecl) == FUNCTION_DECL)
+ if (function *fn = DECL_STRUCT_FUNCTION (fndecl))
+ fn->machine->pcs = ARM_PCS_UNKNOWN;
+
/* First set the target options. */
cl_target_option_restore (&global_options, &global_options_set,
TREE_TARGET_OPTION (new_tree));
@@ -25821,7 +25853,7 @@ static bool
aarch64_is_variant_pcs (tree fndecl)
{
/* Check for ABIs that preserve more registers than usual. */
- arm_pcs pcs = (arm_pcs) fndecl_abi (fndecl).id ();
+ arm_pcs pcs = aarch64_fndecl_abi (fndecl);
if (pcs == ARM_PCS_SIMD || pcs == ARM_PCS_SVE || pcs == ARM_PCS_PRESERVE_NONE)
return true;
diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
index 5a1d5a94670f..073e57e2e371 100644
--- a/gcc/config/aarch64/aarch64.h
+++ b/gcc/config/aarch64/aarch64.h
@@ -989,6 +989,25 @@ extern enum aarch64_cpu aarch64_tune;
#define DEFAULT_PCC_STRUCT_RETURN 0
+/* The set of available Procedure Call Stardards. */
+
+enum arm_pcs
+{
+ ARM_PCS_AAPCS64, /* Base standard AAPCS for 64 bit. */
+ ARM_PCS_SIMD, /* For aarch64_vector_pcs functions. */
+ ARM_PCS_SVE, /* For functions that pass or return
+ values in SVE registers. */
+ ARM_PCS_TLSDESC, /* For targets of tlsdesc calls. */
+ ARM_PCS_PRESERVE_NONE, /* PCS variant with no call-preserved
+ registers except X29. */
+ ARM_PCS_MS_VARIADIC, /* PCS variant with no call-preserved
+ differently.
+ All composites are treated alike.
+ SIMD and floating-point registers
+ aren't used. */
+ ARM_PCS_UNKNOWN
+};
+
#if defined(HAVE_POLY_INT_H) && defined(GCC_VEC_H)
struct GTY (()) aarch64_frame
{
@@ -1159,6 +1178,9 @@ typedef struct GTY (()) machine_function
/* During SEH output, this is non-null. */
struct seh_frame_state * GTY ((skip (""))) seh;
+
+ /* The Procedure Call Standard for the function. */
+ enum arm_pcs pcs;
} machine_function;
#endif
#endif
@@ -1176,26 +1198,6 @@ enum aarch64_abi_type
#define TARGET_ILP32 (aarch64_abi & AARCH64_ABI_ILP32)
-enum arm_pcs
-{
- ARM_PCS_AAPCS64, /* Base standard AAPCS for 64 bit. */
- ARM_PCS_SIMD, /* For aarch64_vector_pcs functions. */
- ARM_PCS_SVE, /* For functions that pass or return
- values in SVE registers. */
- ARM_PCS_TLSDESC, /* For targets of tlsdesc calls. */
- ARM_PCS_PRESERVE_NONE, /* PCS variant with no call-preserved
- registers except X29. */
- ARM_PCS_MS_VARIADIC, /* PCS variant with no call-preserved
- differently.
- All composites are treated alike.
- SIMD and floating-point registers
- aren't used. */
- ARM_PCS_UNKNOWN
-};
-
-
-
-
/* We can't use machine_mode inside a generator file because it
hasn't been created yet; we shouldn't be using any code that
needs the real definition though, so this ought to be safe. */
More information about the Gcc-cvs
mailing list