[llvm-dev] [PATCH] D12923: Add support for function attribute "notail"

Akira Hatanaka via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 29 11:38:59 PDT 2015


On Tue, Sep 29, 2015 at 10:49 AM, Philip Reames <listmail at philipreames.com>
wrote:

>
>
> On 09/28/2015 10:38 PM, Sanjoy Das wrote:
>
>>
>> > That was what I had in mind: the function attribute blocks tail call
>> for statically direct calls but doesn't promise
>> > anything (in fact, does nothing) for indirect calls.
>> >
>> > Do you think we shouldn't make any promises for statically direct calls
>> either? I don't see why it's hard to keep the
>> > promise that direct tail calls will be blocked. Do you have a
>> particular optimization in mind that would be difficult or
>> > impossible to implement if we promised to block direct calls?
>>
>> I think in this scheme we'll have problems around devirtualization.
>> For instance, you could start with a indirect call to a notail target
>> that would get TCO'ed (as an indirect call), after which
>> devirtualization or load/store motion would turn the indirect call
>> into a direct call; and you'd end up with a direct tail call to a
>> notail target.
>>
> Sanjoy hits on some of the same concerns I had with this.  In particular,
> there's a distinction between what the language specification defines as a
> direct call and what the optimizer/compiler might turn into a direct call.
> At the source layer, we can *only* make guarantees about the former.  Any
> specification we write has to account for the fact the later are an
> implementation detail entirely under the control of the compiler. i.e.
> optimizations can not break the semantics.  You have to ensure this when
> defining the semantics.


By "statically direct calls", I meant the set of calls that can be
determined to be direct at the source level, which is normally a subset of
the calls that end up being direct calls after all the optimization passes
are run. I agree that we can probably promise or guarantee that tail call
will be blocked for direct calls at the source level. We don't guarantee
anything for indirect calls at the source level.


>
>
>> I don't know what your requirements are, but if I were you I'd design
>> the `notail` marker to be logically part of a function's calling
>> convention.  That way functions marked `notail` get to do things that
>> are legal only if the call to them wasn't a tail call, because all
>> well-defined calls constrain the caller to match callee's expectation
>> with respect to tail calls.  In the CFE, you could make the `notail`
>> attribute have the same restrictions / conventions as things like
>> `fastcall`.
>>
> I disagree with this slightly.  As I've stated previously, I think there
> are two distinct semantics here: a) this call must be a notail call, and b)
> we'd "like" this to be a no tail, but it's optional. We need to not mix
> them.
>
>>
>>
The semantics of the tail call marker I'm looking for is close to b), but
differs in whether we say it's optional or we guarantee that we block tail
call for a certain subset of calls (direct calls at the source level). I'm
inclined to have the tail call marker mean "notail is guaranteed if the
call is direct at the source level", but I wonder if it'll come back to
bite us.

Also, this tail call marker won't be used to enable optimizations on the
marked function that would be available only if it were known the call to
the function isn't TCO'ed. That might be an interesting idea to other
people, but it's not something that is needed for our use case.


> -- Sanjoy
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150929/5772b4b3/attachment.html>


More information about the llvm-commits mailing list