This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: forcing tail/sibling call optimization


On Thu, Jan 04, 2001 at 09:58:31AM +1100, Fergus Henderson wrote:
> Just the former, in general.  The front-end author can't guess at what
> machine-specific or implementation-specific reasons there might be for
> not doing a tail call.  All the front-end can do is to let the
> back-end know that the locals are not live at this call,
> and (perhaps) that the call is in a tail position.
> So in general it can only be a hint.

Mostly what I meant here is "Does CALL_EXPR_TAILCALL imply tail-ness"?
I.e. can you only get it in constructs like "return foo()" and semantic
equivalences thereof.

> Good point.  How about I rename it as "CALL_EXPR_USE_TAILCALL"?
> That seems more neutral.

Sure.  Or just CALL_EXPR_TAILCALL.

> I suppose we could have two different flags, one for the hint, and one
> for the requirement.  But those tree flag bits seem to be in fairly
> short supply.  Is it worth using two flags?

Maybe.  Mark Mitchell has always wanted us to do that optimization
at the tree level instead of after the fact in rtl.  Doing that would
mean verifying tail-ness, validating argument safety, and setting the 
hint bit.  If the target rejects the tail call conversion, no harm
done.  Alternately, if the front end didn't really care if the tail
call didn't happen, it could query the target before setting the bit.

Let's just go with the one bit for now and make it mean "require".

> But I see now that we already check all those reasons in expand_call(),
> and optimize_sibling_and_tail_recursive_call is just checking the
> tail-ness of the call and the liveness of the locals.

Yep.  Most of the target-specific reasons why conversion might not
be possible depends on the types involved, so we have to perform
that check before we throw the types away.

> If the call to foo is not a tail call, then it's OK to
> inline it and make the calls to bar1, bar2, etc. ordinary
> calls rather than tail calls.  That can only increase
> stack usage by a constant factor, I think.

True, but I'm thinking of implementation correctness here.

If we emit a tail call sequence into the rtl directly, then
that is _going_ to be a tail call now and forevermore.  Thus
we can't perform rtl inlining with that sequence installed.

So we either have to annotate CALL_PLACEHOLDER as you did,
or prevent rtl inlining on functions that have had tail calls
expanded already.

Long term we want to get rid of rtl inlining entirely and
perform this operation at the tree level.  This already 
happens in the C++ front end, but hasn't been made general.

So short-term I'd rather just disable rtl inlining if we
expand a CALL_EXPR with CALL_EXPR_TAILCALL set.



r~

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]