public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* Problems with sibling calls
@ 2009-05-29 14:16 Georg-Johann Lay
  2009-05-29 16:14 ` Dave Korn
                   ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: Georg-Johann Lay @ 2009-05-29 14:16 UTC (permalink / raw)
  To: gcc

Hi,

I'd like to support sibling calls for a target where function args can 
be passed in call-saved registers, namely AVR.

The trouble is this: If a callee gets some arguments passed on the stack 
or in call-saved regs, the callee is not ok for a sibling call. That's 
because sibcall_epilogue executes before sibcall insns.

All this information is pretty easy available in FUNCTION_ARGS resp. 
FUNCTION_ARG_ADVANCE and can be stored in CUMULATIVE_ARGS.

However, the place where the information is needed is in 
targetm.function_ok_for_sibcall (aka. TARGET_FUNCTION_OK_FOR_SIBCALL), 
and that hook only gets the function decl and call expression trees, but 
these trees do not contain information about where the calle's arguments 
get passed.

How can that be fixed? Most probably, I am missing something, and the 
information is hidden somewhere is the trees passed to 
targetm.function_ok_for_sibcall?
All of the following fixed I considered are not nice:

=1=
Store the needed information in a static backend variable. Store in 
FUNCTION_ARG et al. and use it in TARGET_FUNCTION_OK_FOR_SIBCALL.
Bad, because this makes implications on the way calls.c runs the backend 
hooks. May break if local functions are involved.

=2=
Copy the machinery that elaborates the function arguments from calls.c 
to the backend and redo all the work on the arguments to be passed.

=3=
Introduce a new backend hook
    bool targetm.function_ok_for_sibcall_with_cum (tree, tree, 
CUMULATIVE_ARGS*);
and call it with &args_so_far from calls.c:expand_call

I'd prefer =3= but I don't want to change the middle end. =1= works 
(AVR does not implement local functions) fine but seems too hacky. =2= 
might work but is overkill.

So what am I missing here? Is there some other approach to solve this?

If =3= is appropriate I could workout a patch and provide it (calls.c, 
targetm, docs/tm.texi, ...).

Thanks much

cheers, Georg-Johann



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Problems with sibling calls
  2009-05-29 14:16 Problems with sibling calls Georg-Johann Lay
@ 2009-05-29 16:14 ` Dave Korn
  2009-05-29 16:56   ` Georg-Johann Lay
  2009-05-29 16:26 ` Ian Lance Taylor
  2009-05-30 18:26 ` Ulrich Weigand
  2 siblings, 1 reply; 9+ messages in thread
From: Dave Korn @ 2009-05-29 16:14 UTC (permalink / raw)
  To: Georg-Johann Lay; +Cc: gcc

Georg-Johann Lay wrote:

> The trouble is this: If a callee gets some arguments passed on the stack
> or in call-saved regs, the callee is not ok for a sibling call. That's
> because sibcall_epilogue executes before sibcall insns.
> 
> All this information is pretty easy available in FUNCTION_ARGS resp.
> FUNCTION_ARG_ADVANCE and can be stored in CUMULATIVE_ARGS.
> 
> However, the place where the information is needed is in
> targetm.function_ok_for_sibcall (aka. TARGET_FUNCTION_OK_FOR_SIBCALL),
> and that hook only gets the function decl and call expression trees, but
> these trees do not contain information about where the calle's arguments
> get passed.
> 
> How can that be fixed? Most probably, I am missing something, and the
> information is hidden somewhere is the trees passed to
> targetm.function_ok_for_sibcall?

> So what am I missing here? Is there some other approach to solve this?

  The standard answer is that frame layout and other per-function info is
stored in the "struct function" machine-dependent part of the global 'cfun'
current function struct.  See:

http://gcc.gnu.org/onlinedocs/gccint/Per_002dFunction-Data.html

    cheers,
      DaveK

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Problems with sibling calls
  2009-05-29 14:16 Problems with sibling calls Georg-Johann Lay
  2009-05-29 16:14 ` Dave Korn
@ 2009-05-29 16:26 ` Ian Lance Taylor
  2009-05-29 16:38   ` Georg-Johann Lay
  2009-05-30 18:26 ` Ulrich Weigand
  2 siblings, 1 reply; 9+ messages in thread
From: Ian Lance Taylor @ 2009-05-29 16:26 UTC (permalink / raw)
  To: Georg-Johann Lay; +Cc: gcc

Georg-Johann Lay <avr@gjlay.de> writes:

> The trouble is this: If a callee gets some arguments passed on the
> stack or in call-saved regs, the callee is not ok for a sibling
> call. That's because sibcall_epilogue executes before sibcall insns.

I'm having trouble with your terminology "call-saved regs".  Do that
mean "caller-saved regs" or "callee-saved regs"?

I gather that in the case where f wants to make a sibling call to g, the
problem is that this fails if g accepts arguments anywhere other than in
registers which are neither caller-saved nor callee-saved.  I would
expect that that would be fairly easy to determine from the call
expression.  You can be conservative when doing something odd like
passing a struct: the only effect would be that in an extremely small
number of cases gcc would make a regular call when it could make a
sibling call.

> Introduce a new backend hook
>    bool targetm.function_ok_for_sibcall_with_cum (tree, tree,
> CUMULATIVE_ARGS*);
> and call it with &args_so_far from calls.c:expand_call

It would be OK to change the existing hook to add a CUMULATIVE_ARGS*
parameter, but unfortunately you don't have the CUMULATIVE_ARGS at the
point where it is called.  Adding another one does seem pretty ugly.

Ian

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Problems with sibling calls
  2009-05-29 16:26 ` Ian Lance Taylor
@ 2009-05-29 16:38   ` Georg-Johann Lay
  2009-05-29 16:59     ` Dave Korn
  0 siblings, 1 reply; 9+ messages in thread
From: Georg-Johann Lay @ 2009-05-29 16:38 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: gcc

Ian Lance Taylor schrieb:
> Georg-Johann Lay <avr@gjlay.de> writes:
> 
>> The trouble is this: If a callee gets some arguments passed on the
>> stack or in call-saved regs, the callee is not ok for a sibling
>> call. That's because sibcall_epilogue executes before sibcall insns.
> 
> I'm having trouble with your terminology "call-saved regs".  Do that
> mean "caller-saved regs" or "callee-saved regs"?

They are callee-saved in that case.

> I gather that in the case where f wants to make a sibling call to g, the
> problem is that this fails if g accepts arguments anywhere other than in
> registers which are neither caller-saved nor callee-saved.  I would
> expect that that would be fairly easy to determine from the call
> expression.  You can be conservative when doing something odd like
> passing a struct: the only effect would be that in an extremely small
> number of cases gcc would make a regular call when it could make a
> sibling call.

Yes that's right. It would work if I recreate the information which code 
a couple of lines away did already, I just wanted to avoid doubling 
(some parts of) the code/work in order to keep the backend clean. 
Moreover, calls.c is far from being short and straight forward, and 
obviously many different cases must be handled. Many cases will 
disappear because the implementation is for a specific machine, though.

>> Introduce a new backend hook
>>    bool targetm.function_ok_for_sibcall_with_cum (tree, tree,
>> CUMULATIVE_ARGS*);
>> and call it with &args_so_far from calls.c:expand_call
> 
> It would be OK to change the existing hook to add a CUMULATIVE_ARGS*
> parameter, but unfortunately you don't have the CUMULATIVE_ARGS at the
> point where it is called.  Adding another one does seem pretty ugly.

Yes, having two hooks that do almost the same is odd. The original 
TARGET_FUNCTION_OK_FOR_SIBCALL could always return true and the new one 
would be the worker instead. But that's definitely ugly. And the two 
hooks would need different default implementations (one returning false 
and the other true).

I am working with 4.3.3, and there args_fo_far is available when the 
hook gets called. The final call to FUNCTION_ARG with mode=VOIDmode will 
follow after the hook, which seems reasonable to me.

Georg-Johann

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Problems with sibling calls
  2009-05-29 16:14 ` Dave Korn
@ 2009-05-29 16:56   ` Georg-Johann Lay
  2009-05-29 16:57     ` Dave Korn
  0 siblings, 1 reply; 9+ messages in thread
From: Georg-Johann Lay @ 2009-05-29 16:56 UTC (permalink / raw)
  To: Dave Korn; +Cc: gcc

Dave Korn schrieb:
> Georg-Johann Lay wrote:
> 
>> The trouble is this: If a callee gets some arguments passed on the stack
>> or in call-saved regs, the callee is not ok for a sibling call. That's
>> because sibcall_epilogue executes before sibcall insns.
>>
>> All this information is pretty easy available in FUNCTION_ARGS resp.
>> FUNCTION_ARG_ADVANCE and can be stored in CUMULATIVE_ARGS.
>>
>> However, the place where the information is needed is in
>> targetm.function_ok_for_sibcall (aka. TARGET_FUNCTION_OK_FOR_SIBCALL),
>> and that hook only gets the function decl and call expression trees, but
>> these trees do not contain information about where the calle's arguments
>> get passed.
>>
>> How can that be fixed? Most probably, I am missing something, and the
>> information is hidden somewhere is the trees passed to
>> targetm.function_ok_for_sibcall?
> 
>> So what am I missing here? Is there some other approach to solve this?
> 
>   The standard answer is that frame layout and other per-function info is
> stored in the "struct function" machine-dependent part of the global 'cfun'
> current function struct.

Yep, thanks much! That's the right place to store the information and 
will solve the local function problem.

But this will only (or is intended to) track information for the caller, 
not information needed for the callee that was gathered in the mentioned 
hooks. It can be used, of course, to exchange data between hooks 
provided with CUMULATIVE_ARGS and hooks that aren't, but it would still 
make implications on how the hooks get called in calls.c:expand_call().

Georg-Johann

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Problems with sibling calls
  2009-05-29 16:56   ` Georg-Johann Lay
@ 2009-05-29 16:57     ` Dave Korn
  0 siblings, 0 replies; 9+ messages in thread
From: Dave Korn @ 2009-05-29 16:57 UTC (permalink / raw)
  To: Georg-Johann Lay; +Cc: Dave Korn, gcc

Georg-Johann Lay wrote:

> But this will only (or is intended to) track information for the caller,
> not information needed for the callee that was gathered in the mentioned
> hooks. It can be used, of course, to exchange data between hooks
> provided with CUMULATIVE_ARGS and hooks that aren't, but it would still
> make implications on how the hooks get called in calls.c:expand_call().

  You decide whether to allow sibcalls on a per-caller basis generally.  All
the information needed to know how the arguments will be passed is available
at the call site, and your backend knows how arguments are passed, so it can
decide then whether the callee is also suitable or not.  It shouldn't be a
significant overhead even if you have to evaluate the suitability of the same
callee multiple times in independent callers.

    cheers,
      DaveK

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Problems with sibling calls
  2009-05-29 16:38   ` Georg-Johann Lay
@ 2009-05-29 16:59     ` Dave Korn
  0 siblings, 0 replies; 9+ messages in thread
From: Dave Korn @ 2009-05-29 16:59 UTC (permalink / raw)
  To: Georg-Johann Lay; +Cc: Ian Lance Taylor, gcc

Georg-Johann Lay wrote:

> Yes that's right. It would work if I recreate the information which code
> a couple of lines away did already, I just wanted to avoid doubling
> (some parts of) the code/work in order to keep the backend clean.

  Well, then don't!  Factor out the common parts of your stack layout and arg
passing into subroutines that can be called from multiple places in your backend.

> Moreover, calls.c is far from being short and straight forward, and
> obviously many different cases must be handled. Many cases will
> disappear because the implementation is for a specific machine, though.

  You shouldn't need to be doing anything to calls.c itself, unless I've
missed something seriously complicated here.

    cheers,
      DaveK

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Problems with sibling calls
  2009-05-29 14:16 Problems with sibling calls Georg-Johann Lay
  2009-05-29 16:14 ` Dave Korn
  2009-05-29 16:26 ` Ian Lance Taylor
@ 2009-05-30 18:26 ` Ulrich Weigand
  2009-06-01 14:03   ` Georg-Johann Lay
  2 siblings, 1 reply; 9+ messages in thread
From: Ulrich Weigand @ 2009-05-30 18:26 UTC (permalink / raw)
  To: Georg-Johann Lay; +Cc: gcc

Georg-Johann Lay wrote:

> I'd like to support sibling calls for a target where function args can 
> be passed in call-saved registers, namely AVR.

The s390 back-end already has the very same issue.  You may want to have
a look at config/s390/s390.c:s390_call_saved_register_used and how it is
used by s390_function_ok_for_sibcall.

Bye,
Ulrich

-- 
  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE
  Ulrich.Weigand@de.ibm.com

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Problems with sibling calls
  2009-05-30 18:26 ` Ulrich Weigand
@ 2009-06-01 14:03   ` Georg-Johann Lay
  0 siblings, 0 replies; 9+ messages in thread
From: Georg-Johann Lay @ 2009-06-01 14:03 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: gcc

Ulrich Weigand schrieb:
> Georg-Johann Lay wrote:
>>I'd like to support sibling calls for a target where function args can 
>>be passed in call-saved registers, namely AVR.
> The s390 back-end already has the very same issue.  You may want to have
> a look at config/s390/s390.c:s390_call_saved_register_used and how it is
> used by s390_function_ok_for_sibcall.

Hi Ulrich,

thank's much for this hint. It's the missing link I was after.

Georg-Johann

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2009-06-01 14:03 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-05-29 14:16 Problems with sibling calls Georg-Johann Lay
2009-05-29 16:14 ` Dave Korn
2009-05-29 16:56   ` Georg-Johann Lay
2009-05-29 16:57     ` Dave Korn
2009-05-29 16:26 ` Ian Lance Taylor
2009-05-29 16:38   ` Georg-Johann Lay
2009-05-29 16:59     ` Dave Korn
2009-05-30 18:26 ` Ulrich Weigand
2009-06-01 14:03   ` Georg-Johann Lay

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).