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

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.

Reply via email to