Ian Lance Taylor schrieb:
Georg-Johann Lay <a...@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