aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@arm.com>2019-09-30 16:19:59 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2019-09-30 16:19:59 +0000
commit6ee2cc70024253d2670a4a317158b2a65251a1d1 (patch)
tree7ceef0efbbe69d1fadfdd5ab9b202832d6239868
parent2a2e3a0dfcbe0861915f421d11b828f0c35023f0 (diff)
downloadgcc-6ee2cc70024253d2670a4a317158b2a65251a1d1.zip
gcc-6ee2cc70024253d2670a4a317158b2a65251a1d1.tar.gz
gcc-6ee2cc70024253d2670a4a317158b2a65251a1d1.tar.bz2
Pass an ABI identifier to hard_regno_call_part_clobbered
This patch replaces the rtx_insn argument to targetm.hard_regno_call_part_clobbered with an ABI identifier, since call insns are now just one possible way of getting an ABI handle. This in turn allows predefined_function_abi::initialize to do the right thing for non-default ABIs. The horrible ?: in need_for_call_save_p goes away in a later patch, with the series as a whole removing most direct calls to the hook in favour of function_abi operations. 2019-09-30 Richard Sandiford <richard.sandiford@arm.com> gcc/ * target.def (hard_regno_call_part_clobbered): Take an ABI identifier instead of an rtx_insn. * doc/tm.texi: Regenerate. * hooks.h (hook_bool_insn_uint_mode_false): Delete. (hook_bool_uint_uint_mode_false): New function. * hooks.c (hook_bool_insn_uint_mode_false): Delete. (hook_bool_uint_uint_mode_false): New function. * config/aarch64/aarch64.c (aarch64_hard_regno_call_part_clobbered): Take an ABI identifier instead of an rtx_insn. * config/avr/avr.c (avr_hard_regno_call_part_clobbered): Likewise. * config/i386/i386.c (ix86_hard_regno_call_part_clobbered): Likewise. * config/mips/mips.c (mips_hard_regno_call_part_clobbered): Likewise. * config/pru/pru.c (pru_hard_regno_call_part_clobbered): Likewise. * config/rs6000/rs6000.c (rs6000_hard_regno_call_part_clobbered): Likewise. * config/s390/s390.c (s390_hard_regno_call_part_clobbered): Likewise. * cselib.c: Include function-abi.h. (cselib_process_insn): Update call to targetm.hard_regno_call_part_clobbered, using insn_callee_abi to get the appropriate ABI identifier. * function-abi.cc (predefined_function_abi::initialize): Update call to targetm.hard_regno_call_part_clobbered. * ira-conflicts.c (ira_build_conflicts): Likewise. * ira-costs.c (ira_tune_allocno_costs): Likewise. * lra-constraints.c: Include function-abi.h. (need_for_call_save_p): Update call to targetm.hard_regno_call_part_clobbered, using insn_callee_abi to get the appropriate ABI identifier. * lra-lives.c (check_pseudos_live_through_calls): Likewise. * regcprop.c (copyprop_hardreg_forward_1): Update call to targetm.hard_regno_call_part_clobbered. * reginfo.c (choose_hard_reg_mode): Likewise. * regrename.c (check_new_reg_p): Likewise. * reload.c (find_equiv_reg): Likewise. * reload1.c (emit_reload_insns): Likewise. * sched-deps.c: Include function-abi.h. (deps_analyze_insn): Update call to targetm.hard_regno_call_part_clobbered, using insn_callee_abi to get the appropriate ABI identifier. * sel-sched.c (init_regs_for_mode, mark_unavailable_hard_regs): Update call to targetm.hard_regno_call_part_clobbered. * targhooks.c (default_dwarf_frame_reg_mode): Likewise. From-SVN: r276311
-rw-r--r--gcc/ChangeLog45
-rw-r--r--gcc/config/aarch64/aarch64.c5
-rw-r--r--gcc/config/avr/avr.c4
-rw-r--r--gcc/config/i386/i386.c4
-rw-r--r--gcc/config/mips/mips.c4
-rw-r--r--gcc/config/pru/pru.c4
-rw-r--r--gcc/config/rs6000/rs6000.c4
-rw-r--r--gcc/config/s390/s390.c4
-rw-r--r--gcc/cselib.c5
-rw-r--r--gcc/doc/tm.texi25
-rw-r--r--gcc/function-abi.cc8
-rw-r--r--gcc/hooks.c3
-rw-r--r--gcc/hooks.h2
-rw-r--r--gcc/ira-conflicts.c2
-rw-r--r--gcc/ira-costs.c2
-rw-r--r--gcc/lra-constraints.c4
-rw-r--r--gcc/lra-lives.c4
-rw-r--r--gcc/regcprop.c2
-rw-r--r--gcc/reginfo.c10
-rw-r--r--gcc/regrename.c4
-rw-r--r--gcc/reload.c4
-rw-r--r--gcc/reload1.c8
-rw-r--r--gcc/sched-deps.c6
-rw-r--r--gcc/sel-sched.c4
-rw-r--r--gcc/target.def27
-rw-r--r--gcc/targhooks.c2
26 files changed, 132 insertions, 64 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index acdcd91..59bfeb2 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,50 @@
2019-09-30 Richard Sandiford <richard.sandiford@arm.com>
+ * target.def (hard_regno_call_part_clobbered): Take an ABI
+ identifier instead of an rtx_insn.
+ * doc/tm.texi: Regenerate.
+ * hooks.h (hook_bool_insn_uint_mode_false): Delete.
+ (hook_bool_uint_uint_mode_false): New function.
+ * hooks.c (hook_bool_insn_uint_mode_false): Delete.
+ (hook_bool_uint_uint_mode_false): New function.
+ * config/aarch64/aarch64.c (aarch64_hard_regno_call_part_clobbered):
+ Take an ABI identifier instead of an rtx_insn.
+ * config/avr/avr.c (avr_hard_regno_call_part_clobbered): Likewise.
+ * config/i386/i386.c (ix86_hard_regno_call_part_clobbered): Likewise.
+ * config/mips/mips.c (mips_hard_regno_call_part_clobbered): Likewise.
+ * config/pru/pru.c (pru_hard_regno_call_part_clobbered): Likewise.
+ * config/rs6000/rs6000.c (rs6000_hard_regno_call_part_clobbered):
+ Likewise.
+ * config/s390/s390.c (s390_hard_regno_call_part_clobbered): Likewise.
+ * cselib.c: Include function-abi.h.
+ (cselib_process_insn): Update call to
+ targetm.hard_regno_call_part_clobbered, using insn_callee_abi
+ to get the appropriate ABI identifier.
+ * function-abi.cc (predefined_function_abi::initialize): Update call
+ to targetm.hard_regno_call_part_clobbered.
+ * ira-conflicts.c (ira_build_conflicts): Likewise.
+ * ira-costs.c (ira_tune_allocno_costs): Likewise.
+ * lra-constraints.c: Include function-abi.h.
+ (need_for_call_save_p): Update call to
+ targetm.hard_regno_call_part_clobbered, using insn_callee_abi
+ to get the appropriate ABI identifier.
+ * lra-lives.c (check_pseudos_live_through_calls): Likewise.
+ * regcprop.c (copyprop_hardreg_forward_1): Update call
+ to targetm.hard_regno_call_part_clobbered.
+ * reginfo.c (choose_hard_reg_mode): Likewise.
+ * regrename.c (check_new_reg_p): Likewise.
+ * reload.c (find_equiv_reg): Likewise.
+ * reload1.c (emit_reload_insns): Likewise.
+ * sched-deps.c: Include function-abi.h.
+ (deps_analyze_insn): Update call to
+ targetm.hard_regno_call_part_clobbered, using insn_callee_abi
+ to get the appropriate ABI identifier.
+ * sel-sched.c (init_regs_for_mode, mark_unavailable_hard_regs): Update
+ call to targetm.hard_regno_call_part_clobbered.
+ * targhooks.c (default_dwarf_frame_reg_mode): Likewise.
+
+2019-09-30 Richard Sandiford <richard.sandiford@arm.com>
+
* config/i386/i386.c: Include function-abi.h.
(ix86_avx_u128_mode_needed): Treat function calls as AVX_U128_ANY
if they preserve some 256-bit or 512-bit SSE registers.
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 71cdce3..ca4c183 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -1910,12 +1910,13 @@ aarch64_insn_callee_abi (const rtx_insn *insn)
clobbers the top 64 bits when restoring the bottom 64 bits. */
static bool
-aarch64_hard_regno_call_part_clobbered (rtx_insn *insn, unsigned int regno,
+aarch64_hard_regno_call_part_clobbered (unsigned int abi_id,
+ unsigned int regno,
machine_mode mode)
{
if (FP_REGNUM_P (regno))
{
- bool simd_p = insn && CALL_P (insn) && aarch64_simd_call_p (insn);
+ bool simd_p = (abi_id == ARM_PCS_SIMD);
poly_int64 per_register_size = GET_MODE_SIZE (mode);
unsigned int nregs = hard_regno_nregs (regno, mode);
if (nregs > 1)
diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c
index 04fc00f..3ccff8e 100644
--- a/gcc/config/avr/avr.c
+++ b/gcc/config/avr/avr.c
@@ -12164,8 +12164,8 @@ avr_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
/* Implement TARGET_HARD_REGNO_CALL_PART_CLOBBERED. */
static bool
-avr_hard_regno_call_part_clobbered (rtx_insn *insn ATTRIBUTE_UNUSED,
- unsigned regno, machine_mode mode)
+avr_hard_regno_call_part_clobbered (unsigned, unsigned regno,
+ machine_mode mode)
{
/* FIXME: This hook gets called with MODE:REGNO combinations that don't
represent valid hard registers like, e.g. HI:29. Returning TRUE
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index a13aef8..8af4bc5 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -18794,8 +18794,8 @@ ix86_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
the low 16 bytes are saved. */
static bool
-ix86_hard_regno_call_part_clobbered (rtx_insn *insn ATTRIBUTE_UNUSED,
- unsigned int regno, machine_mode mode)
+ix86_hard_regno_call_part_clobbered (unsigned int, unsigned int regno,
+ machine_mode mode)
{
return SSE_REGNO_P (regno) && GET_MODE_SIZE (mode) > 16;
}
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index c682ebd..91dd94b 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -12928,8 +12928,8 @@ mips_hard_regno_scratch_ok (unsigned int regno)
registers with MODE > 64 bits are part clobbered too. */
static bool
-mips_hard_regno_call_part_clobbered (rtx_insn *insn ATTRIBUTE_UNUSED,
- unsigned int regno, machine_mode mode)
+mips_hard_regno_call_part_clobbered (unsigned int, unsigned int regno,
+ machine_mode mode)
{
if (TARGET_FLOATXX
&& hard_regno_nregs (regno, mode) == 1
diff --git a/gcc/config/pru/pru.c b/gcc/config/pru/pru.c
index 416399e..16d1451 100644
--- a/gcc/config/pru/pru.c
+++ b/gcc/config/pru/pru.c
@@ -559,8 +559,8 @@ pru_hard_regno_scratch_ok (unsigned int regno)
/* Implement TARGET_HARD_REGNO_CALL_PART_CLOBBERED. */
static bool
-pru_hard_regno_call_part_clobbered (rtx_insn *insn ATTRIBUTE_UNUSED,
- unsigned regno, machine_mode mode)
+pru_hard_regno_call_part_clobbered (unsigned, unsigned regno,
+ machine_mode mode)
{
HARD_REG_SET caller_saved_set;
HARD_REG_SET callee_saved_set;
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index d6e1fea..330e249 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -1946,8 +1946,8 @@ rs6000_modes_tieable_p (machine_mode mode1, machine_mode mode2)
/* Implement TARGET_HARD_REGNO_CALL_PART_CLOBBERED. */
static bool
-rs6000_hard_regno_call_part_clobbered (rtx_insn *insn ATTRIBUTE_UNUSED,
- unsigned int regno, machine_mode mode)
+rs6000_hard_regno_call_part_clobbered (unsigned int, unsigned int regno,
+ machine_mode mode)
{
if (TARGET_32BIT
&& TARGET_POWERPC64
diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index cfdfa4e..1764c34 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -10297,8 +10297,8 @@ s390_hard_regno_scratch_ok (unsigned int regno)
bytes are saved across calls, however. */
static bool
-s390_hard_regno_call_part_clobbered (rtx_insn *insn ATTRIBUTE_UNUSED,
- unsigned int regno, machine_mode mode)
+s390_hard_regno_call_part_clobbered (unsigned int, unsigned int regno,
+ machine_mode mode)
{
if (!TARGET_64BIT
&& TARGET_ZARCH
diff --git a/gcc/cselib.c b/gcc/cselib.c
index 109cc27..5de14a0 100644
--- a/gcc/cselib.c
+++ b/gcc/cselib.c
@@ -32,6 +32,7 @@ along with GCC; see the file COPYING3. If not see
#include "dumpfile.h"
#include "cselib.h"
#include "params.h"
+#include "function-abi.h"
/* A list of cselib_val structures. */
struct elt_list
@@ -2765,11 +2766,13 @@ cselib_process_insn (rtx_insn *insn)
memory. */
if (CALL_P (insn))
{
+ function_abi callee_abi = insn_callee_abi (insn);
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
if (call_used_or_fixed_reg_p (i)
|| (REG_VALUES (i) && REG_VALUES (i)->elt
&& (targetm.hard_regno_call_part_clobbered
- (insn, i, GET_MODE (REG_VALUES (i)->elt->val_rtx)))))
+ (callee_abi.id (), i,
+ GET_MODE (REG_VALUES (i)->elt->val_rtx)))))
cselib_invalidate_regno (i, reg_raw_mode[i]);
/* Since it is not clear how cselib is going to be used, be
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 33997a5..419c706 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -1919,14 +1919,23 @@ interoperability between several ABIs in the same translation unit.
@cindex call-used register
@cindex call-clobbered register
@cindex call-saved register
-@deftypefn {Target Hook} bool TARGET_HARD_REGNO_CALL_PART_CLOBBERED (rtx_insn *@var{insn}, unsigned int @var{regno}, machine_mode @var{mode})
-This hook should return true if @var{regno} is partly call-saved and
-partly call-clobbered, and if a value of mode @var{mode} would be partly
-clobbered by call instruction @var{insn}. If @var{insn} is NULL then it
-should return true if any call could partly clobber the register.
-For example, if the low 32 bits of @var{regno} are preserved across a call
-but higher bits are clobbered, this hook should return true for a 64-bit
-mode but false for a 32-bit mode.
+@deftypefn {Target Hook} bool TARGET_HARD_REGNO_CALL_PART_CLOBBERED (unsigned int @var{abi_id}, unsigned int @var{regno}, machine_mode @var{mode})
+ABIs usually specify that calls must preserve the full contents
+of a particular register, or that calls can alter any part of a
+particular register. This information is captured by the target macro
+@code{CALL_REALLY_USED_REGISTERS}. However, some ABIs specify that calls
+must preserve certain bits of a particular register but can alter others.
+This hook should return true if this applies to at least one of the
+registers in @samp{(reg:@var{mode} @var{regno})}, and if as a result the
+call would alter part of the @var{mode} value. For example, if a call
+preserves the low 32 bits of a 64-bit hard register @var{regno} but can
+clobber the upper 32 bits, this hook should return true for a 64-bit mode
+but false for a 32-bit mode.
+
+The value of @var{abi_id} comes from the @code{predefined_function_abi}
+structure that describes the ABI of the call; see the definition of the
+structure for more details. If (as is usual) the target uses the same ABI
+for all functions in a translation unit, @var{abi_id} is always 0.
The default implementation returns false, which is correct
for targets that don't have partly call-clobbered registers.
diff --git a/gcc/function-abi.cc b/gcc/function-abi.cc
index e2c35b6..1d1ac9a 100644
--- a/gcc/function-abi.cc
+++ b/gcc/function-abi.cc
@@ -50,7 +50,7 @@ predefined_function_abi::initialize (unsigned int id,
If the ABI specifies that part of a hard register R is call-clobbered,
we should be able to find a single-register mode M for which
- targetm.hard_regno_call_part_clobbered (NULL, R, M) is true.
+ targetm.hard_regno_call_part_clobbered (m_id, R, M) is true.
In other words, it shouldn't be the case that R can hold all
single-register modes across a call, but can't hold part of
a multi-register mode.
@@ -66,7 +66,7 @@ predefined_function_abi::initialize (unsigned int id,
for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno)
if (targetm.hard_regno_mode_ok (regno, mode)
&& hard_regno_nregs (regno, mode) == 1
- && targetm.hard_regno_call_part_clobbered (NULL, regno, mode))
+ && targetm.hard_regno_call_part_clobbered (m_id, regno, mode))
SET_HARD_REG_BIT (m_full_and_partial_reg_clobbers, regno);
}
@@ -89,7 +89,7 @@ predefined_function_abi::initialize (unsigned int id,
for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno)
if (targetm.hard_regno_mode_ok (regno, mode)
&& !overlaps_hard_reg_set_p (m_full_reg_clobbers, mode, regno)
- && !targetm.hard_regno_call_part_clobbered (NULL, regno, mode))
+ && !targetm.hard_regno_call_part_clobbered (m_id, regno, mode))
remove_from_hard_reg_set (&m_mode_clobbers[i], mode, regno);
}
@@ -104,7 +104,7 @@ predefined_function_abi::initialize (unsigned int id,
for (unsigned int regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno)
if (targetm.hard_regno_mode_ok (regno, mode)
&& !overlaps_hard_reg_set_p (m_full_reg_clobbers, mode, regno)
- && targetm.hard_regno_call_part_clobbered (NULL, regno, mode))
+ && targetm.hard_regno_call_part_clobbered (m_id, regno, mode))
gcc_assert (overlaps_hard_reg_set_p (all_clobbers, mode, regno)
&& overlaps_hard_reg_set_p (m_mode_clobbers[i],
mode, regno));
diff --git a/gcc/hooks.c b/gcc/hooks.c
index ca731c4..a9a87de 100644
--- a/gcc/hooks.c
+++ b/gcc/hooks.c
@@ -140,9 +140,8 @@ hook_bool_puint64_puint64_true (poly_uint64, poly_uint64)
return true;
}
-/* Generic hook that takes (unsigned int, machine_mode) and returns false. */
bool
-hook_bool_insn_uint_mode_false (rtx_insn *, unsigned int, machine_mode)
+hook_bool_uint_uint_mode_false (unsigned int, unsigned int, machine_mode)
{
return false;
}
diff --git a/gcc/hooks.h b/gcc/hooks.h
index 040eff0..7cfe91d 100644
--- a/gcc/hooks.h
+++ b/gcc/hooks.h
@@ -40,7 +40,7 @@ extern bool hook_bool_const_rtx_insn_const_rtx_insn_true (const rtx_insn *,
extern bool hook_bool_mode_uhwi_false (machine_mode,
unsigned HOST_WIDE_INT);
extern bool hook_bool_puint64_puint64_true (poly_uint64, poly_uint64);
-extern bool hook_bool_insn_uint_mode_false (rtx_insn *, unsigned int,
+extern bool hook_bool_uint_uint_mode_false (unsigned int, unsigned int,
machine_mode);
extern bool hook_bool_uint_mode_true (unsigned int, machine_mode);
extern bool hook_bool_tree_false (tree);
diff --git a/gcc/ira-conflicts.c b/gcc/ira-conflicts.c
index c199309..6ceed53 100644
--- a/gcc/ira-conflicts.c
+++ b/gcc/ira-conflicts.c
@@ -838,7 +838,7 @@ ira_build_conflicts (void)
regs must conflict with them. */
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
if (!TEST_HARD_REG_BIT (call_used_or_fixed_regs, regno)
- && targetm.hard_regno_call_part_clobbered (NULL, regno,
+ && targetm.hard_regno_call_part_clobbered (0, regno,
obj_mode))
{
SET_HARD_REG_BIT (OBJECT_CONFLICT_HARD_REGS (obj), regno);
diff --git a/gcc/ira-costs.c b/gcc/ira-costs.c
index aefec08..2e7e10a 100644
--- a/gcc/ira-costs.c
+++ b/gcc/ira-costs.c
@@ -2381,7 +2381,7 @@ ira_tune_allocno_costs (void)
*crossed_calls_clobber_regs)
&& (ira_hard_reg_set_intersection_p (regno, mode,
call_used_or_fixed_regs)
- || targetm.hard_regno_call_part_clobbered (NULL, regno,
+ || targetm.hard_regno_call_part_clobbered (0, regno,
mode)))
cost += (ALLOCNO_CALL_FREQ (a)
* (ira_memory_move_cost[mode][rclass][0]
diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c
index a60bc6c..43fe107 100644
--- a/gcc/lra-constraints.c
+++ b/gcc/lra-constraints.c
@@ -131,6 +131,7 @@
#include "lra.h"
#include "lra-int.h"
#include "print-rtl.h"
+#include "function-abi.h"
/* Value of LRA_CURR_RELOAD_NUM at the beginning of BB of the current
insn. Remember that LRA_CURR_RELOAD_NUM is the number of emitted
@@ -5442,7 +5443,8 @@ need_for_call_save_p (int regno)
: call_used_or_fixed_regs,
PSEUDO_REGNO_MODE (regno), reg_renumber[regno])
|| (targetm.hard_regno_call_part_clobbered
- (lra_reg_info[regno].call_insn,
+ (lra_reg_info[regno].call_insn
+ ? insn_callee_abi (lra_reg_info[regno].call_insn).id () : 0,
reg_renumber[regno], PSEUDO_REGNO_MODE (regno)))));
}
diff --git a/gcc/lra-lives.c b/gcc/lra-lives.c
index b84d646..40e9f66 100644
--- a/gcc/lra-lives.c
+++ b/gcc/lra-lives.c
@@ -594,7 +594,7 @@ check_pseudos_live_through_calls (int regno,
if (! sparseset_bit_p (pseudos_live_through_calls, regno))
return;
- gcc_assert (call_insn && CALL_P (call_insn));
+ function_abi callee_abi = insn_callee_abi (call_insn);
old_call_insn = lra_reg_info[regno].call_insn;
if (!old_call_insn
|| (targetm.return_call_with_max_clobbers
@@ -606,7 +606,7 @@ check_pseudos_live_through_calls (int regno,
lra_reg_info[regno].conflict_hard_regs |= last_call_used_reg_set;
for (hr = 0; HARD_REGISTER_NUM_P (hr); hr++)
- if (targetm.hard_regno_call_part_clobbered (call_insn, hr,
+ if (targetm.hard_regno_call_part_clobbered (callee_abi.id (), hr,
PSEUDO_REGNO_MODE (regno)))
add_to_hard_reg_set (&lra_reg_info[regno].conflict_hard_regs,
PSEUDO_REGNO_MODE (regno), hr);
diff --git a/gcc/regcprop.c b/gcc/regcprop.c
index 4879063..0bdd6b9 100644
--- a/gcc/regcprop.c
+++ b/gcc/regcprop.c
@@ -1057,7 +1057,7 @@ copyprop_hardreg_forward_1 (basic_block bb, struct value_data *vd)
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
if ((callee_abi.clobbers_full_reg_p (regno)
|| (targetm.hard_regno_call_part_clobbered
- (insn, regno, vd->e[regno].mode)))
+ (callee_abi.id (), regno, vd->e[regno].mode)))
&& (regno < set_regno || regno >= set_regno + set_nregs))
kill_value_regno (regno, 1, vd);
diff --git a/gcc/reginfo.c b/gcc/reginfo.c
index a3fbbe6..f084c0e 100644
--- a/gcc/reginfo.c
+++ b/gcc/reginfo.c
@@ -568,7 +568,7 @@ choose_hard_reg_mode (unsigned int regno ATTRIBUTE_UNUSED,
if (hard_regno_nregs (regno, mode) == nregs
&& targetm.hard_regno_mode_ok (regno, mode)
&& (!call_saved
- || !targetm.hard_regno_call_part_clobbered (NULL, regno, mode))
+ || !targetm.hard_regno_call_part_clobbered (0, regno, mode))
&& maybe_gt (GET_MODE_SIZE (mode), GET_MODE_SIZE (found_mode)))
found_mode = mode;
@@ -576,7 +576,7 @@ choose_hard_reg_mode (unsigned int regno ATTRIBUTE_UNUSED,
if (hard_regno_nregs (regno, mode) == nregs
&& targetm.hard_regno_mode_ok (regno, mode)
&& (!call_saved
- || !targetm.hard_regno_call_part_clobbered (NULL, regno, mode))
+ || !targetm.hard_regno_call_part_clobbered (0, regno, mode))
&& maybe_gt (GET_MODE_SIZE (mode), GET_MODE_SIZE (found_mode)))
found_mode = mode;
@@ -584,7 +584,7 @@ choose_hard_reg_mode (unsigned int regno ATTRIBUTE_UNUSED,
if (hard_regno_nregs (regno, mode) == nregs
&& targetm.hard_regno_mode_ok (regno, mode)
&& (!call_saved
- || !targetm.hard_regno_call_part_clobbered (NULL, regno, mode))
+ || !targetm.hard_regno_call_part_clobbered (0, regno, mode))
&& maybe_gt (GET_MODE_SIZE (mode), GET_MODE_SIZE (found_mode)))
found_mode = mode;
@@ -592,7 +592,7 @@ choose_hard_reg_mode (unsigned int regno ATTRIBUTE_UNUSED,
if (hard_regno_nregs (regno, mode) == nregs
&& targetm.hard_regno_mode_ok (regno, mode)
&& (!call_saved
- || !targetm.hard_regno_call_part_clobbered (NULL, regno, mode))
+ || !targetm.hard_regno_call_part_clobbered (0, regno, mode))
&& maybe_gt (GET_MODE_SIZE (mode), GET_MODE_SIZE (found_mode)))
found_mode = mode;
@@ -606,7 +606,7 @@ choose_hard_reg_mode (unsigned int regno ATTRIBUTE_UNUSED,
if (hard_regno_nregs (regno, mode) == nregs
&& targetm.hard_regno_mode_ok (regno, mode)
&& (!call_saved
- || !targetm.hard_regno_call_part_clobbered (NULL, regno, mode)))
+ || !targetm.hard_regno_call_part_clobbered (0, regno, mode)))
return mode;
}
diff --git a/gcc/regrename.c b/gcc/regrename.c
index 14ce954..6a2442bd 100644
--- a/gcc/regrename.c
+++ b/gcc/regrename.c
@@ -339,9 +339,9 @@ check_new_reg_p (int reg ATTRIBUTE_UNUSED, int new_reg,
&& ! DEBUG_INSN_P (tmp->insn))
|| (this_head->need_caller_save_reg
&& ! (targetm.hard_regno_call_part_clobbered
- (NULL, reg, GET_MODE (*tmp->loc)))
+ (0, reg, GET_MODE (*tmp->loc)))
&& (targetm.hard_regno_call_part_clobbered
- (NULL, new_reg, GET_MODE (*tmp->loc)))))
+ (0, new_reg, GET_MODE (*tmp->loc)))))
return false;
return true;
diff --git a/gcc/reload.c b/gcc/reload.c
index 7731e0f..b760130 100644
--- a/gcc/reload.c
+++ b/gcc/reload.c
@@ -6912,14 +6912,14 @@ find_equiv_reg (rtx goal, rtx_insn *insn, enum reg_class rclass, int other,
if (regno >= 0 && regno < FIRST_PSEUDO_REGISTER)
for (i = 0; i < nregs; ++i)
if (call_used_or_fixed_reg_p (regno + i)
- || targetm.hard_regno_call_part_clobbered (NULL, regno + i,
+ || targetm.hard_regno_call_part_clobbered (0, regno + i,
mode))
return 0;
if (valueno >= 0 && valueno < FIRST_PSEUDO_REGISTER)
for (i = 0; i < valuenregs; ++i)
if (call_used_or_fixed_reg_p (valueno + i)
- || targetm.hard_regno_call_part_clobbered (NULL, valueno + i,
+ || targetm.hard_regno_call_part_clobbered (0, valueno + i,
mode))
return 0;
}
diff --git a/gcc/reload1.c b/gcc/reload1.c
index c619c54..39dff6a 100644
--- a/gcc/reload1.c
+++ b/gcc/reload1.c
@@ -8193,8 +8193,7 @@ emit_reload_insns (class insn_chain *chain)
: out_regno + k);
reg_reloaded_insn[regno + k] = insn;
SET_HARD_REG_BIT (reg_reloaded_valid, regno + k);
- if (targetm.hard_regno_call_part_clobbered (NULL,
- regno + k,
+ if (targetm.hard_regno_call_part_clobbered (0, regno + k,
mode))
SET_HARD_REG_BIT (reg_reloaded_call_part_clobbered,
regno + k);
@@ -8274,8 +8273,7 @@ emit_reload_insns (class insn_chain *chain)
: in_regno + k);
reg_reloaded_insn[regno + k] = insn;
SET_HARD_REG_BIT (reg_reloaded_valid, regno + k);
- if (targetm.hard_regno_call_part_clobbered (NULL,
- regno + k,
+ if (targetm.hard_regno_call_part_clobbered (0, regno + k,
mode))
SET_HARD_REG_BIT (reg_reloaded_call_part_clobbered,
regno + k);
@@ -8391,7 +8389,7 @@ emit_reload_insns (class insn_chain *chain)
CLEAR_HARD_REG_BIT (reg_reloaded_dead, src_regno + k);
SET_HARD_REG_BIT (reg_reloaded_valid, src_regno + k);
if (targetm.hard_regno_call_part_clobbered
- (NULL, src_regno + k, mode))
+ (0, src_regno + k, mode))
SET_HARD_REG_BIT (reg_reloaded_call_part_clobbered,
src_regno + k);
else
diff --git a/gcc/sched-deps.c b/gcc/sched-deps.c
index 52db3cc..87d0791 100644
--- a/gcc/sched-deps.c
+++ b/gcc/sched-deps.c
@@ -38,6 +38,7 @@ along with GCC; see the file COPYING3. If not see
#include "sched-int.h"
#include "params.h"
#include "cselib.h"
+#include "function-abi.h"
#ifdef INSN_SCHEDULING
@@ -3723,6 +3724,7 @@ deps_analyze_insn (class deps_desc *deps, rtx_insn *insn)
}
else
{
+ function_abi callee_abi = insn_callee_abi (insn);
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
/* A call may read and modify global register variables. */
if (global_regs[i])
@@ -3734,8 +3736,8 @@ deps_analyze_insn (class deps_desc *deps, rtx_insn *insn)
Since we only have a choice between 'might be clobbered'
and 'definitely not clobbered', we must include all
partly call-clobbered registers here. */
- else if (targetm.hard_regno_call_part_clobbered (insn, i,
- reg_raw_mode[i])
+ else if (targetm.hard_regno_call_part_clobbered
+ (callee_abi.id (), i, reg_raw_mode[i])
|| TEST_HARD_REG_BIT (regs_invalidated_by_call, i))
SET_REGNO_REG_SET (reg_pending_clobbers, i);
/* We don't know what set of fixed registers might be used
diff --git a/gcc/sel-sched.c b/gcc/sel-sched.c
index 077845e..bf370b5 100644
--- a/gcc/sel-sched.c
+++ b/gcc/sel-sched.c
@@ -1102,7 +1102,7 @@ init_regs_for_mode (machine_mode mode)
if (i >= 0)
continue;
- if (targetm.hard_regno_call_part_clobbered (NULL, cur_reg, mode))
+ if (targetm.hard_regno_call_part_clobbered (0, cur_reg, mode))
SET_HARD_REG_BIT (sel_hrd.regs_for_call_clobbered[mode],
cur_reg);
@@ -1247,7 +1247,7 @@ mark_unavailable_hard_regs (def_t def, struct reg_rename *reg_rename_p,
/* Exclude registers that are partially call clobbered. */
if (def->crosses_call
- && !targetm.hard_regno_call_part_clobbered (NULL, regno, mode))
+ && !targetm.hard_regno_call_part_clobbered (0, regno, mode))
reg_rename_p->available_for_renaming
&= ~sel_hrd.regs_for_call_clobbered[mode];
diff --git a/gcc/target.def b/gcc/target.def
index adf7a96..3bdbb8d 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -5814,18 +5814,27 @@ The default version of this hook always returns @code{true}.",
DEFHOOK
(hard_regno_call_part_clobbered,
- "This hook should return true if @var{regno} is partly call-saved and\n\
-partly call-clobbered, and if a value of mode @var{mode} would be partly\n\
-clobbered by call instruction @var{insn}. If @var{insn} is NULL then it\n\
-should return true if any call could partly clobber the register.\n\
-For example, if the low 32 bits of @var{regno} are preserved across a call\n\
-but higher bits are clobbered, this hook should return true for a 64-bit\n\
-mode but false for a 32-bit mode.\n\
+ "ABIs usually specify that calls must preserve the full contents\n\
+of a particular register, or that calls can alter any part of a\n\
+particular register. This information is captured by the target macro\n\
+@code{CALL_REALLY_USED_REGISTERS}. However, some ABIs specify that calls\n\
+must preserve certain bits of a particular register but can alter others.\n\
+This hook should return true if this applies to at least one of the\n\
+registers in @samp{(reg:@var{mode} @var{regno})}, and if as a result the\n\
+call would alter part of the @var{mode} value. For example, if a call\n\
+preserves the low 32 bits of a 64-bit hard register @var{regno} but can\n\
+clobber the upper 32 bits, this hook should return true for a 64-bit mode\n\
+but false for a 32-bit mode.\n\
+\n\
+The value of @var{abi_id} comes from the @code{predefined_function_abi}\n\
+structure that describes the ABI of the call; see the definition of the\n\
+structure for more details. If (as is usual) the target uses the same ABI\n\
+for all functions in a translation unit, @var{abi_id} is always 0.\n\
\n\
The default implementation returns false, which is correct\n\
for targets that don't have partly call-clobbered registers.",
- bool, (rtx_insn *insn, unsigned int regno, machine_mode mode),
- hook_bool_insn_uint_mode_false)
+ bool, (unsigned int abi_id, unsigned int regno, machine_mode mode),
+ hook_bool_uint_uint_mode_false)
DEFHOOK
(return_call_with_max_clobbers,
diff --git a/gcc/targhooks.c b/gcc/targhooks.c
index d2e3ff6..6105137 100644
--- a/gcc/targhooks.c
+++ b/gcc/targhooks.c
@@ -1928,7 +1928,7 @@ default_dwarf_frame_reg_mode (int regno)
{
machine_mode save_mode = reg_raw_mode[regno];
- if (targetm.hard_regno_call_part_clobbered (NULL, regno, save_mode))
+ if (targetm.hard_regno_call_part_clobbered (0, regno, save_mode))
save_mode = choose_hard_reg_mode (regno, 1, true);
return save_mode;
}