This is the mail archive of the
mailing list for the GCC project.
Problems with sibling calls
- From: Georg-Johann Lay <avr at gjlay dot de>
- To: gcc at gcc dot gnu dot org
- Date: Fri, 29 May 2009 12:21:17 +0200
- Subject: Problems with sibling calls
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
How can that be fixed? Most probably, I am missing something, and the
information is hidden somewhere is the trees passed to
All of the following fixed I considered are not nice:
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.
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.
Introduce a new backend hook
bool targetm.function_ok_for_sibcall_with_cum (tree, tree,
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, ...).