aboutsummaryrefslogtreecommitdiff
path: root/gcc/calls.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2020-09-27 19:11:58 +0930
committerAlan Modra <amodra@gmail.com>2020-11-03 09:36:40 +1030
commit18963d3bee780cd8a6477ad5a198410758ec4e60 (patch)
treecb7655415ee5b592ad09023beec1f1466cd365e1 /gcc/calls.c
parent3ceaafc95c77cded164cde58da41bed0cbe76489 (diff)
downloadgcc-18963d3bee780cd8a6477ad5a198410758ec4e60.zip
gcc-18963d3bee780cd8a6477ad5a198410758ec4e60.tar.gz
gcc-18963d3bee780cd8a6477ad5a198410758ec4e60.tar.bz2
can_implement_as_sibling_call_p REG_PARM_STACK_SPACE check
This moves an #ifdef block of code from calls.c to targetm.function_ok_for_sibcall. Only two targets, x86 and rs6000, define REG_PARM_STACK_SPACE or OUTGOING_REG_PARM_STACK_SPACE macros that might vary depending on the called function. Macros like UNITS_PER_WORD don't change over a function boundary, nor does the MIPS ABI, nor does TARGET_64BIT on PA-RISC. Other targets are even more trivially proven to not need the calls.c code. Besides cleaning up a small piece of #ifdef code, the motivation for this patch is to allow tail calls on PowerPC for functions that require less reg_parm_stack_space than their caller. The original code in calls.c only permitted tail calls when exactly equal, but on PowerPC we can tail call if the callee has less or equal REG_PARM_STACK_SPACE than the caller, as demonstrated by the testcase. So we should use /* If reg parm stack space increases, we cannot sibcall. */ if (REG_PARM_STACK_SPACE (decl ? decl : fntype) > INCOMING_REG_PARM_STACK_SPACE (current_function_decl)) and note the change to use INCOMING_REG_PARM_STACK_SPACE. REG_PARM_STACK_SPACE has always been wrong there for PowerPC. See https://gcc.gnu.org/pipermail/gcc-patches/2014-May/389867.html for why if you're curious. Not that it matters, because PowerPC can do without this check entirely, relying on a stack slot test in generic code. a) The generic code checks that arg passing stack in the callee is not greater than that in the caller, and, b) ELFv2 only allocates reg_parm_stack_space when some parameter is passed on the stack. Point (b) means that zero reg_parm_stack_space implies zero stack space, and non-zero reg_parm_stack_space implies non-zero stack space. So the case of 0 reg_parm_stack_space in the caller and 64 in the callee will be caught by (a). gcc/ PR middle-end/97267 * calls.h (maybe_complain_about_tail_call): Declare. * calls.c (maybe_complain_about_tail_call): Make global. (can_implement_as_sibling_call_p): Delete reg_parm_stack_space param. Adjust caller. Move REG_PARM_STACK_SPACE check to.. * config/i386/i386.c (ix86_function_ok_for_sibcall): ..here. gcc/testsuite/ PR middle-end/97267 * gcc.target/powerpc/pr97267.c: New test.
Diffstat (limited to 'gcc/calls.c')
-rw-r--r--gcc/calls.c18
1 files changed, 1 insertions, 17 deletions
diff --git a/gcc/calls.c b/gcc/calls.c
index a8f4596..1a7632d 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -1922,7 +1922,7 @@ maybe_warn_nonstring_arg (tree fndecl, tree exp)
/* Issue an error if CALL_EXPR was flagged as requiring
tall-call optimization. */
-static void
+void
maybe_complain_about_tail_call (tree call_expr, const char *reason)
{
gcc_assert (TREE_CODE (call_expr) == CALL_EXPR);
@@ -3525,7 +3525,6 @@ static bool
can_implement_as_sibling_call_p (tree exp,
rtx structure_value_addr,
tree funtype,
- int reg_parm_stack_space ATTRIBUTE_UNUSED,
tree fndecl,
int flags,
tree addr,
@@ -3550,20 +3549,6 @@ can_implement_as_sibling_call_p (tree exp,
return false;
}
-#ifdef REG_PARM_STACK_SPACE
- /* If outgoing reg parm stack space changes, we cannot do sibcall. */
- if (OUTGOING_REG_PARM_STACK_SPACE (funtype)
- != OUTGOING_REG_PARM_STACK_SPACE (TREE_TYPE (current_function_decl))
- || (reg_parm_stack_space != REG_PARM_STACK_SPACE (current_function_decl)))
- {
- maybe_complain_about_tail_call (exp,
- "inconsistent size of stack space"
- " allocated for arguments which are"
- " passed in registers");
- return false;
- }
-#endif
-
/* Check whether the target is able to optimize the call
into a sibcall. */
if (!targetm.function_ok_for_sibcall (fndecl, exp))
@@ -4088,7 +4073,6 @@ expand_call (tree exp, rtx target, int ignore)
try_tail_call = can_implement_as_sibling_call_p (exp,
structure_value_addr,
funtype,
- reg_parm_stack_space,
fndecl,
flags, addr, args_size);