mirror of git://gcc.gnu.org/git/gcc.git
aarch64.c (aarch64_simd_call_p): New function.
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. From-SVN: r267846
This commit is contained in:
parent
17a73b3c47
commit
b3650d40fa
|
|
@ -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>
|
2019-01-11 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
PR bootstrap/88714
|
PR bootstrap/88714
|
||||||
|
|
|
||||||
|
|
@ -1655,6 +1655,45 @@ aarch64_reg_save_mode (tree fndecl, unsigned regno)
|
||||||
: (aarch64_simd_decl_p (fndecl) ? E_TFmode : E_DFmode);
|
: (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
|
/* 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
|
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. */
|
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 \
|
#define TARGET_HARD_REGNO_CALL_PART_CLOBBERED \
|
||||||
aarch64_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
|
#undef TARGET_CONSTANT_ALIGNMENT
|
||||||
#define TARGET_CONSTANT_ALIGNMENT aarch64_constant_alignment
|
#define TARGET_CONSTANT_ALIGNMENT aarch64_constant_alignment
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1905,6 +1905,18 @@ The default implementation returns false, which is correct
|
||||||
for targets that don't have partly call-clobbered registers.
|
for targets that don't have partly call-clobbered registers.
|
||||||
@end deftypefn
|
@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 fixed_regs
|
||||||
@findex call_used_regs
|
@findex call_used_regs
|
||||||
@findex global_regs
|
@findex global_regs
|
||||||
|
|
|
||||||
|
|
@ -1707,6 +1707,8 @@ of @code{CALL_USED_REGISTERS}.
|
||||||
@cindex call-saved register
|
@cindex call-saved register
|
||||||
@hook TARGET_HARD_REGNO_CALL_PART_CLOBBERED
|
@hook TARGET_HARD_REGNO_CALL_PART_CLOBBERED
|
||||||
|
|
||||||
|
@hook TARGET_REMOVE_EXTRA_CALL_PRESERVED_REGS
|
||||||
|
|
||||||
@findex fixed_regs
|
@findex fixed_regs
|
||||||
@findex call_used_regs
|
@findex call_used_regs
|
||||||
@findex global_regs
|
@findex global_regs
|
||||||
|
|
|
||||||
|
|
@ -5095,7 +5095,7 @@ get_call_reg_set_usage (rtx_insn *insn, HARD_REG_SET *reg_set,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
COPY_HARD_REG_SET (*reg_set, default_set);
|
COPY_HARD_REG_SET (*reg_set, default_set);
|
||||||
|
targetm.remove_extra_call_preserved_regs (insn, reg_set);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5775,6 +5775,20 @@ for targets that don't have partly call-clobbered registers.",
|
||||||
bool, (unsigned int regno, machine_mode mode),
|
bool, (unsigned int regno, machine_mode mode),
|
||||||
hook_bool_uint_mode_false)
|
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
|
/* Return the smallest number of different values for which it is best to
|
||||||
use a jump-table instead of a tree of conditional branches. */
|
use a jump-table instead of a tree of conditional branches. */
|
||||||
DEFHOOK
|
DEFHOOK
|
||||||
|
|
|
||||||
|
|
@ -2374,4 +2374,9 @@ default_speculation_safe_value (machine_mode mode ATTRIBUTE_UNUSED,
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
default_remove_extra_call_preserved_regs (rtx_insn *, HARD_REG_SET *)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
#include "gt-targhooks.h"
|
#include "gt-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 default_have_speculation_safe_value (bool);
|
||||||
extern bool speculation_safe_value_not_needed (bool);
|
extern bool speculation_safe_value_not_needed (bool);
|
||||||
extern rtx default_speculation_safe_value (machine_mode, rtx, rtx, rtx);
|
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 */
|
#endif /* GCC_TARGHOOKS_H */
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue