[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