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.
