summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog12
-rw-r--r--gcc/config/aarch64/aarch64.c43
-rw-r--r--gcc/doc/tm.texi12
-rw-r--r--gcc/doc/tm.texi.in2
-rw-r--r--gcc/final.c2
-rw-r--r--gcc/target.def14
-rw-r--r--gcc/targhooks.c5
-rw-r--r--gcc/targhooks.h2
8 files changed, 91 insertions, 1 deletions
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 <sellcey@marvell.com>
+
+ * 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 <jakub@redhat.com>
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 */