]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Add CALL_INSN_ABI_ID
authorRichard Sandiford <rdsandiford@googlemail.com>
Wed, 3 Jun 2026 12:11:17 +0000 (13:11 +0100)
committerRichard Sandiford <rdsandiford@googlemail.com>
Wed, 3 Jun 2026 12:11:17 +0000 (13:11 +0100)
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/.

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.

20 files changed:
gcc/calls.cc
gcc/cfgcleanup.cc
gcc/config/aarch64/aarch64-protos.h
gcc/config/aarch64/aarch64.cc
gcc/config/aarch64/aarch64.md
gcc/config/i386/i386.cc
gcc/config/riscv/riscv-sr.cc
gcc/config/riscv/riscv.cc
gcc/config/riscv/riscv.md
gcc/doc/rtl.texi
gcc/doc/tm.texi
gcc/doc/tm.texi.in
gcc/emit-rtl.cc
gcc/function-abi.cc
gcc/recog.cc
gcc/rtl.def
gcc/rtl.h
gcc/target.def
gcc/testsuite/gcc.dg/rtl/x86_64/different-structs.c
gcc/testsuite/selftests/x86_64/call-insn.rtl

index d491a414611516e38a0b9d2fd1e1b20bcf4ec9b3..e5d67b6c97a518d70bf322538911de4222e6ff96 100644 (file)
@@ -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
index b6f04754f251d8d6b4d77edd20083c695440c1a1..1d9ec908dab0cc0da6f25aa122f56bc3e36fc834 100644 (file)
@@ -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;
 
index 513b556398fac7c733de47c27587c3aaa07cbcf3..34e770db60c030e5310e0b57c5240b63d06413af 100644 (file)
@@ -888,7 +888,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);
index 5a859e12b1a55e70284469e3e9c175eee849e18d..983cef6d68114281e1d4388e4d6f3f1272c3920b 100644 (file)
@@ -2841,29 +2841,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
@@ -2909,14 +2895,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.  */
 
@@ -8114,7 +8092,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);
@@ -11144,8 +11121,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 ();
@@ -34237,9 +34215,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
 
index 6c31f7c72114da5a48da95e30c359c36cd059d98..6c141df40a4b64fa0a0e7f46959719b187202a4f 100644 (file)
   {
     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
index e1b2cbea12bde4905ecd2a63ef02ae9fa9ba5727..2945081234b3c5c073684aacf69f4a173822d571 100644 (file)
@@ -21871,19 +21871,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
@@ -21905,6 +21892,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.  */
@@ -28818,9 +28806,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
 
index 531ba66cbb1741fcaed78b99bcb9d6ae9d6e4b5c..e1b2dafc30b923e82edbe78d1147b55c28683a92 100644 (file)
@@ -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
index 9ab4ab3cd1d97b0e77750c6cb74a56b2de998ff4..362c66c82230c6005ec35c192dda3dc5a3bfe990 100644 (file)
@@ -3251,8 +3251,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 ();
@@ -7295,8 +7295,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);
 }
@@ -7822,30 +7821,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
@@ -11795,8 +11770,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
@@ -16297,8 +16272,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 \
index 5f9f26ee63f4cd85fea250b8aabcc62d903b27f3..94f81b9c29eb50faf79ebb4daeebd77edcd3a118 100644 (file)
@@ -83,9 +83,6 @@
   UNSPEC_CLMULH
   UNSPEC_CLMULR
 
-  ;; the calling convention of callee
-  UNSPEC_CALLEE_CC
-
   ;; String unspecs
   UNSPEC_STRLEN
 
 (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
   [(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
 (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))]
   ""
   "@
   [(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;
 })
 
   [(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))]
   ""
   "@
 {
   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++)
     {
index 082cb39372bc4dd4b0d7b891a62efd9e0809b09b..f79571ac6cfaad4b3340f5f9341e01b99a73d0fd 100644 (file)
@@ -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
index 1fbf43c6c57799372752f581528e122689a33f15..d1e5d1b79521d5236db97292348e3ba9b144e6dc 100644 (file)
@@ -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
index 6ecbeda09ca9b6473f12f78f8805ced44907f146..6c9c4658b9d9cad92403c0ba554637af303e21b8 100644 (file)
@@ -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
index 7f5d267341ac30afbd25c65bec2910f5b6ce3150..4a23eaefe0246e341ccb6bd2b14f4d5def6195e8 100644 (file)
@@ -4036,6 +4036,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);
@@ -4225,6 +4228,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;
 
@@ -6626,6 +6630,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);
index 53a76dc2341dfb5f09b11136aed2a3926b183e4c..277863ecee3c8f1b6bed46aa8ce7f48e3eb39cfa 100644 (file)
@@ -227,10 +227,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
index 4cae276f1f70602c4f7fa846c090f0405f64e6ee..a45a37db6bb9b806b9d6c8abdb36a9a8f98fa68d 100644 (file)
@@ -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);
index c88b4565b3e98e9487f19a1f692d48ce55cb73b5..e83d6554c808f68bc3846fcc538ab801c734a359 100644 (file)
@@ -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
index 93315cb580224a092fd0691947de7d55ed8cfd90..747d917ecf2ed9677fbe7b163cf2b20e9258f201 100644 (file)
--- 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.  */
index 25a94559e198aef2c3e842f02aa5414c5193c4a6..6ade66716a3bb671174613ecbf34cc35b1277b73 100644 (file)
@@ -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,
index f9d1555b0c8aaa88b7de94021ef7359cadf41529..ac36546331fa90cd55a0a681e77c1a8e6d4593ad 100644 (file)
@@ -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)
index 8f3a78126879d8feb1d59d3f9bf44c37a662a890..5423705bb188a445817718a11694ecce4d360906 100644 (file)
@@ -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