diff options
Diffstat (limited to '0149-Backport-SME-Add-a-target-hook-for-sibcall-epilogues.patch')
-rw-r--r-- | 0149-Backport-SME-Add-a-target-hook-for-sibcall-epilogues.patch | 239 |
1 files changed, 239 insertions, 0 deletions
diff --git a/0149-Backport-SME-Add-a-target-hook-for-sibcall-epilogues.patch b/0149-Backport-SME-Add-a-target-hook-for-sibcall-epilogues.patch new file mode 100644 index 0000000..d892432 --- /dev/null +++ b/0149-Backport-SME-Add-a-target-hook-for-sibcall-epilogues.patch @@ -0,0 +1,239 @@ +From e906213086639df81085a0101bf88fb66c1dbc2b Mon Sep 17 00:00:00 2001 +From: Richard Sandiford <richard.sandiford@arm.com> +Date: Tue, 5 Dec 2023 09:35:57 +0000 +Subject: [PATCH 050/157] [Backport][SME] Add a target hook for sibcall + epilogues + +Reference: https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=2e0aefa77157396acb48833407637303edba450a + +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. +--- + 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 4d0bc45be..c1db66883 100644 +--- a/gcc/calls.cc ++++ b/gcc/calls.cc +@@ -2461,7 +2461,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 86e444a60..97984f3ab 100644 +--- a/gcc/config/aarch64/aarch64-protos.h ++++ b/gcc/config/aarch64/aarch64-protos.h +@@ -887,7 +887,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 fd1114b52..055b436b1 100644 +--- a/gcc/config/aarch64/aarch64.cc ++++ b/gcc/config/aarch64/aarch64.cc +@@ -10046,7 +10046,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) + { + poly_int64 initial_adjust = cfun->machine->frame.initial_adjust; + HOST_WIDE_INT callee_adjust = cfun->machine->frame.callee_adjust; +@@ -10194,7 +10194,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 (aarch64_ra_sign_key) + { +@@ -10212,7 +10212,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) + { + /* We need to unwind the stack by the offset computed by + EH_RETURN_STACKADJ_RTX. We have already reset the CFA +@@ -10223,7 +10223,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); + } + +@@ -28246,6 +28246,9 @@ aarch64_libgcc_floating_mode_supported_p + #undef TARGET_HAVE_SHADOW_CALL_STACK + #define TARGET_HAVE_SHADOW_CALL_STACK true + ++#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 7267a74d6..a78476c8a 100644 +--- a/gcc/config/aarch64/aarch64.md ++++ b/gcc/config/aarch64/aarch64.md +@@ -871,16 +871,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 d930d233d..369f4b8da 100644 +--- a/gcc/doc/tm.texi ++++ b/gcc/doc/tm.texi +@@ -11703,6 +11703,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 19eabec48..748b0777a 100644 +--- a/gcc/doc/tm.texi.in ++++ b/gcc/doc/tm.texi.in +@@ -7710,6 +7710,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 7c90b5f23..ddab43ca4 100644 +--- a/gcc/function.cc ++++ b/gcc/function.cc +@@ -6209,7 +6209,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); +@@ -6259,7 +6269,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 fd4899612..cf9f96eba 100644 +--- a/gcc/target.def ++++ b/gcc/target.def +@@ -4141,6 +4141,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 +-- +2.33.0 + |