[PATCH] D12923: Add support for function attribute "notail"
Philip Reames via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 24 16:34:17 PDT 2015
On 09/24/2015 03:04 PM, Akira Hatanaka wrote:
> On Thu, Sep 24, 2015 at 1:53 PM, Philip Reames
> <listmail at philipreames.com <mailto:listmail at philipreames.com>> wrote:
>
>
>
> On 09/24/2015 01:47 PM, Akira Hatanaka wrote:
>> On Wed, Sep 23, 2015 at 11:13 AM, Philip Reames
>> <listmail at philipreames.com <mailto:listmail at philipreames.com>> wrote:
>>
>>
>>
>> On 09/23/2015 08:48 AM, Akira Hatanaka wrote:
>>> On Tue, Sep 22, 2015 at 8:31 AM, Philip Reames
>>> <listmail at philipreames.com
>>> <mailto:listmail at philipreames.com>> wrote:
>>>
>>> To be clear, this is a debuging aid only? It's not
>>> something required for correctness? I'm somewhat
>>> bothered by that because it seems like it would be a
>>> useful implementation tool for higher level languages.
>>>
>>>
>>> It's not purely a debugging aid that helps when you are
>>> using the debugger. There are projects (that are not
>>> debuggers) that rely on not missing frames to produce
>>> results that are useful.
>> If it's not simply best effort, that constrains our choices.
>>>
>>> A couple of thoughts in no particular order:
>>> 1) Can we always annotate the call site rather than the
>>> function? That removes the unpredictability due to
>>> optimization.
>>>
>>>
>>> Annotating the call site should be fine. For the use cases
>>> that we care about, it probably isn't important to prevent
>>> tail calls on indirect calls.
>> Given this, I would lean towards a notail value being added
>> as an alternative to "tail" and "musttail". This seems to fit
>> the existing uses, doesn't have any obvious loop holes or
>> best effort semantics, and solves the problem at hand.
>>>
>>> 2) Calling it something like "no-direct-tail-call" or
>>> "prefer-no-tail" would remove some of the confusion
>>> value. When I see "notail", I expect that to always be
>>> respected; the best effort semantics come as a bit of a
>>> surprise.
>>>
>>>
>>> I agree. A name that indicates it's only a best effort
>>> option or it's an option that affects only direct calls
>>> would be good.
>> (This only applies if we're talking about a function
>> annotation. The call site annotation applies to both direct
>> and indirect calls.)
>>>
>>>
>>> 3) This seems analogous to the "tail" marker in that it
>>> indicates a preference/option. Whatever we end up with,
>>> it needs to be a verifier option to have a "tail" or
>>> "musttail" call site which is also "notail". It also
>>> needs to be an error to have a mustail callsite to a
>>> notail function (if such ends up existing.)
>>>
>>>
>>> If we are going to annotate the function, I think we should
>>> have the verifier catch incompatibilities between the
>>> markers on the call sites and the function attribute on the
>>> called functions.
>>>
>>> If we are annotating the call site, the verifier check isn't
>>> needed since the tail-call related markers are enums that
>>> are mutually exclusive.
>> Yep.
>>>
>>> 4) It somewhat feels like there are two concepts being
>>> intermixed here. 1) A call site which will never be a
>>> tail call. 2) A function which we prefer not to tail
>>> call to. Does it make sense to separate them?
>>>
>>>
>>> Yes, it makes sense to separate them. For the use case we
>>> care about, either 1) or 2) will do. We don't have to have
>>> support for both.
>> I would lean toward doing (1) for now. We can come back and
>> implement (2) at a later time if we find it's needed. After
>> (1), each call site will have four states:
>> - "notail" - Can not be a tail call.
>> - "" - May be a tail call if analysis finds it legal,
>> profitable, and desirable*
>> - "tail" - May be a tail call, profitability hinted
>> - "musttail" - Must be a tail call.
>>
>> * (2) would basically just change the desirability of moving
>> from "" to "tail".
>>
>>
>> OK. I'm considering changing the direction of this patch and
>> marking the call site instead of the called function.
>>
>> We should also discuss what kinds of source level attributes
>> we'll need. My plan is to attach an attribute that indicates
>> notail (something like no_direct_tail) to the called function
>> declaration and definition and then mark all the direct call
>> sites in the IR that call the function as notaill. In addition to
>> that, it seems like we want to have a way to attach the attribute
>> directly to the call site:
>>
>> void (*indirectCall)(int, int, int);
>>
>> void foo1(int a, int b) {
>> (*indirectCall)(a, b, c) __attribute__((notail));
>> }
> I think you're going to want to have the same dichotomy between
> (1) and (2) at the source level as in the IR. The same issues
> apply in both cases.
>
>
> I think you were suggesting we always annotate the call site rather
> than the function. Are you suggesting we do the same thing at the
> source level, i.e. allow marking the call site but not the function? I
> have to confirm, but I believe the people who requested this feature
> wanted to use a function attribute rather than marking each call site
> that calls the target function.
What I'm suggesting is that the function attribute should be a best
effort semantic. If we can tell something is a direct call, we should
avoid the tail call, but we don't guarantee to never emit a tail call to
the function in question. If you need an absolutely guarantee that a
particular call (even if indirect) will not be a tail call, you'd need
to mark the call site.
(In practice, the "prefer_no_tail" function attribute will probably work
pretty reliability, but I'm concerned about "promising" that it will
work. Doing so for a subset of calls (i.e. "statically direct calls")
and may work for others is somewhat defensible, but I've learned not to
make promises the optimizer has a hard time keeping. Does the
distinction make sense?)
>
>>>
>>> Philip
>>>
>>>
>>> On 09/21/2015 06:22 PM, Akira Hatanaka wrote:
>>>> Several users have been asking for this function
>>>> attribute to prevent losing the calling functions's
>>>> information in the backtrace. If we attach the
>>>> attribute to a function, ideally we would want to
>>>> prevent tail call optimization on all call sites that
>>>> call the function. However, the compiler cannot always
>>>> tell which function is called from a call site if it's
>>>> an indirect call, so it's fine if an indirect call to
>>>> the marked function ends up being tail-call optimized.
>>>> For direct calls, we want the function attribute to
>>>> prevent tail call 100% of the time.
>>>>
>>>> We can also use a "notail" marker on the call
>>>> instruction instead of using a function attribute. The
>>>> only downside of using a marker is that we probably
>>>> will never be able to prevent tail call optimization on
>>>> indirect calls even when the compiler can turn it into
>>>> a direct call (for example, via inlining). I'm not sure
>>>> at the moment how important this is.
>>>>
>>>> On Thu, Sep 17, 2015 at 9:47 AM, Philip Reames via
>>>> llvm-commits <llvm-commits at lists.llvm.org
>>>> <mailto:llvm-commits at lists.llvm.org>> wrote:
>>>>
>>>> +llvm-dev
>>>>
>>>> Can you give a bit of background on what you're
>>>> trying to address here? After reading through the
>>>> discussion and seeing that this is a best effort
>>>> flag, I'm not sure that a function attribute is the
>>>> best way to describe this. I'm open to being
>>>> convinced it is, but I'd like to hear a bit more
>>>> about the use case and get broader visibility on
>>>> the proposal first.
>>>>
>>>> Philip
>>>>
>>>>
>>>> On 09/16/2015 07:27 PM, Akira Hatanaka via
>>>> llvm-commits wrote:
>>>>> ahatanak created this revision.
>>>>> ahatanak added a subscriber: llvm-commits.
>>>>>
>>>>> This patch adds support for a new IR function attribute "notail". The attribute is used to disable tail call optimization on calls to functions marked with the attribute.
>>>>>
>>>>> This attribute is different from the existing attribute "disable-tail-calls", which disables tail call optimizations on all call sites within the marked function.
>>>>>
>>>>> The patch to add support for the corresponding source-level function attribute is here:
>>>>> http://reviews.llvm.org/D12922
>>>>>
>>>>> http://reviews.llvm.org/D12923
>>>>>
>>>>> Files:
>>>>> docs/LangRef.rst
>>>>> include/llvm/Bitcode/LLVMBitCodes.h
>>>>> include/llvm/IR/Attributes.h
>>>>> include/llvm/IR/Instructions.h
>>>>> lib/AsmParser/LLLexer.cpp
>>>>> lib/AsmParser/LLParser.cpp
>>>>> lib/AsmParser/LLToken.h
>>>>> lib/Bitcode/Reader/BitcodeReader.cpp
>>>>> lib/Bitcode/Writer/BitcodeWriter.cpp
>>>>> lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
>>>>> lib/IR/Attributes.cpp
>>>>> lib/IR/Verifier.cpp
>>>>> lib/Transforms/Scalar/TailRecursionElimination.cpp
>>>>> test/Bindings/llvm-c/Inputs/invalid.ll.bc
>>>>> test/Bindings/llvm-c/invalid-bitcode.test
>>>>> test/Bitcode/attributes.ll
>>>>> test/Bitcode/invalid.ll
>>>>> test/Bitcode/invalid.ll.bc
>>>>> test/CodeGen/X86/attr-notail.ll
>>>>> test/Transforms/TailCallElim/notail.ll
>>>>>
>>>>>
>>>>>
>>>>> _______________________________________________
>>>>> llvm-commits mailing list
>>>>> llvm-commits at lists.llvm.org
>>>>> <mailto:llvm-commits at lists.llvm.org>
>>>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>>>>
>>>>
>>>> _______________________________________________
>>>> llvm-commits mailing list
>>>> llvm-commits at lists.llvm.org
>>>> <mailto:llvm-commits at lists.llvm.org>
>>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>>>>
>>>>
>>>
>>>
>>
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150924/e3eea620/attachment.html>
More information about the llvm-commits
mailing list