Pass an ABI identifier to hard_regno_call_part_clobbered
authorRichard Sandiford <richard.sandiford@arm.com>
Mon, 30 Sep 2019 16:19:59 +0000 (16:19 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Mon, 30 Sep 2019 16:19:59 +0000 (16:19 +0000)
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

26 files changed:
gcc/ChangeLog
gcc/config/aarch64/aarch64.c
gcc/config/avr/avr.c
gcc/config/i386/i386.c
gcc/config/mips/mips.c
gcc/config/pru/pru.c
gcc/config/rs6000/rs6000.c
gcc/config/s390/s390.c
gcc/cselib.c
gcc/doc/tm.texi
gcc/function-abi.cc
gcc/hooks.c
gcc/hooks.h
gcc/ira-conflicts.c
gcc/ira-costs.c
gcc/lra-constraints.c
gcc/lra-lives.c
gcc/regcprop.c
gcc/reginfo.c
gcc/regrename.c
gcc/reload.c
gcc/reload1.c
gcc/sched-deps.c
gcc/sel-sched.c
gcc/target.def
gcc/targhooks.c

index acdcd914dc20a23ce7422b13fd8bcda9748066d8..59bfeb2b66fa018a94a945a92f5286de744dde0d 100644 (file)
@@ -1,3 +1,48 @@
+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.
index 71cdce3033c33e86df6ec12b1ea1b2e9542ab8de..ca4c183d89d10ce512b29444b31d0f8687580bda 100644 (file)
@@ -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)
index 04fc00f4a55fbcd9747d86cbd56ccf9dde978222..3ccff8ebedc4633373c6c3951a93977fabff7ef8 100644 (file)
@@ -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
index a13aef8077a7b52a80cc802a1021f73c111223dd..8af4bc581e176bfb7fa773e1ce6b9426bb558190 100644 (file)
@@ -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;
 }
index c682ebd5add32da6c98a3ac5eefad8392ac186e9..91dd94bf4e6e0fb81a3c2c2d0ac39467370a31ff 100644 (file)
@@ -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
index 416399ea5fd8f479f1abf8be518dde4b53be348b..16d1451262e9074252f15c129275209cef2ad103 100644 (file)
@@ -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;
index d6e1fea842646d473de0aa80581aa9021cbf7ce5..330e2490301950ab0d9ae61571d20468a6d3787b 100644 (file)
@@ -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
index cfdfa4e141dccc2dc13f6e44521b3406e2192f29..1764c3450e60b3586a401f3a213bf9018a24a0ad 100644 (file)
@@ -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
index 109cc27959cba8315bc0d9f8ccc36d5ead0d969b..5de14a07317fd4f8c17d641a7f62057ad37d8197 100644 (file)
@@ -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
index 33997a5c7a0823d9215067b089a4f2cfb9577c59..419c706cb9e8fd73f1fd715689595fc63effbd12 100644 (file)
@@ -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.
index e2c35b6a274cb87c4560779c4350c5585595622e..1d1ac9a25899936d383160935807e50236206ccc 100644 (file)
@@ -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));
index ca731c440e75ccbb11ae0810b1a946e833e58533..a9a87de3cdbf85059d25cda38aa677917c907748 100644 (file)
@@ -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;
 }
index 040eff008db73e08ea32194054fb6187eb7a9614..7cfe91d12dfdc3d01307b5b7b81364912668195c 100644 (file)
@@ -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);
index c199309e7a61c174fd477b3449440fc81852b88c..6ceed5333292c68ad90a34925937a07ac6b2f51e 100644 (file)
@@ -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);
index aefec08da548475c0509a70afdca8eb3b4e2a97d..2e7e10ac903a6bed9d84ad330a007ee4f5f477e8 100644 (file)
@@ -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]
index a60bc6cc3f9f8d2373c3b59713dc9a26bcb9fbc3..43fe1074788486ff03ea948320ebfefdbe877ea2 100644 (file)
 #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)))));
 }
 
index b84d6461c4cc8ecf5270f56848403f4a768d621a..40e9f66f3b11a4a57a1f270e2f037024b05cb675 100644 (file)
@@ -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);
index 4879063ea69e63d195cce3959a51ed76d4b41f24..0bdd6b918150d2591b5c33c34d32b9652c4d12dc 100644 (file)
@@ -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);
 
index a3fbbe67c52a7a6ec791b4afe7db1949ee613152..f084c0e430680850fee0e165c3e6ac5a574a0326 100644 (file)
@@ -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;
     }
 
index 14ce95470b2fa698cb6227bc3932b3bc87430dbe..6a2442bdaa7e981c9f6eaf87a9d8092f224ef41a 100644 (file)
@@ -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;
index 7731e0fcf57e94dcef785581b568d17c5c104ae9..b7601307f82f60dca6165dfc3c2294e660b17d3d 100644 (file)
@@ -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;
        }
index c619c5411742fba148d3c5a5b366c17adcb7214c..39dff6a32b2dc805bcd1f8e7055b56c999e0064a 100644 (file)
@@ -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
index 52db3cc1523656f69230d7e13adfe0e35c088b44..87d0791374ed6322fc4c97ec8655bcecc1782a58 100644 (file)
@@ -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
index 077845e156a0a0afa013e9f91caf509105cb2e94..bf370b5a5d85ac8707b665282a45f85f7a52a0a0 100644 (file)
@@ -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];
 
index adf7a96e419ef0c52fc4c98423a218b72a8efa3f..3bdbb8d86bab30cddc75e08257b77a627f2f0705 100644 (file)
@@ -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,
index d2e3ff662b67ae4a0c2c281ec26c312c52f12847..6105137aad5a35f616fc3bbfb1972ad73c4416fc 100644 (file)
@@ -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;
 }