On 13-12-13 06:43, Jeff Law wrote:
Was this meant perhaps?
...
|| (reg_parm_stack_space != REG_PARM_STACK_SPACE
(current_function_decl))
I think you're probably right.
sibcall/tailcall basically re-use the current function's stack
Jeff,
Right, say we have function a tail-calling function b. If the sibcall
optimization is done, function a deallocates it's stack frame before calling
function b.
so if there's a
difference between REG_PARM_STACK_SPACE (fndecl) and REG_PARM_STACK_SPACE
(current_function_decl), then we can't perform a sibcall/tailcall optimization.
So the pattern that we want to check a property of fndecl and
current_function_decl and if they don't match, then don't do a sibcall is
repeated in a few places.
I wonder if OUTGOING_REG_PARM_STACK_SPACE makes a difference here.
If OUTGOING_REG_PARM_STACK_SPACE == 0, it is the responsibility of the callee to
allocate the area reserved for arguments passed in registers. AFAIU, both
functions a and b would do that in their own stack frame, and there's no need to
test for reg_parm_stack_space != REG_PARM_STACK_SPACE (current_function_decl).
If OUTGOING_REG_PARM_STACK_SPACE != 0, it is the responsibility of the caller to
allocate the area reserved for arguments passed in registers. Which means that
function a and b share the space allocated by the caller of function a.
AFAIU, what is required is reg_parm_stack_space <= REG_PARM_STACK_SPACE
(current_function_decl).
So this might be a more precise fix:
...
diff --git a/gcc/calls.c b/gcc/calls.c
index 3963bc2..47dc844 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -2593,7 +2593,8 @@ expand_call (tree exp, rtx target, int ignore)
/* If outgoing reg parm stack space changes, we can not do sibcall. */
|| (OUTGOING_REG_PARM_STACK_SPACE (funtype)
!= OUTGOING_REG_PARM_STACK_SPACE (TREE_TYPE (current_function_decl)))
- || (reg_parm_stack_space != REG_PARM_STACK_SPACE (fndecl))
+ || (OUTGOING_REG_PARM_STACK_SPACE (funtype)
+ && reg_parm_stack_space > REG_PARM_STACK_SPACE
(current_function_decl))
#endif
/* Check whether the target is able to optimize the call
into a sibcall. */
...
But probably not a stage3 fix.
Assuming you bootstrap & test successfully, consider a patch which fixes this
pre-approved.
Bootstrapped and reg-tested attached patch on x86_64. Committed to trunk.
Thanks,
- Tom
jeff
2013-12-14 Tom de Vries <t...@codesourcery.com>
* calls.c (expand_call): Fix REG_PARM_STACK_SPACE comparison.
diff --git a/gcc/calls.c b/gcc/calls.c
index 2226e78..501474b 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -2595,7 +2595,7 @@ expand_call (tree exp, rtx target, int ignore)
/* If outgoing reg parm stack space changes, we can not do sibcall. */
|| (OUTGOING_REG_PARM_STACK_SPACE (funtype)
!= OUTGOING_REG_PARM_STACK_SPACE (TREE_TYPE (current_function_decl)))
- || (reg_parm_stack_space != REG_PARM_STACK_SPACE (fndecl))
+ || (reg_parm_stack_space != REG_PARM_STACK_SPACE (current_function_decl))
#endif
/* Check whether the target is able to optimize the call
into a sibcall. */