<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Wed, Sep 16, 2015 at 8:05 AM, Aaron Ballman <span dir="ltr"><<a href="mailto:aaron.ballman@gmail.com" target="_blank">aaron.ballman@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><span>On Wed, Sep 16, 2015 at 12:47 AM, Akira Hatanaka <<a href="mailto:ahatanak@gmail.com" target="_blank">ahatanak@gmail.com</a>> wrote:<br>
> ahatanak added inline comments.<br>
><br>
> ================<br>
> Comment at: include/clang/Basic/Attr.td:894<br>
> @@ -893,1 +893,3 @@<br>
><br>
> +def DisableTailCalls : InheritableAttr {<br>
> +  let Spellings = [GNU<"disable_tail_calls">,<br>
> ----------------<br>
> aaron.ballman wrote:<br>
>> Pardon me if this is obvious, but -- are there times when you would want to disable tail calls but leave other optimizations in place? I'm trying to understand why these attributes are orthogonal.<br>
> Yes, that's correct. The new function attribute we are adding shouldn't disable other optimizations that are normally run at -O2 or -O3.<br>
<br>
</span>Okay -- with this and your other explanations, I now understand why<br>
this attribute is orthogonal to optnone. Thanks!<br>
<span><br>
> ================<br>
> Comment at: include/clang/Basic/Attr.td:896<br>
> @@ +895,3 @@<br>
> +  let Spellings = [GNU<"disable_tail_calls">,<br>
> +                   CXX11<"clang", "disable_tail_calls">];<br>
> +  let Subjects = SubjectList<[Function, ObjCMethod]>;<br>
> ----------------<br>
> aaron.ballman wrote:<br>
>> Should this attribute be plural? Are there multiple tail calls within a single method that can be optimized away?<br>
> I named it after the existing IR function attribute and I'm guessing the plural name was chosen because functions can have multiple tail call sites. I think the singular name is better if we want this attribute to mean "disable tail call optimization".<br>
<br>
</span>I'm holding off on having an opinion on the name until I have an idea<br>
as to the other planned attribute's name, but I basically think the<br>
plural is reasonable if the purpose is to disable TCO on the functions<br>
called within the marked function. But we may want to consider making<br>
the name more obvious. The majority of the attributes we support<br>
appertain to the behavior of the declaration itself, not to entities<br>
*within* the declaration. However, it seems like no_sanitize,<br>
no_sanitize_thread, et al are similar concepts. Perhaps we want this<br>
to be named "no_tail_calls" instead? Just something to think about.<br>
<span><br></span></blockquote><div><br></div><div>I think something similar to no_sanitize makes sense.</div><div><br></div><div>The tentative names I had were notailcall for this attribute and notail for the other, but I'm open to suggestions if there are better names.</div><div><br></div><div>I'll send a patch to support the other attribute today.</div><div><br><span>
> ================<br>
> Comment at: include/clang/Basic/AttrDocs.td:1619<br>
> @@ +1618,3 @@<br>
> +  let Content = [{<br>
> +Use ``__attribute__((disable_tail_calls)))`` to instruct the backend not to do tail call optimization.<br>
> +  }];<br>
> ----------------<br>
> aaron.ballman wrote:<br>
>> I would avoid using the exact syntax here because this is a GNU and C++ attribute. Could just say:<br>
>><br>
>> The ``disable_tail_calls`` attribute instructs the backend to not perform tail call optimization.<br>
> OK, done.<br>
><br>
> ================<br>
> Comment at: lib/Sema/SemaDeclAttr.cpp:4882<br>
> @@ +4881,3 @@<br>
> +  case AttributeList::AT_DisableTailCalls:<br>
> +    handleSimpleAttribute<DisableTailCallsAttr>(S, D, Attr);<br>
> +    break;<br>
> ----------------<br>
> aaron.ballman wrote:<br>
>> Okay, that makes sense. I can contrive examples of noreturn where TCO could happen, it just took me a while to think of them. ;-)<br>
>><br>
>> What about other semantic checks, like warning the user about disabling TCO when TCO could never be enabled in the first place? Can you disable TCO for functions that are marked __attribute__((naked))? What about returns_twice?<br>
>><br>
>> Unfortunately, we have a lot of attributes for which we've yet to write documentation, so you may need to look through Attr.td.<br>
> Since "naked" allows only inline assembly statements, it should be an error to have disable-tail-calls and naked on the same function. I made changes in Sema to detect that case.<br>
<br>
</span>__declspec(naked) behaves differently than __attribute__((naked)), but<br>
I'm not certain whether that changes the reasoning<br>
(<a href="https://msdn.microsoft.com/en-us/library/h5w10wxs.aspx" rel="noreferrer" target="_blank">https://msdn.microsoft.com/en-us/library/h5w10wxs.aspx</a>).<br></div><div><br></div><div>gcc seems to take a stricter stance on what is allowed inside naked functions, but I think it's still safe to say it's a mistake to attach disable-tail-calls to a naked function (because you have no control over it), regardless of whether it's an msvc or gcc attribute.</div><div><br></div><div><a href="https://gcc.gnu.org/onlinedocs/gcc/ARM-Function-Attributes.html#ARM-Function-Attributes">https://gcc.gnu.org/onlinedocs/gcc/ARM-Function-Attributes.html#ARM-Function-Attributes</a><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><span>
> My understanding is that you can't do tail call optimization on call sites of a function that calls a "return_twice" function. However, attaching "return_twice" on the calling function doesn't block tail call optimizations on the call sites inside the function.<br>
<br>
</span>That makes sense to me.<br>
<span><br>
> I didn't find any other attributes that seemed incompatible with disable-tail-calls.<br>
<br>
</span>If a user finds something, we can handle it at that time. Thank you<br>
for looking into this!<br>
<span><br>
> Index: include/clang/Basic/AttrDocs.td<br>
> ===================================================================<br>
> --- include/clang/Basic/AttrDocs.td<br>
> +++ include/clang/Basic/AttrDocs.td<br>
> @@ -1612,3 +1612,10 @@<br>
>  arguments, with arbitrary offsets.<br>
>    }];<br>
>  }<br>
> +<br>
> +def DisableTailCallsDocs : Documentation {<br>
> +  let Category = DocCatFunction;<br>
> +  let Content = [{<br>
</span>> +The ``disable_tail_calls`` attribute instructs the backend to not perform tail call optimization.<br>
<br>
The documentation should be updated to clarify the semantics of the<br>
attribute. Right now it's ambiguous as to which TCOs are disabled.<br>
<br>
> +  }];<br>
> +}<br>
<span>> Index: lib/Sema/SemaDeclAttr.cpp<br>
> ===================================================================<br>
> --- lib/Sema/SemaDeclAttr.cpp<br>
> +++ lib/Sema/SemaDeclAttr.cpp<br>
</span>> @@ -1696,6 +1696,18 @@<br>
>                                     Attr.getAttributeSpellingListIndex()));<br>
>  }<br>
><br>
> +static void handleDisableTailCallsAttr(Sema &S, Decl *D,<br>
> +                                       const AttributeList &Attr) {<br>
> +  if (auto *A = D->getAttr<NakedAttr>()) {<br>
> +    S.Diag(Attr.getLoc(), diag::err_attributes_are_not_compatible)<br>
> +        << Attr.getName() << A;<br>
> +    return;<br>
> +  }<br>
<br>
Please use checkAttrMutualExclusion() instead.<br>
<span><font color="#888888"><br>
~Aaron<br>
</font></span></blockquote></div><br></div></div>