From: Alfie Richards Date: Tue, 18 Nov 2025 10:50:04 +0000 (+0000) Subject: aarch64: Cache the PCS value for a function X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=765ca9133971c94e7a6b94be230aba6d8d00db4b;p=thirdparty%2Fgcc.git 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 --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc index 0ef22e8e52c..f4bef646a92 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->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 5a1d5a94670..073e57e2e37 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. */