From b3650d40fab1ed168be0109372ec49fcff95a18b Mon Sep 17 00:00:00 2001 From: Steve Ellcey Date: Fri, 11 Jan 2019 15:53:02 +0000 Subject: [PATCH] aarch64.c (aarch64_simd_call_p): New function. 2019-01-11 Steve Ellcey * config/aarch64/aarch64.c (aarch64_simd_call_p): New function. (aarch64_remove_extra_call_preserved_regs): New function. (TARGET_REMOVE_EXTRA_CALL_PRESERVED_REGS): New macro. * doc/tm.texi.in (TARGET_REMOVE_EXTRA_CALL_PRESERVED_REGS): New hook. * doc/tm.texi: Regenerate. * final.c (get_call_reg_set_usage): Call new hook. * target.def (remove_extra_call_preserved_regs): New hook. * targhooks.c (default_remove_extra_call_preserved_regs): New function. * targhooks.h (default_remove_extra_call_preserved_regs): New function. From-SVN: r267846 --- gcc/ChangeLog | 12 ++++++++++ gcc/config/aarch64/aarch64.c | 43 ++++++++++++++++++++++++++++++++++++ gcc/doc/tm.texi | 12 ++++++++++ gcc/doc/tm.texi.in | 2 ++ gcc/final.c | 2 +- gcc/target.def | 14 ++++++++++++ gcc/targhooks.c | 5 +++++ gcc/targhooks.h | 2 ++ 8 files changed, 91 insertions(+), 1 deletion(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 13b178471e0..4b5a67a857a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2019-01-11 Steve Ellcey + + * config/aarch64/aarch64.c (aarch64_simd_call_p): New function. + (aarch64_remove_extra_call_preserved_regs): New function. + (TARGET_REMOVE_EXTRA_CALL_PRESERVED_REGS): New macro. + * doc/tm.texi.in (TARGET_REMOVE_EXTRA_CALL_PRESERVED_REGS): New hook. + * doc/tm.texi: Regenerate. + * final.c (get_call_reg_set_usage): Call new hook. + * target.def (remove_extra_call_preserved_regs): New hook. + * targhooks.c (default_remove_extra_call_preserved_regs): New function. + * targhooks.h (default_remove_extra_call_preserved_regs): New function. + 2019-01-11 Jakub Jelinek PR bootstrap/88714 diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index 1c300af19bc..588fc80bbd7 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -1655,6 +1655,45 @@ aarch64_reg_save_mode (tree fndecl, unsigned regno) : (aarch64_simd_decl_p (fndecl) ? E_TFmode : E_DFmode); } +/* Return true if the instruction is a call to a SIMD function, false + if it is not a SIMD function or if we do not know anything about + the function. */ + +static bool +aarch64_simd_call_p (rtx_insn *insn) +{ + rtx symbol; + rtx call; + tree fndecl; + + gcc_assert (CALL_P (insn)); + call = get_call_rtx_from (insn); + symbol = XEXP (XEXP (call, 0), 0); + if (GET_CODE (symbol) != SYMBOL_REF) + return false; + fndecl = SYMBOL_REF_DECL (symbol); + if (!fndecl) + return false; + + return aarch64_simd_decl_p (fndecl); +} + +/* Implement TARGET_REMOVE_EXTRA_CALL_PRESERVED_REGS. If INSN calls + a function that uses the SIMD ABI, take advantage of the extra + call-preserved registers that the ABI provides. */ + +void +aarch64_remove_extra_call_preserved_regs (rtx_insn *insn, + HARD_REG_SET *return_set) +{ + if (aarch64_simd_call_p (insn)) + { + for (int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) + if (FP_SIMD_SAVED_REGNUM_P (regno)) + CLEAR_HARD_REG_BIT (*return_set, regno); + } +} + /* Implement TARGET_HARD_REGNO_CALL_PART_CLOBBERED. The callee only saves the lower 64 bits of a 128-bit register. Tell the compiler the callee clobbers the top 64 bits when restoring the bottom 64 bits. */ @@ -18825,6 +18864,10 @@ aarch64_libgcc_floating_mode_supported_p #define TARGET_HARD_REGNO_CALL_PART_CLOBBERED \ aarch64_hard_regno_call_part_clobbered +#undef TARGET_REMOVE_EXTRA_CALL_PRESERVED_REGS +#define TARGET_REMOVE_EXTRA_CALL_PRESERVED_REGS \ + aarch64_remove_extra_call_preserved_regs + #undef TARGET_CONSTANT_ALIGNMENT #define TARGET_CONSTANT_ALIGNMENT aarch64_constant_alignment diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index ddde4a7287b..daf29f046c3 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -1905,6 +1905,18 @@ The default implementation returns false, which is correct for targets that don't have partly call-clobbered registers. @end deftypefn +@deftypefn {Target Hook} void TARGET_REMOVE_EXTRA_CALL_PRESERVED_REGS (rtx_insn *@var{insn}, HARD_REG_SET *@var{used_regs}) +This hook removes registers from the set of call-clobbered registers + in @var{used_regs} if, contrary to the default rules, something guarantees + that @samp{insn} preserves those registers. For example, some targets + support variant ABIs in which functions preserve more registers than + normal functions would. Removing those extra registers from @var{used_regs} + can lead to better register allocation. + + The default implementation does nothing, which is always safe. + Defining the hook is purely an optimization. +@end deftypefn + @findex fixed_regs @findex call_used_regs @findex global_regs diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in index 976a7009fa6..d9f40a1a5f3 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -1707,6 +1707,8 @@ of @code{CALL_USED_REGISTERS}. @cindex call-saved register @hook TARGET_HARD_REGNO_CALL_PART_CLOBBERED +@hook TARGET_REMOVE_EXTRA_CALL_PRESERVED_REGS + @findex fixed_regs @findex call_used_regs @findex global_regs diff --git a/gcc/final.c b/gcc/final.c index 6dc1cd1b0c8..f6edd6a1dfc 100644 --- a/gcc/final.c +++ b/gcc/final.c @@ -5095,7 +5095,7 @@ get_call_reg_set_usage (rtx_insn *insn, HARD_REG_SET *reg_set, return true; } } - COPY_HARD_REG_SET (*reg_set, default_set); + targetm.remove_extra_call_preserved_regs (insn, reg_set); return false; } diff --git a/gcc/target.def b/gcc/target.def index 2aeb1ff8445..e361c41d3de 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -5775,6 +5775,20 @@ for targets that don't have partly call-clobbered registers.", bool, (unsigned int regno, machine_mode mode), hook_bool_uint_mode_false) +DEFHOOK +(remove_extra_call_preserved_regs, + "This hook removes registers from the set of call-clobbered registers\n\ + in @var{used_regs} if, contrary to the default rules, something guarantees\n\ + that @samp{insn} preserves those registers. For example, some targets\n\ + support variant ABIs in which functions preserve more registers than\n\ + normal functions would. Removing those extra registers from @var{used_regs}\n\ + can lead to better register allocation.\n\ + \n\ + The default implementation does nothing, which is always safe.\n\ + Defining the hook is purely an optimization.", + void, (rtx_insn *insn, HARD_REG_SET *used_regs), + default_remove_extra_call_preserved_regs) + /* Return the smallest number of different values for which it is best to use a jump-table instead of a tree of conditional branches. */ DEFHOOK diff --git a/gcc/targhooks.c b/gcc/targhooks.c index 898848f6a82..6bd9767b469 100644 --- a/gcc/targhooks.c +++ b/gcc/targhooks.c @@ -2374,4 +2374,9 @@ default_speculation_safe_value (machine_mode mode ATTRIBUTE_UNUSED, return result; } +void +default_remove_extra_call_preserved_regs (rtx_insn *, HARD_REG_SET *) +{ +} + #include "gt-targhooks.h" diff --git a/gcc/targhooks.h b/gcc/targhooks.h index 3b6e404f080..01ee0be3c92 100644 --- a/gcc/targhooks.h +++ b/gcc/targhooks.h @@ -284,5 +284,7 @@ extern tree default_preferred_else_value (unsigned, tree, unsigned, tree *); extern bool default_have_speculation_safe_value (bool); extern bool speculation_safe_value_not_needed (bool); extern rtx default_speculation_safe_value (machine_mode, rtx, rtx, rtx); +extern void default_remove_extra_call_preserved_regs (rtx_insn *, + HARD_REG_SET *); #endif /* GCC_TARGHOOKS_H */ -- 2.30.2