public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/vendors/ARM/heads/gcs-13)] Add a target hook for sibcall epilogues
@ 2024-02-14 15:35 Szabolcs Nagy
  0 siblings, 0 replies; only message in thread
From: Szabolcs Nagy @ 2024-02-14 15:35 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:cf82a74f716ad2b2b3b449dfde00222269c24f83

commit cf82a74f716ad2b2b3b449dfde00222269c24f83
Author: Richard Sandiford <richard.sandiford@arm.com>
Date:   Tue Dec 5 09:35:57 2023 +0000

    Add a target hook for sibcall epilogues
    
    Epilogues for sibling calls are generated using the
    sibcall_epilogue pattern.  One disadvantage of this approach
    is that the target doesn't know which call the epilogue is for,
    even though the code that generates the pattern has the call
    to hand.
    
    Although call instructions are currently rtxes, and so could be
    passed as an operand to the pattern, the main point of introducing
    rtx_insn was to move towards separating the rtx and insn types
    (a good thing IMO).  There also isn't an existing practice of
    passing genuine instructions (as opposed to labels) to
    instruction patterns.
    
    This patch therefore adds a hook that can be defined as an
    alternative to sibcall_epilogue.  The advantage is that it
    can be passed the call; the disadvantage is that it can't
    use .md conveniences like generating instructions from
    textual patterns (although most epilogues are too complex
    to benefit much from that anyway).
    
    gcc/
            * doc/tm.texi.in: Add TARGET_EMIT_EPILOGUE_FOR_SIBCALL.
            * doc/tm.texi: Regenerate.
            * target.def (emit_epilogue_for_sibcall): New hook.
            * calls.cc (can_implement_as_sibling_call_p): Use it.
            * function.cc (thread_prologue_and_epilogue_insns): Likewise.
            (reposition_prologue_and_epilogue_notes): Likewise.
            * config/aarch64/aarch64-protos.h (aarch64_expand_epilogue): Take
            an rtx_call_insn * rather than a bool.
            * config/aarch64/aarch64.cc (aarch64_expand_epilogue): Likewise.
            (TARGET_EMIT_EPILOGUE_FOR_SIBCALL): Define.
            * config/aarch64/aarch64.md (epilogue): Update call.
            (sibcall_epilogue): Delete.
    
    (cherry picked from commit 2e0aefa77157396acb48833407637303edba450a)

Diff:
---
 gcc/calls.cc                        |  3 ++-
 gcc/config/aarch64/aarch64-protos.h |  2 +-
 gcc/config/aarch64/aarch64.cc       | 11 +++++++----
 gcc/config/aarch64/aarch64.md       | 11 +----------
 gcc/doc/tm.texi                     |  8 ++++++++
 gcc/doc/tm.texi.in                  |  2 ++
 gcc/function.cc                     | 15 +++++++++++++--
 gcc/target.def                      |  9 +++++++++
 8 files changed, 43 insertions(+), 18 deletions(-)

diff --git a/gcc/calls.cc b/gcc/calls.cc
index 4d7f6c3d2912..b550673017c0 100644
--- a/gcc/calls.cc
+++ b/gcc/calls.cc
@@ -2493,7 +2493,8 @@ can_implement_as_sibling_call_p (tree exp,
 				 tree addr,
 				 const args_size &args_size)
 {
-  if (!targetm.have_sibcall_epilogue ())
+  if (!targetm.have_sibcall_epilogue ()
+      && !targetm.emit_epilogue_for_sibcall)
     {
       maybe_complain_about_tail_call
 	(exp,
diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
index 818361b57e6e..7be51ea6f56c 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -878,7 +878,7 @@ const char * aarch64_gen_far_branch (rtx *, int, const char *, const char *);
 const char * aarch64_output_probe_stack_range (rtx, rtx);
 const char * aarch64_output_probe_sve_stack_clash (rtx, rtx, rtx, rtx);
 void aarch64_err_no_fpadvsimd (machine_mode);
-void aarch64_expand_epilogue (bool);
+void aarch64_expand_epilogue (rtx_call_insn *);
 rtx aarch64_ptrue_all (unsigned int);
 opt_machine_mode aarch64_ptrue_all_mode (rtx);
 rtx aarch64_convert_sve_data_to_pred (rtx, machine_mode, rtx);
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 06aef1bb725c..410e0b38ece9 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -10208,7 +10208,7 @@ aarch64_use_return_insn_p (void)
    from a deallocated stack, and we optimize the unwind records by
    emitting them all together if possible.  */
 void
-aarch64_expand_epilogue (bool for_sibcall)
+aarch64_expand_epilogue (rtx_call_insn *sibcall)
 {
   aarch64_frame &frame = cfun->machine->frame;
   poly_int64 initial_adjust = frame.initial_adjust;
@@ -10344,7 +10344,7 @@ aarch64_expand_epilogue (bool for_sibcall)
     }
 
   /* Stack adjustment for exception handler.  */
-  if (crtl->calls_eh_return && !for_sibcall)
+  if (crtl->calls_eh_return && !sibcall)
     {
       /* If the EH_RETURN_TAKEN_RTX flag is set then we need
 	 to unwind the stack and jump to the handler, otherwise
@@ -10379,7 +10379,7 @@ aarch64_expand_epilogue (bool for_sibcall)
 	   explicitly authenticate.
     */
   if (aarch64_return_address_signing_enabled ()
-      && (for_sibcall || !TARGET_ARMV8_3))
+      && (sibcall || !TARGET_ARMV8_3))
     {
       switch (aarch_ra_sign_key)
 	{
@@ -10397,7 +10397,7 @@ aarch64_expand_epilogue (bool for_sibcall)
     }
 
   emit_use (gen_rtx_REG (DImode, LR_REGNUM));
-  if (!for_sibcall)
+  if (!sibcall)
     emit_jump_insn (ret_rtx);
 }
 
@@ -28134,6 +28134,9 @@ aarch64_libgcc_floating_mode_supported_p
 #undef TARGET_CONST_ANCHOR
 #define TARGET_CONST_ANCHOR 0x1000000
 
+#undef TARGET_EMIT_EPILOGUE_FOR_SIBCALL
+#define TARGET_EMIT_EPILOGUE_FOR_SIBCALL aarch64_expand_epilogue
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 #include "gt-aarch64.h"
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 922cc9875953..1f8b780d94ba 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -869,16 +869,7 @@
   [(clobber (const_int 0))]
   ""
   "
-  aarch64_expand_epilogue (false);
-  DONE;
-  "
-)
-
-(define_expand "sibcall_epilogue"
-  [(clobber (const_int 0))]
-  ""
-  "
-  aarch64_expand_epilogue (true);
+  aarch64_expand_epilogue (nullptr);
   DONE;
   "
 )
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index df33a5303a74..82729c887d4e 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -11701,6 +11701,14 @@ the hook might return true if the prologue and epilogue need to switch
 between instruction sets.
 @end deftypefn
 
+@deftypefn {Target Hook} void TARGET_EMIT_EPILOGUE_FOR_SIBCALL (rtx_call_insn *@var{call})
+If defined, this hook emits an epilogue sequence for sibling (tail)
+call instruction @var{call}.  Another way of providing epilogues
+for sibling calls is to define the @code{sibcall_epilogue} instruction
+pattern; the main advantage of this hook over the pattern is that it
+has access to the call instruction.
+@end deftypefn
+
 @deftypefn {Target Hook} void TARGET_MACHINE_DEPENDENT_REORG (void)
 If non-null, this hook performs a target-specific pass over the
 instruction stream.  The compiler will run it at all optimization levels,
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index d816c31f7a58..18ea2723f9d7 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -7724,6 +7724,8 @@ to by @var{ce_info}.
 
 @hook TARGET_USE_LATE_PROLOGUE_EPILOGUE
 
+@hook TARGET_EMIT_EPILOGUE_FOR_SIBCALL
+
 @hook TARGET_MACHINE_DEPENDENT_REORG
 
 @hook TARGET_INIT_BUILTINS
diff --git a/gcc/function.cc b/gcc/function.cc
index 443d6855284c..0114e0260390 100644
--- a/gcc/function.cc
+++ b/gcc/function.cc
@@ -6231,7 +6231,17 @@ thread_prologue_and_epilogue_insns (void)
       if (!(CALL_P (insn) && SIBLING_CALL_P (insn)))
 	continue;
 
-      if (rtx_insn *ep_seq = targetm.gen_sibcall_epilogue ())
+      rtx_insn *ep_seq;
+      if (targetm.emit_epilogue_for_sibcall)
+	{
+	  start_sequence ();
+	  targetm.emit_epilogue_for_sibcall (as_a<rtx_call_insn *> (insn));
+	  ep_seq = get_insns ();
+	  end_sequence ();
+	}
+      else
+	ep_seq = targetm.gen_sibcall_epilogue ();
+      if (ep_seq)
 	{
 	  start_sequence ();
 	  emit_note (NOTE_INSN_EPILOGUE_BEG);
@@ -6291,7 +6301,8 @@ reposition_prologue_and_epilogue_notes (void)
 {
   if (!targetm.have_prologue ()
       && !targetm.have_epilogue ()
-      && !targetm.have_sibcall_epilogue ())
+      && !targetm.have_sibcall_epilogue ()
+      && !targetm.emit_epilogue_for_sibcall)
     return;
 
   /* Since the hash table is created on demand, the fact that it is
diff --git a/gcc/target.def b/gcc/target.def
index 9839c291c2ed..5c6f183522b3 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -4107,6 +4107,15 @@ between instruction sets.",
  bool, (),
  hook_bool_void_false)
 
+DEFHOOK
+(emit_epilogue_for_sibcall,
+ "If defined, this hook emits an epilogue sequence for sibling (tail)\n\
+call instruction @var{call}.  Another way of providing epilogues\n\
+for sibling calls is to define the @code{sibcall_epilogue} instruction\n\
+pattern; the main advantage of this hook over the pattern is that it\n\
+has access to the call instruction.",
+ void, (rtx_call_insn *call), NULL)
+
 /* Do machine-dependent code transformations.  Called just before
      delayed-branch scheduling.  */
 DEFHOOK

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2024-02-14 15:35 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-02-14 15:35 [gcc(refs/vendors/ARM/heads/gcs-13)] Add a target hook for sibcall epilogues Szabolcs Nagy

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).