On Mon, May 18, 2026 at 6:30 AM H.J. Lu <[email protected]> wrote:
>
> On Sat, May 16, 2026 at 6:34 PM Richard Sandiford
> <[email protected]> wrote:
> >
> > Richard Sandiford <[email protected]> writes:
> > > function-abi.h was originally added to cope with AArch64's
> > > vector PCS and SVE PCS variants.  One of the key requirements
> > > was that a call insn must say precisely which ABI the callee uses,
> > > regardless of how the call is created.
> > >
> > > At the time, I did this by encoding the information as an UNSPEC
> > > in the AArch64 call patterns.  IIRC, there were three reasons for
> > > doing it that way:
> > >
> > > (1) To make sure that the information is not accidentally dropped.
> > >
> > > (2) To make sure that calls using different ABIs are distinct
> > >     (not rtx_equal_p).
> > >
> > > (3) Because it seemed presumptious to add a new CALL_INSN field for
> > >     something that only AArch64 was using.
> > >
> > > However, CALL_INSN_FUNCTION_USAGE and SIBLING_CALL_P also require (1)
> > > and at least SIBLING_CALL_P requires (2).  I'm not aware that this
> > > has been a common source of bugs in practice.
> > >
> > > As far as (3) goes, RISC-V now uses a similar system, and x86 is
> > > also about to use function_abi more heavily (see HJ's patches).
> > > Any target that wants to run CPython efficiently will probably want
> > > to implement preserve_none, and so adopt the same kind of approach.
> > >
> > > If we take the view that having multiple ABIs is now going to be
> > > common for "major" targets, attaching the information to the
> > > CALL_INSN would be both simpler and more compact.
> > >
> > > As it stands, targets have to smuggle the ABI information from
> > > init_cumulative_args (which supplies the function type) through
> > > function_arg (which asks the target for the final call operand)
> > > to call/call_value/etc. (which receive the information from
> > > function_arg).  It's all a bit of a mess.
> > >
> > > This patch therefore adds a new CALL_INSN_ABI_ID field to CALL_INSN
> > > and removes the now-redundant insn_callee_abi hook.
> > >
> > > This makes UNSPEC_CALLEE_CC unnecessary on RISC-V, so the patch
> > > reverts the call patterns to something like their state before
> > > r14-3733-gfdd59c0f73e9e6 (which is in no way a comment against
> > > that patch).  In contrast, AArch64 still uses the ABI "cookie"
> > > for other information, so it needs to be kept.
> > >
> > > The patch reflows the CALL_INSN_FUNCTION_USAGE documentation but
> > > otherwise just does s/@code{CALL_INSN_FUNCTION_USAGE}/This field/.
> > >
> > > Tested on aarch64-linux-gnu, powerpc64le-linux-gnu and
> > > x86_64-linux-gnu.  I've cc:ed the RISC-V CI to get testing there.
> > > OK to install if that testing passes?
> >
> > FWIW, the RISC-V CI testing passed, except for a long line in the
> > riscv.md call to gen_sibcall_value_internal, which I've fixed in my
> > local copy.
>
> Could someone review this patch?  It blocks patches for
>
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124798

The patch is here:

https://gcc.gnu.org/pipermail/gcc-patches/2026-May/716712.html


> Thanks.
>
> > Thanks,
> > Richard
> >
> > >
> > > Richard
> > >
> > >
> > > gcc/
> > >       * rtl.def (CALL_INSN): Add a new integer field.
> > >       * rtl.h (CALL_INSN_ABI_ID): New macro.
> > >       * target.def (insn_callee_abi): Delete.
> > >       * doc/rtl.texi: Document CALL_INSN_ABI_ID.
> > >       * doc/tm.texi.in (TARGET_INSN_CALLEE_ABI): Remove.
> > >       * doc/tm.texi: Regenerate.
> > >       * calls.cc: Include regs.h and function-abi.h.
> > >       (emit_call_1): Initialize CALL_INSN_ABI_ID.
> > >       * cfgcleanup.cc (old_insns_match_p): Compare CALL_INSN_ABI_IDs.
> > >       * emit-rtl.cc (try_split): Copy the original insn's CALL_INSN_ABI_ID
> > >       to the new call.
> > >       (emit_copy_of_insn_after): Likewise.
> > >       (make_call_insn_raw): Initialise CALL_INSN_ABI_ID.
> > >       * function-abi.cc (insn_callee_abi): Remove use of the 
> > > insn_callee_abi
> > >       hook and instead use CALL_INSN_ABI_ID.
> > >       * recog.cc (peep2_attempt): Copy the original insn's 
> > > CALL_INSN_ABI_ID
> > >       to the new call.
> > >       * config/aarch64/aarch64-protos.h (aarch64_gen_callee_cookie): 
> > > Remove
> > >       arm_pcs parameter.
> > >       * config/aarch64/aarch64.cc (aarch64_gen_callee_cookie): Likewise.
> > >       (aarch64_callee_abi): Delete.
> > >       (aarch64_insn_callee_abi): Likewise.
> > >       (aarch64_function_arg): Update call to aarch64_callee_abi.
> > >       (aarch64_output_mi_thunk): Likewise.  Set CALL_INSN_ABI_ID instead.
> > >       (TARGET_INSN_CALLEE_ABI): Delete.
> > >       * config/aarch64/aarch64.md (tlsdesc_small_<mode>): Update call
> > >       to aarch64_callee_abi and set CALL_INSN_ABI_ID instead.
> > >       * config/i386/i386.cc (ix86_insn_callee_abi): Delete.
> > >       (ix86_expand_avx_vzeroupper): Set CALL_INSN_ABI_ID.
> > >       (TARGET_INSN_CALLEE_ABI): Delete.
> > >       * config/riscv/riscv-sr.cc 
> > > (riscv_remove_unneeded_save_restore_calls):
> > >       Remove coding convention from calls to gen_sibcall_internal and
> > >       gen_sibcall_value_internal.  Store the ABI identifier in
> > >       CALL_INSN_ABI_ID instead.
> > >       * config/riscv/riscv.cc (riscv_output_mi_thunk): Likewise.
> > >       (riscv_call_tls_get_addr): Likewise, but calling gen_call_value.
> > >       (riscv_function_arg): Return null for the end marker.
> > >       (get_riscv_cc, riscv_insn_callee_abi): Delete.
> > >       (TARGET_INSN_CALLEE_ABI): Delete.
> > >       * config/riscv/riscv.md (UNSPEC_CALLEE_CC): Delete.
> > >       (sibcall): Revert to treating operand 2 as a placeholder.
> > >       Do not pass it to gen_sibcall_internal.
> > >       (sibcall_value): Likewise operand 3 and gen_sibcall_value_internal.
> > >       (call): Likewise operand 2 and gen_call_internal.
> > >       (call_value): Likewise operand 3 and gen_call_value_internal.
> > >       (sibcall_internal, call_internal): Remove operand 2.
> > >       (sibcall_value_internal, call_value_internal): Remove operand 3.
> > >       (untyped_call): Update call to gen_call.
> > >
> > > gcc/testsuite/
> > >       * gcc.dg/rtl/x86_64/different-structs.c: Initialize 
> > > CALL_INSN_ABI_ID.
> > >       * selftests/x86_64/call-insn.rtl: Likewise.
> > > ---
> > >  gcc/calls.cc                                  |  3 ++
> > >  gcc/cfgcleanup.cc                             |  1 +
> > >  gcc/config/aarch64/aarch64-protos.h           |  2 +-
> > >  gcc/config/aarch64/aarch64.cc                 | 33 ++-----------
> > >  gcc/config/aarch64/aarch64.md                 |  5 +-
> > >  gcc/config/i386/i386.cc                       | 17 +------
> > >  gcc/config/riscv/riscv-sr.cc                  |  8 ++-
> > >  gcc/config/riscv/riscv.cc                     | 37 ++------------
> > >  gcc/config/riscv/riscv.md                     | 49 +++++--------------
> > >  gcc/doc/rtl.texi                              | 22 ++++++---
> > >  gcc/doc/tm.texi                               | 11 -----
> > >  gcc/doc/tm.texi.in                            |  2 -
> > >  gcc/emit-rtl.cc                               |  5 ++
> > >  gcc/function-abi.cc                           |  5 +-
> > >  gcc/recog.cc                                  |  1 +
> > >  gcc/rtl.def                                   |  6 +--
> > >  gcc/rtl.h                                     |  4 ++
> > >  gcc/target.def                                | 13 -----
> > >  .../gcc.dg/rtl/x86_64/different-structs.c     |  3 +-
> > >  gcc/testsuite/selftests/x86_64/call-insn.rtl  |  3 +-
> > >  20 files changed, 65 insertions(+), 165 deletions(-)
> > >
> > > diff --git a/gcc/calls.cc b/gcc/calls.cc
> > > index d491a414611..e5d67b6c97a 100644
> > > --- a/gcc/calls.cc
> > > +++ b/gcc/calls.cc
> > > @@ -61,6 +61,8 @@ along with GCC; see the file COPYING3.  If not see
> > >  #include "value-query.h"
> > >  #include "tree-pretty-print.h"
> > >  #include "tree-eh.h"
> > > +#include "regs.h"
> > > +#include "function-abi.h"
> > >
> > >  /* Like PREFERRED_STACK_BOUNDARY but in units of bytes, not bits.  */
> > >  #define STACK_BYTES (PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT)
> > > @@ -512,6 +514,7 @@ emit_call_1 (rtx funexp, tree fntree 
> > > ATTRIBUTE_UNUSED, tree fndecl ATTRIBUTE_UNU
> > >        cfun->calls_setjmp = 1;
> > >      }
> > >
> > > +  CALL_INSN_ABI_ID (call_insn) = (funtype ? fntype_abi (funtype).id () : 
> > > 0);
> > >    SIBLING_CALL_P (call_insn) = ((ecf_flags & ECF_SIBCALL) != 0);
> > >
> > >    /* Restore this now, so that we do defer pops for this call's args
> > > diff --git a/gcc/cfgcleanup.cc b/gcc/cfgcleanup.cc
> > > index b6f04754f25..1d9ec908dab 100644
> > > --- a/gcc/cfgcleanup.cc
> > > +++ b/gcc/cfgcleanup.cc
> > > @@ -1204,6 +1204,7 @@ old_insns_match_p (int mode ATTRIBUTE_UNUSED, 
> > > rtx_insn *i1, rtx_insn *i2)
> > >
> > >        if (!rtx_equal_p (CALL_INSN_FUNCTION_USAGE (i1),
> > >                       CALL_INSN_FUNCTION_USAGE (i2))
> > > +       || CALL_INSN_ABI_ID (i1) != CALL_INSN_ABI_ID (i2)
> > >         || SIBLING_CALL_P (i1) != SIBLING_CALL_P (i2))
> > >       return dir_none;
> > >
> > > diff --git a/gcc/config/aarch64/aarch64-protos.h 
> > > b/gcc/config/aarch64/aarch64-protos.h
> > > index 8d201821e93..89b7752bdce 100644
> > > --- a/gcc/config/aarch64/aarch64-protos.h
> > > +++ b/gcc/config/aarch64/aarch64-protos.h
> > > @@ -887,7 +887,7 @@ bool aarch64_emit_approx_div (rtx, rtx, rtx);
> > >  bool aarch64_emit_approx_sqrt (rtx, rtx, bool);
> > >  bool aarch64_emit_opt_vec_rotate (rtx, rtx, rtx);
> > >  tree aarch64_vector_load_decl (tree);
> > > -rtx aarch64_gen_callee_cookie (aarch64_isa_mode, arm_pcs, bool);
> > > +rtx aarch64_gen_callee_cookie (aarch64_isa_mode, bool);
> > >  void aarch64_expand_call (rtx, rtx, rtx, bool);
> > >  bool aarch64_expand_cpymem_mops (rtx *, bool);
> > >  bool aarch64_expand_cpymem (rtx *, bool);
> > > diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
> > > index cd5ed154c7a..ab6f5ebbf97 100644
> > > --- a/gcc/config/aarch64/aarch64.cc
> > > +++ b/gcc/config/aarch64/aarch64.cc
> > > @@ -2826,29 +2826,15 @@ aarch64_reg_save_mode (unsigned int regno)
> > >  /* Return the CONST_INT that should be placed in an UNSPEC_CALLEE_ABI 
> > > rtx.
> > >     This value encodes the following information:
> > >      - the ISA mode on entry to a callee (ISA_MODE)
> > > -    - the ABI of the callee (PCS_VARIANT)
> > >      - whether the callee has an indirect_return
> > >        attribute (INDIRECT_RETURN).  */
> > >
> > >  rtx
> > > -aarch64_gen_callee_cookie (aarch64_isa_mode isa_mode, arm_pcs 
> > > pcs_variant,
> > > -                        bool indirect_return)
> > > +aarch64_gen_callee_cookie (aarch64_isa_mode isa_mode, bool 
> > > indirect_return)
> > >  {
> > >    unsigned int im = (unsigned int) isa_mode;
> > >    unsigned int ir = (indirect_return ? 1 : 0) << AARCH64_NUM_ISA_MODES;
> > > -  unsigned int pv = (unsigned int) pcs_variant
> > > -                  << (AARCH64_NUM_ABI_ATTRIBUTES + 
> > > AARCH64_NUM_ISA_MODES);
> > > -  return gen_int_mode (im | ir | pv, DImode);
> > > -}
> > > -
> > > -/* COOKIE is a CONST_INT from an UNSPEC_CALLEE_ABI rtx.  Return the
> > > -   callee's ABI.  */
> > > -
> > > -static const predefined_function_abi &
> > > -aarch64_callee_abi (rtx cookie)
> > > -{
> > > -  return function_abis[UINTVAL (cookie)
> > > -      >> (AARCH64_NUM_ABI_ATTRIBUTES + AARCH64_NUM_ISA_MODES)];
> > > +  return gen_int_mode (im | ir, DImode);
> > >  }
> > >
> > >  /* COOKIE is a CONST_INT from an UNSPEC_CALLEE_ABI rtx.  Return the
> > > @@ -2894,14 +2880,6 @@ aarch_fun_is_indirect_return (rtx_insn *insn)
> > >    return aarch64_callee_indirect_return (cookie);
> > >  }
> > >
> > > -/* Implement TARGET_INSN_CALLEE_ABI.  */
> > > -
> > > -const predefined_function_abi &
> > > -aarch64_insn_callee_abi (const rtx_insn *insn)
> > > -{
> > > -  return aarch64_callee_abi (aarch64_insn_callee_cookie (insn));
> > > -}
> > > -
> > >  /* INSN is a call instruction.  Return the required ISA mode on entry to
> > >     the callee, which is also the ISA mode on return from the callee.  */
> > >
> > > @@ -8103,7 +8081,6 @@ aarch64_function_arg (cumulative_args_t pcum_v, 
> > > const function_arg_info &arg)
> > >    if (arg.end_marker_p ())
> > >      {
> > >        rtx abi_cookie = aarch64_gen_callee_cookie (pcum->isa_mode,
> > > -                                               pcum->pcs_variant,
> > >                                                 pcum->indirect_return);
> > >        rtx sme_mode_switch_args = aarch64_finish_sme_mode_switch_args 
> > > (pcum);
> > >        rtx shared_za_flags = gen_int_mode (pcum->shared_za_flags, SImode);
> > > @@ -11133,8 +11110,9 @@ aarch64_output_mi_thunk (FILE *file, tree thunk 
> > > ATTRIBUTE_UNUSED,
> > >    auto pcs_variant = aarch64_fndecl_abi (function);
> > >    bool ir = lookup_attribute ("indirect_return",
> > >                             TYPE_ATTRIBUTES (TREE_TYPE (function)));
> > > -  rtx callee_abi = aarch64_gen_callee_cookie (isa_mode, pcs_variant, ir);
> > > +  rtx callee_abi = aarch64_gen_callee_cookie (isa_mode, ir);
> > >    insn = emit_call_insn (gen_sibcall (funexp, const0_rtx, callee_abi));
> > > +  CALL_INSN_ABI_ID (insn) = pcs_variant;
> > >    SIBLING_CALL_P (insn) = 1;
> > >
> > >    insn = get_insns ();
> > > @@ -33981,9 +33959,6 @@ aarch64_libgcc_floating_mode_supported_p
> > >  #define TARGET_HARD_REGNO_CALL_PART_CLOBBERED \
> > >    aarch64_hard_regno_call_part_clobbered
> > >
> > > -#undef TARGET_INSN_CALLEE_ABI
> > > -#define TARGET_INSN_CALLEE_ABI aarch64_insn_callee_abi
> > > -
> > >  #undef TARGET_CONSTANT_ALIGNMENT
> > >  #define TARGET_CONSTANT_ALIGNMENT aarch64_constant_alignment
> > >
> > > diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
> > > index 0ef01e889a6..5a1d756af70 100644
> > > --- a/gcc/config/aarch64/aarch64.md
> > > +++ b/gcc/config/aarch64/aarch64.md
> > > @@ -8119,11 +8119,10 @@
> > >    {
> > >      if (TARGET_SVE)
> > >        {
> > > -     rtx abi = aarch64_gen_callee_cookie (AARCH64_ISA_MODE,
> > > -                                          aarch64_tlsdesc_abi_id (),
> > > -                                          false);
> > > +     rtx abi = aarch64_gen_callee_cookie (AARCH64_ISA_MODE, false);
> > >       rtx_insn *call
> > >         = emit_call_insn (gen_tlsdesc_small_sve_<mode> (operands[0], 
> > > abi));
> > > +     CALL_INSN_ABI_ID (call) = aarch64_tlsdesc_abi_id ();
> > >       RTL_CONST_CALL_P (call) = 1;
> > >        }
> > >      else
> > > diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
> > > index 9aecd51119f..7a90196aaeb 100644
> > > --- a/gcc/config/i386/i386.cc
> > > +++ b/gcc/config/i386/i386.cc
> > > @@ -21847,19 +21847,6 @@ ix86_hard_regno_mode_ok (unsigned int regno, 
> > > machine_mode mode)
> > >    return false;
> > >  }
> > >
> > > -/* Implement TARGET_INSN_CALLEE_ABI.  */
> > > -
> > > -const predefined_function_abi &
> > > -ix86_insn_callee_abi (const rtx_insn *insn)
> > > -{
> > > -  unsigned int abi_id = 0;
> > > -  rtx pat = PATTERN (insn);
> > > -  if (vzeroupper_pattern (pat, VOIDmode))
> > > -    abi_id = ABI_VZEROUPPER;
> > > -
> > > -  return function_abis[abi_id];
> > > -}
> > > -
> > >  /* Initialize function_abis with corresponding abi_id,
> > >     currently only handle vzeroupper.  */
> > >  void
> > > @@ -21881,6 +21868,7 @@ ix86_expand_avx_vzeroupper (void)
> > >    /* Initialize vzeroupper_abi here.  */
> > >    ix86_initialize_callee_abi (ABI_VZEROUPPER);
> > >    rtx_insn *insn = emit_call_insn (gen_avx_vzeroupper_callee_abi ());
> > > +  CALL_INSN_ABI_ID (insn) = ABI_VZEROUPPER;
> > >    /* Return false for non-local goto in can_nonlocal_goto.  */
> > >    make_reg_eh_region_note (insn, 0, INT_MIN);
> > >    /* Flag used for call_insn indicates it's a fake call.  */
> > > @@ -28779,9 +28767,6 @@ ix86_libgcc_floating_mode_supported_p
> > >  #define TARGET_HARD_REGNO_CALL_PART_CLOBBERED \
> > >    ix86_hard_regno_call_part_clobbered
> > >
> > > -#undef TARGET_INSN_CALLEE_ABI
> > > -#define TARGET_INSN_CALLEE_ABI ix86_insn_callee_abi
> > > -
> > >  #undef TARGET_CAN_CHANGE_MODE_CLASS
> > >  #define TARGET_CAN_CHANGE_MODE_CLASS ix86_can_change_mode_class
> > >
> > > diff --git a/gcc/config/riscv/riscv-sr.cc b/gcc/config/riscv/riscv-sr.cc
> > > index d7fb3c274eb..90f9278fa88 100644
> > > --- a/gcc/config/riscv/riscv-sr.cc
> > > +++ b/gcc/config/riscv/riscv-sr.cc
> > > @@ -447,20 +447,18 @@ riscv_remove_unneeded_save_restore_calls (void)
> > >        && !SIBCALL_REG_P (REGNO (target)))
> > >      return;
> > >
> > > -  riscv_cc cc = get_riscv_cc (XVECEXP (callpat, 0, 1));
> > >    rtx sibcall = NULL;
> > >    if (set_target != NULL)
> > > -    sibcall = gen_sibcall_value_internal (set_target, target, const0_rtx,
> > > -                                       gen_int_mode (cc, SImode));
> > > +    sibcall = gen_sibcall_value_internal (set_target, target, 
> > > const0_rtx);
> > >    else
> > > -    sibcall
> > > -      = gen_sibcall_internal (target, const0_rtx, gen_int_mode (cc, 
> > > SImode));
> > > +    sibcall = gen_sibcall_internal (target, const0_rtx);
> > >
> > >    rtx_insn *before_call = PREV_INSN (call);
> > >    remove_insn (call);
> > >    rtx_insn *insn = emit_call_insn_after_setloc (sibcall, before_call,
> > >                                               INSN_LOCATION (call));
> > >    REG_NOTES (insn) = REG_NOTES (call);
> > > +  CALL_INSN_ABI_ID (insn) = CALL_INSN_ABI_ID (call);
> > >    SIBLING_CALL_P (insn) = 1;
> > >
> > >    /* Now update the prologue and epilogue to take account of the
> > > diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
> > > index 681b816d248..0a4f934d9dd 100644
> > > --- a/gcc/config/riscv/riscv.cc
> > > +++ b/gcc/config/riscv/riscv.cc
> > > @@ -3105,8 +3105,8 @@ riscv_call_tls_get_addr (rtx sym, rtx result)
> > >    start_sequence ();
> > >
> > >    emit_insn (riscv_got_load_tls_gd (a0, sym));
> > > -  insn = emit_call_insn (gen_call_value (result, func, const0_rtx,
> > > -                                      gen_int_mode (RISCV_CC_BASE, 
> > > SImode)));
> > > +  insn = emit_call_insn (gen_call_value (result, func, const0_rtx, 
> > > NULL_RTX));
> > > +  CALL_INSN_ABI_ID (insn) = RISCV_CC_BASE;
> > >    RTL_CONST_CALL_P (insn) = 1;
> > >    use_reg (&CALL_INSN_FUNCTION_USAGE (insn), a0);
> > >    insn = end_sequence ();
> > > @@ -7073,8 +7073,7 @@ riscv_function_arg (cumulative_args_t cum_v, const 
> > > function_arg_info &arg)
> > >    struct riscv_arg_info info;
> > >
> > >    if (arg.end_marker_p ())
> > > -    /* Return the calling convention that used by the current function. 
> > > */
> > > -    return gen_int_mode (cum->variant_cc, SImode);
> > > +    return nullptr;
> > >
> > >    return riscv_get_arg_info (&info, cum, arg.mode, arg.type, arg.named, 
> > > false);
> > >  }
> > > @@ -7600,30 +7599,6 @@ riscv_fntype_abi (const_tree fntype)
> > >    return riscv_fntype_abi_1 (fntype, /* check_only */true);
> > >  }
> > >
> > > -/* Return riscv calling convention of call_insn.  */
> > > -riscv_cc
> > > -get_riscv_cc (const rtx use)
> > > -{
> > > -  gcc_assert (GET_CODE (use) == USE);
> > > -  rtx unspec = XEXP (use, 0);
> > > -  gcc_assert (GET_CODE (unspec) == UNSPEC
> > > -           && XINT (unspec, 1) == UNSPEC_CALLEE_CC);
> > > -  riscv_cc cc = (riscv_cc) INTVAL (XVECEXP (unspec, 0, 0));
> > > -  gcc_assert (cc < RISCV_CC_UNKNOWN);
> > > -  return cc;
> > > -}
> > > -
> > > -/* Implement TARGET_INSN_CALLEE_ABI.  */
> > > -
> > > -const predefined_function_abi &
> > > -riscv_insn_callee_abi (const rtx_insn *insn)
> > > -{
> > > -  rtx pat = PATTERN (insn);
> > > -  gcc_assert (GET_CODE (pat) == PARALLEL);
> > > -  riscv_cc cc = get_riscv_cc (XVECEXP (pat, 0, 1));
> > > -  return function_abis[cc];
> > > -}
> > > -
> > >  /* Handle an attribute requiring a FUNCTION_DECL;
> > >     arguments as in struct attribute_spec.handler.  */
> > >  static tree
> > > @@ -11571,8 +11546,8 @@ riscv_output_mi_thunk (FILE *file, tree 
> > > thunk_fndecl ATTRIBUTE_UNUSED,
> > >      }
> > >
> > >    /* Jump to the target function.  */
> > > -  rtx callee_cc = gen_int_mode (fndecl_abi (function).id (), SImode);
> > > -  insn = emit_call_insn (gen_sibcall (fnaddr, const0_rtx, callee_cc));
> > > +  insn = emit_call_insn (gen_sibcall (fnaddr, const0_rtx, NULL_RTX));
> > > +  CALL_INSN_ABI_ID (insn) = fndecl_abi (function).id ();
> > >    SIBLING_CALL_P (insn) = 1;
> > >
> > >    /* Run just enough of rest_of_compilation.  This sequence was
> > > @@ -16102,8 +16077,6 @@ riscv_memtag_tag_bitsize ()
> > >  #define TARGET_FUNCTION_ARG_BOUNDARY riscv_function_arg_boundary
> > >  #undef TARGET_FNTYPE_ABI
> > >  #define TARGET_FNTYPE_ABI riscv_fntype_abi
> > > -#undef TARGET_INSN_CALLEE_ABI
> > > -#define TARGET_INSN_CALLEE_ABI riscv_insn_callee_abi
> > >
> > >  #undef TARGET_SHRINK_WRAP_GET_SEPARATE_COMPONENTS
> > >  #define TARGET_SHRINK_WRAP_GET_SEPARATE_COMPONENTS \
> > > diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
> > > index 869061e18ae..2d1d10dd6eb 100644
> > > --- a/gcc/config/riscv/riscv.md
> > > +++ b/gcc/config/riscv/riscv.md
> > > @@ -83,9 +83,6 @@
> > >    UNSPEC_CLMULH
> > >    UNSPEC_CLMULR
> > >
> > > -  ;; the calling convention of callee
> > > -  UNSPEC_CALLEE_CC
> > > -
> > >    ;; String unspecs
> > >    UNSPEC_STRLEN
> > >
> > > @@ -4100,22 +4097,17 @@
> > >  (define_expand "sibcall"
> > >    [(parallel [(call (match_operand 0 "")
> > >                   (match_operand 1 ""))
> > > -           (use (unspec:SI [
> > > -                  (match_operand 2 "const_int_operand")
> > > -                ] UNSPEC_CALLEE_CC))])]
> > > +           (use (match_operand 2 ""))])]
> > >    ""
> > >  {
> > >    rtx target = riscv_legitimize_call_address (XEXP (operands[0], 0));
> > > -  emit_call_insn (gen_sibcall_internal (target, operands[1], 
> > > operands[2]));
> > > +  emit_call_insn (gen_sibcall_internal (target, operands[1]));
> > >    DONE;
> > >  })
> > >
> > >  (define_insn "sibcall_internal"
> > >    [(call (mem:SI (match_operand 0 "call_insn_operand" "j,S,U"))
> > > -      (match_operand 1 "" ""))
> > > -   (use (unspec:SI [
> > > -          (match_operand 2 "const_int_operand")
> > > -        ] UNSPEC_CALLEE_CC))]
> > > +      (match_operand 1 "" ""))]
> > >    "SIBLING_CALL_P (insn)"
> > >    "@
> > >     jr\t%0
> > > @@ -4127,24 +4119,18 @@
> > >    [(parallel [(set (match_operand 0 "")
> > >                  (call (match_operand 1 "")
> > >                        (match_operand 2 "")))
> > > -           (use (unspec:SI [
> > > -                  (match_operand 3 "const_int_operand")
> > > -                ] UNSPEC_CALLEE_CC))])]
> > > +           (use (match_operand 3 ""))])]
> > >    ""
> > >  {
> > >    rtx target = riscv_legitimize_call_address (XEXP (operands[1], 0));
> > > -  emit_call_insn (gen_sibcall_value_internal (operands[0], target, 
> > > operands[2],
> > > -                                           operands[3]));
> > > +  emit_call_insn (gen_sibcall_value_internal (operands[0], target, 
> > > operands[2]));
> > >    DONE;
> > >  })
> > >
> > >  (define_insn "sibcall_value_internal"
> > >    [(set (match_operand 0 "" "")
> > >       (call (mem:SI (match_operand 1 "call_insn_operand" "j,S,U"))
> > > -           (match_operand 2 "" "")))
> > > -   (use (unspec:SI [
> > > -          (match_operand 3 "const_int_operand")
> > > -        ] UNSPEC_CALLEE_CC))]
> > > +           (match_operand 2 "" "")))]
> > >    "SIBLING_CALL_P (insn)"
> > >    "@
> > >     jr\t%1
> > > @@ -4155,22 +4141,17 @@
> > >  (define_expand "call"
> > >    [(parallel [(call (match_operand 0 "")
> > >                   (match_operand 1 ""))
> > > -           (use (unspec:SI [
> > > -                  (match_operand 2 "const_int_operand")
> > > -                ] UNSPEC_CALLEE_CC))])]
> > > +           (use (match_operand 2 ""))])]
> > >    ""
> > >  {
> > >    rtx target = riscv_legitimize_call_address (XEXP (operands[0], 0));
> > > -  emit_call_insn (gen_call_internal (target, operands[1], operands[2]));
> > > +  emit_call_insn (gen_call_internal (target, operands[1]));
> > >    DONE;
> > >  })
> > >
> > >  (define_insn "call_internal"
> > >    [(call (mem:SI (match_operand 0 "call_insn_operand" "l,S,U"))
> > >        (match_operand 1 "" ""))
> > > -   (use (unspec:SI [
> > > -          (match_operand 2 "const_int_operand")
> > > -        ] UNSPEC_CALLEE_CC))
> > >     (clobber (reg:SI RETURN_ADDR_REGNUM))]
> > >    ""
> > >    "@
> > > @@ -4183,14 +4164,11 @@
> > >    [(parallel [(set (match_operand 0 "")
> > >                  (call (match_operand 1 "")
> > >                        (match_operand 2 "")))
> > > -           (use (unspec:SI [
> > > -                  (match_operand 3 "const_int_operand")
> > > -                ] UNSPEC_CALLEE_CC))])]
> > > +           (use (match_operand 3 ""))])]
> > >    ""
> > >  {
> > >    rtx target = riscv_legitimize_call_address (XEXP (operands[1], 0));
> > > -  emit_call_insn (gen_call_value_internal (operands[0], target, 
> > > operands[2],
> > > -                                        operands[3]));
> > > +  emit_call_insn (gen_call_value_internal (operands[0], target, 
> > > operands[2]));
> > >    DONE;
> > >  })
> > >
> > > @@ -4198,9 +4176,6 @@
> > >    [(set (match_operand 0 "" "")
> > >       (call (mem:SI (match_operand 1 "call_insn_operand" "l,S,U"))
> > >             (match_operand 2 "" "")))
> > > -   (use (unspec:SI [
> > > -          (match_operand 3 "const_int_operand")
> > > -        ] UNSPEC_CALLEE_CC))
> > >     (clobber (reg:SI RETURN_ADDR_REGNUM))]
> > >    ""
> > >    "@
> > > @@ -4220,9 +4195,7 @@
> > >  {
> > >    int i;
> > >
> > > -  /* Untyped calls always use the RISCV_CC_BASE calling convention.  */
> > > -  emit_call_insn (gen_call (operands[0], const0_rtx,
> > > -                         gen_int_mode (RISCV_CC_BASE, SImode)));
> > > +  emit_call_insn (gen_call (operands[0], const0_rtx, NULL));
> > >
> > >    for (i = 0; i < XVECLEN (operands[2], 0); i++)
> > >      {
> > > diff --git a/gcc/doc/rtl.texi b/gcc/doc/rtl.texi
> > > index 4fa4d27506c..dd90a6e58f1 100644
> > > --- a/gcc/doc/rtl.texi
> > > +++ b/gcc/doc/rtl.texi
> > > @@ -3800,13 +3800,16 @@ function calls.  It is important to distinguish 
> > > these instructions because
> > >  they imply that certain registers and memory locations may be altered
> > >  unpredictably.
> > >
> > > -@findex CALL_INSN_FUNCTION_USAGE
> > >  @code{call_insn} insns have the same extra fields as @code{insn} insns,
> > > -accessed in the same way and in addition contain a field
> > > -@code{CALL_INSN_FUNCTION_USAGE}, which contains a list (chain of
> > > -@code{expr_list} expressions) containing @code{use}, @code{clobber} and
> > > -sometimes @code{set} expressions that denote hard registers and
> > > -@code{mem}s used or clobbered by the called function.
> > > +accessed in the same way.  They have two further fields:
> > > +
> > > +@table @code
> > > +@findex CALL_INSN_FUNCTION_USAGE
> > > +@item CALL_INSN_FUNCTION_USAGE
> > > +This field contains a list (chain of @code{expr_list} expressions)
> > > +containing @code{use}, @code{clobber} and sometimes @code{set}
> > > +expressions that denote hard registers and @code{mem}s used or
> > > +clobbered by the called function.
> > >
> > >  A @code{mem} generally points to a stack slot in which arguments passed
> > >  to the libcall by reference (@pxref{Register Arguments,
> > > @@ -3825,6 +3828,13 @@ that the function returns one of its arguments.  
> > > Such a @code{set} may
> > >  look like a no-op if the same register holds the argument and the return
> > >  value.
> > >
> > > +@findex CALL_INSN_ABI_ID
> > > +@item CALL_INSN_ABI_ID
> > > +This field identifies the callee's calling convention, as an index in
> > > +the range [0, @code{NUM_ABI_IDS} - 1].  See @file{function-abi.h} for
> > > +more details about the representation of these calling conventions.
> > > +@end table
> > > +
> > >  @findex code_label
> > >  @findex CODE_LABEL_NUMBER
> > >  @item code_label
> > > diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
> > > index a4ae17decb0..e4143c1337f 100644
> > > --- a/gcc/doc/tm.texi
> > > +++ b/gcc/doc/tm.texi
> > > @@ -2020,17 +2020,6 @@ descriptor.  Targets only need to define this hook 
> > > if they support
> > >  interoperability between several ABIs in the same translation unit.
> > >  @end deftypefn
> > >
> > > -@deftypefn {Target Hook} {const predefined_function_abi &} 
> > > TARGET_INSN_CALLEE_ABI (const rtx_insn *@var{insn})
> > > -This hook returns a description of the ABI used by the target of
> > > -call instruction @var{insn}; see the definition of
> > > -@code{predefined_function_abi} for details of the ABI descriptor.
> > > -Only the global function @code{insn_callee_abi} should call this hook
> > > -directly.
> > > -
> > > -Targets only need to define this hook if they support
> > > -interoperability between several ABIs in the same translation unit.
> > > -@end deftypefn
> > > -
> > >  @cindex call-used register
> > >  @cindex call-clobbered register
> > >  @cindex call-saved register
> > > diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
> > > index 1acda0c264c..4cb2becc4d4 100644
> > > --- a/gcc/doc/tm.texi.in
> > > +++ b/gcc/doc/tm.texi.in
> > > @@ -1743,8 +1743,6 @@ must be defined.  Modern ports should define 
> > > @code{CALL_REALLY_USED_REGISTERS}.
> > >  @cindex call-saved register
> > >  @hook TARGET_FNTYPE_ABI
> > >
> > > -@hook TARGET_INSN_CALLEE_ABI
> > > -
> > >  @cindex call-used register
> > >  @cindex call-clobbered register
> > >  @cindex call-saved register
> > > diff --git a/gcc/emit-rtl.cc b/gcc/emit-rtl.cc
> > > index e41ec2283b8..ade5ea09c9e 100644
> > > --- a/gcc/emit-rtl.cc
> > > +++ b/gcc/emit-rtl.cc
> > > @@ -4037,6 +4037,9 @@ try_split (rtx pat, rtx_insn *trial, int last)
> > >             p = &XEXP (*p, 1);
> > >           *p = CALL_INSN_FUNCTION_USAGE (trial);
> > >
> > > +         /* Preserve the ABI information from the original call.  */
> > > +         CALL_INSN_ABI_ID (insn) = CALL_INSN_ABI_ID (trial);
> > > +
> > >           /* If the old call was a sibling call, the new one must
> > >              be too.  */
> > >           SIBLING_CALL_P (insn) = SIBLING_CALL_P (trial);
> > > @@ -4226,6 +4229,7 @@ make_call_insn_raw (rtx pattern)
> > >    INSN_CODE (insn) = -1;
> > >    REG_NOTES (insn) = NULL;
> > >    CALL_INSN_FUNCTION_USAGE (insn) = NULL;
> > > +  CALL_INSN_ABI_ID (insn) = 0;
> > >    INSN_LOCATION (insn) = curr_insn_location ();
> > >    BLOCK_FOR_INSN (insn) = NULL;
> > >
> > > @@ -6627,6 +6631,7 @@ emit_copy_of_insn_after (rtx_insn *insn, rtx_insn 
> > > *after)
> > >        if (CALL_INSN_FUNCTION_USAGE (insn))
> > >       CALL_INSN_FUNCTION_USAGE (new_rtx)
> > >         = copy_insn (CALL_INSN_FUNCTION_USAGE (insn));
> > > +      CALL_INSN_ABI_ID (new_rtx) = CALL_INSN_ABI_ID (insn);
> > >        SIBLING_CALL_P (new_rtx) = SIBLING_CALL_P (insn);
> > >        RTL_CONST_CALL_P (new_rtx) = RTL_CONST_CALL_P (insn);
> > >        RTL_PURE_CALL_P (new_rtx) = RTL_PURE_CALL_P (insn);
> > > diff --git a/gcc/function-abi.cc b/gcc/function-abi.cc
> > > index df1d2e5765b..70304597e2a 100644
> > > --- a/gcc/function-abi.cc
> > > +++ b/gcc/function-abi.cc
> > > @@ -224,10 +224,7 @@ insn_callee_abi (const rtx_insn *insn)
> > >      if (tree fndecl = get_call_fndecl (insn))
> > >        return fndecl_abi (fndecl);
> > >
> > > -  if (targetm.calls.insn_callee_abi)
> > > -    return targetm.calls.insn_callee_abi (insn);
> > > -
> > > -  return default_function_abi;
> > > +  return function_abis[CALL_INSN_ABI_ID (insn)];
> > >  }
> > >
> > >  /* Return the ABI of the function called by CALL_EXPR EXP.  Return the
> > > diff --git a/gcc/recog.cc b/gcc/recog.cc
> > > index 4cae276f1f7..a45a37db6bb 100644
> > > --- a/gcc/recog.cc
> > > +++ b/gcc/recog.cc
> > > @@ -4034,6 +4034,7 @@ peep2_attempt (basic_block bb, rtx_insn *insn, int 
> > > match_len, rtx_insn *attempt)
> > >
> > >        CALL_INSN_FUNCTION_USAGE (new_insn)
> > >       = CALL_INSN_FUNCTION_USAGE (old_insn);
> > > +      CALL_INSN_ABI_ID (new_insn) = CALL_INSN_ABI_ID (old_insn);
> > >        SIBLING_CALL_P (new_insn) = SIBLING_CALL_P (old_insn);
> > >
> > >        for (note = REG_NOTES (old_insn);
> > > diff --git a/gcc/rtl.def b/gcc/rtl.def
> > > index ad98fd59172..d5aee14b9f2 100644
> > > --- a/gcc/rtl.def
> > > +++ b/gcc/rtl.def
> > > @@ -151,9 +151,9 @@ DEF_RTL_EXPR(JUMP_INSN, "jump_insn", "uuBeLie0", 
> > > RTX_INSN)
> > >  /* An instruction that can possibly call a subroutine
> > >     but which will not change which instruction comes next
> > >     in the current function.
> > > -   Field ( rtx->u.fld[8] ) is CALL_INSN_FUNCTION_USAGE.
> > > -   All other fields ( rtx->u.fld[] ) have exact same meaning as INSN's.  
> > > */
> > > -DEF_RTL_EXPR(CALL_INSN, "call_insn", "uuBeLiee", RTX_INSN)
> > > +   Field 7 is CALL_INSN_FUNCTION_USAGE and field 8 is CALL_INSN_ABI_ID.
> > > +   All other fields ( rtx->u.fld[] ) have the same meaning as for INSNs. 
> > >  */
> > > +DEF_RTL_EXPR(CALL_INSN, "call_insn", "uuBeLieei", RTX_INSN)
> > >
> > >  /* Placeholder for tablejump JUMP_INSNs.  The pattern of this kind
> > >     of rtx is always either an ADDR_VEC or an ADDR_DIFF_VEC.  These
> > > diff --git a/gcc/rtl.h b/gcc/rtl.h
> > > index d60587dc5ce..d6824e5cbb6 100644
> > > --- a/gcc/rtl.h
> > > +++ b/gcc/rtl.h
> > > @@ -1669,6 +1669,10 @@ extern const char * const reg_note_name[];
> > >       Pseudo registers cannot be mentioned in this list.  */
> > >  #define CALL_INSN_FUNCTION_USAGE(INSN)       XEXP(INSN, 7)
> > >
> > > +/* Specifies the callee's ABI as an index in the range [0, NUM_ABI_IDS - 
> > > 1].
> > > +   See function-abi.h for more details.  */
> > > +#define CALL_INSN_ABI_ID(INSN) XCINT(INSN, 8, CALL_INSN)
> > > +
> > >  /* The label-number of a code-label.  The assembler label
> > >     is made from `L' and the label-number printed in decimal.
> > >     Label numbers are unique in a compilation.  */
> > > diff --git a/gcc/target.def b/gcc/target.def
> > > index cdb3a6a6c84..d2f7279f7d2 100644
> > > --- a/gcc/target.def
> > > +++ b/gcc/target.def
> > > @@ -5486,19 +5486,6 @@ interoperability between several ABIs in the same 
> > > translation unit.",
> > >   const predefined_function_abi &, (const_tree type),
> > >   NULL)
> > >
> > > -DEFHOOK
> > > -(insn_callee_abi,
> > > - "This hook returns a description of the ABI used by the target of\n\
> > > -call instruction @var{insn}; see the definition of\n\
> > > -@code{predefined_function_abi} for details of the ABI descriptor.\n\
> > > -Only the global function @code{insn_callee_abi} should call this hook\n\
> > > -directly.\n\
> > > -\n\
> > > -Targets only need to define this hook if they support\n\
> > > -interoperability between several ABIs in the same translation unit.",
> > > - const predefined_function_abi &, (const rtx_insn *insn),
> > > - NULL)
> > > -
> > >  /* ??? Documenting this hook requires a GFDL license grant.  */
> > >  DEFHOOK_UNDOC
> > >  (internal_arg_pointer,
> > > diff --git a/gcc/testsuite/gcc.dg/rtl/x86_64/different-structs.c 
> > > b/gcc/testsuite/gcc.dg/rtl/x86_64/different-structs.c
> > > index f9d1555b0c8..ac36546331f 100644
> > > --- a/gcc/testsuite/gcc.dg/rtl/x86_64/different-structs.c
> > > +++ b/gcc/testsuite/gcc.dg/rtl/x86_64/different-structs.c
> > > @@ -66,7 +66,8 @@ double __RTL test (struct foo *f, const struct bar *b)
> > >                          (const_int 0))) 
> > > "../../src/gcc/testsuite/gcc.dg/rtl/x86_64/different-structs.c":23
> > >                   (expr_list:REG_CALL_DECL (symbol_ref:DI ("sqrt") [flags 
> > > 0x41]  <function_decl 0x7fa24e331d00 sqrt>)
> > >                      (expr_list:REG_EH_REGION (const_int 0)))
> > > -                (expr_list:DF (use (reg:DF xmm0))))
> > > +                (expr_list:DF (use (reg:DF xmm0)))
> > > +                0)
> > >        (edge-to exit (flags "ABNORMAL | SIBCALL"))
> > >      ) ;; block 2
> > >      (cbarrier 18)
> > > diff --git a/gcc/testsuite/selftests/x86_64/call-insn.rtl 
> > > b/gcc/testsuite/selftests/x86_64/call-insn.rtl
> > > index 8f3a7812687..5423705bb18 100644
> > > --- a/gcc/testsuite/selftests/x86_64/call-insn.rtl
> > > +++ b/gcc/testsuite/selftests/x86_64/call-insn.rtl
> > > @@ -10,7 +10,8 @@
> > >             (expr_list:REG_EH_REGION (const_int 0)
> > >                (nil)))
> > >          (expr_list:DF (use (reg:DF xmm0))
> > > -           (nil)))
> > > +           (nil))
> > > +     0)
> > >        (edge-to exit (flags "FALLTHRU"))
> > >      ) ;; block 2
> > >    ) ;; insn-chain
>
>
>
> --
> H.J.



-- 
H.J.

Reply via email to