[Patch][AVR]: Support tail calls

Georg-Johann Lay avr@gjlay.de
Wed Mar 16 10:33:00 GMT 2011


Richard Henderson schrieb:
> On 03/11/2011 05:43 AM, Georg-Johann Lay wrote:
>> I did not find a way to make this work together with -mcall-prologues.
>> Please let me know if you have suggestion on how call prologues can be
>> combine with tail calls.
> 
> You need a new symbol in libgcc for this.  It should be easy enough to have
> the sibcall epilogue load up Z+EIND before jumping to the new symbol
> (perhaps called __sibcall_restores__).  This new symbol would be just like
> the existing __epilogue_restores__ except that it would finish with an
> eijmp/ijmp instruction (depending on multilib) instead of a ret instruction.

The point is that the intent of -mprologue-saves is to save program
memory space (flash). If we load the callee's address in the epilogue,
the epilogue's size will increase. Moreover, adding an other lengthy
function besides __epilogue_restores__ to libgcc, that will increase
code size because in many cases we will see both epilogue flavors
being dragged into application.

Note that, in comparison with non-tailcall, a tailcall without
prologue-saves saves one instruction, i.e. the ret. This is no more
true in presence of prologue-saves, i.e. even with tail-calling the
code would be neither faster nor smaller. (It might still save some
stack space, though)

>> The implementation uses struct machine_function to pass information
>> around, i.e. from avr_function_arg_advance to avr_function_ok_for_sibcall.
> 
> Look at how the s390 port handles this exact problem.
> 
>   /* Register 6 on s390 is available as an argument register but unfortunately
>      "caller saved". This makes functions needing this register for arguments
>      not suitable for sibcalls.  */
>   return !s390_call_saved_register_used (exp);
> 
> I'll admit that it would be helpful if the cumulative_args pointer was passed
> into the ok_for_sibcall hook, but it's not *that* hard to recreate that value
> by hand.  This is what the s390_call_saved_register_used function does.

See also discussion in

http://gcc.gnu.org/ml/gcc/2011-03/msg00048.html

I must admit that I did not try to copy-paste all code in calls.c that
deals with preparation of arguments and mapping trees to rtx and see
how it deflates when applying all the #if and #ifdef and avr backend
implications...

Maybe we see Joern's work being committed soon so that on top of this
a patch adding cumulative args to function_of_for_sibcall will be
approved.

Presumably, even s390 backend guys would prefer reusing information
instead of recomputing them.

> 
>> +      || (avr_OS_task_function_p (decl_callee) ^ avr_OS_task_function_p (current_function_decl))
> 
> Please just use != instead of ^ here.  Also, needs line wrapping.

Done in the patch attached.

In the cases of OS_task resp.OS_main, I think I am a bit
over-conservative when rejecting tail-calls. This is basically because
there is *no* documentation of these attributes. Presumably they
implement "naked+ret" so that tail-calling from OS_task resp. OS_main
should be ok?

> I do like very much how you've cleaned up the call patterns.  IMO this should
> be committed as a separate patch; I'll let the AVR maintainers approve it though.

If anyone desires an explicit, intermediate step I will provide
according patch, of course.

New patch attached. Changes with respect to original patch:
- use != instead of ^ to ensure caller/callee epilogue compatibility
  for functions attributed OS_task resp OS_main
- add some more comment to md

Johann

2011-03-16  Georg-Johann Lay  <avr@gjlay.de>

	* config/avr/avr-protos.h (expand_epilogue): Change prototype
	* config/avr/avr.h (struct machine_function): Add field
	sibcall_fails.
	* config/avr/avr.c (init_cumulative_args,
	avr_function_arg_advance): Use it.
	* config/avr/avr.c (expand_epilogue): Add bool parameter. Handle
	sibcall	epilogues.
	(TARGET_FUNCTION_OK_FOR_SIBCALL): Define to...
	(avr_function_ok_for_sibcall): ...this new function.
	(avr_lookup_function_attribute1): New static Function.
	(avr_naked_function_p, interrupt_function_p,
	signal_function_p, avr_OS_task_function_p,
	avr_OS_main_function_p): Use it.
	* config/avr/avr.md ("sibcall", "sibcall_value",
	"sibcall_epilogue"): New expander.
	("*call_insn", "*call_value_insn"): New insn.
	("call_insn", "call_value_insn"): Remove
	("call", "call_value", "epilogue"): Change expander to handle
	sibling calls.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: sibcall-v3.diff
Type: text/x-patch
Size: 15009 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20110316/aff850ac/attachment.bin>


More information about the Gcc-patches mailing list