]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
aarch64: Cache the PCS value for a function
authorAlfie Richards <alfie.richards@arm.com>
Tue, 18 Nov 2025 10:50:04 +0000 (10:50 +0000)
committerAlfie Richards <alfie.richards@arm.com>
Thu, 11 Dec 2025 14:51:11 +0000 (14:51 +0000)
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.

gcc/config/aarch64/aarch64.cc
gcc/config/aarch64/aarch64.h

index 0ef22e8e52c85696002b9b1f89de2774a48f36a6..f4bef646a92a21ff803a0f1760ddc202f12a23de 100644 (file)
@@ -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;
 
index 5a1d5a94670fd6b42c195b81dd0902e961b875f7..073e57e2e3712acda08e9f21c778036cee4078e7 100644 (file)
@@ -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.  */