As implemented before r202131, all the code that checked for AlwaysInline also checked for ForceInline and treated it identically.<div><br></div><div>This commit, r202131, does nothing to change the semantics of how clang feels about ForceInline. It is just as correct or wrong as it was before.</div>
<div><br></div><div>Quite frankly, many of the limitations that __forceinline is documented to have are ridiculous, it seems like their implementation is incredibly dependent on the frontend being able to do some analysis.</div>
<div><br></div><div>For example, they mention that they won't inline if the function has a variable argument list. That just seems like a bug, I don't see why we would need to mimic that behavior.</div><div><br></div>
<div>MSVC has /Ob0, which we bind to -fno-inline. I don't think we have this on by default, they do. The two flags don't have quite the same semantics. I think if there is something to fix, it should be done by fixing /Ob0.</div>
<div><br></div><div>-- </div><div>David Majnemer<br><div><br><div>On Tue Feb 25 2014 at 5:24:05 AM, Aaron Ballman <<a href="mailto:aaron@aaronballman.com">aaron@aaronballman.com</a>> wrote:</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
I don't believe the semantics for __forceinline and always_inline<br>
really match up. As best I can tell, always_inline will *always*<br>
inline the function, regardless of optimization level, which is not<br>
something that __forceinline does. As a simple example:<br>
<br>
__forceinline int i() { return 9; }<br>
<br>
int main(void) {<br>
int j = i();<br>
return 0;<br>
}<br>
<br>
In debug mode in MSVC 2013, this produces (in part):<br>
<br>
; 3 : int main(void) {<br>
<br>
push ebp<br>
mov ebp, esp<br>
sub esp, 204 ; 000000ccH<br>
push ebx<br>
push esi<br>
push edi<br>
lea edi, DWORD PTR [ebp-204]<br>
mov ecx, 51 ; 00000033H<br>
mov eax, -858993460 ; ccccccccH<br>
rep stosd<br>
<br>
; 4 : int j = i();<br>
<br>
call ?i@@YAHXZ ; i<br>
mov DWORD PTR _j$[ebp], eax<br>
<br>
; 5 : return 0;<br>
<br>
xor eax, eax<br>
<br>
; 6 : }<br>
<br>
When I compile in GCC (using always_inline) at -O0, I get:<br>
<br>
main:<br>
push rbp<br>
mov rbp, rsp<br>
mov eax, 9<br>
mov DWORD PTR [rbp-4], eax<br>
mov eax, 0<br>
pop rbp<br>
ret<br>
<br>
Clang may not support __forceinline semantics properly yet, but I am<br>
not keen on this behavior change. It also deviates from the<br>
documentation for both (gcc claims "this attribute inlines the<br>
function even if no optimization level was specified." and msvc claims<br>
"You cannot force the compiler to inline a particular function, even<br>
with the __forceinline keyword.").<br>
<br>
~Aaron<br>
<br>
On Tue, Feb 25, 2014 at 4:53 AM, David Majnemer<br>
<<a href="mailto:david.majnemer@gmail.com" target="_blank">david.majnemer@gmail.com</a>> wrote:<br>
> Author: majnemer<br>
> Date: Tue Feb 25 03:53:29 2014<br>
> New Revision: 202131<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=202131&view=rev" target="_blank">http://llvm.org/viewvc/llvm-<u></u>project?rev=202131&view=rev</a><br>
> Log:<br>
> Attr: Remove ForceInline<br>
><br>
> The __forceinline keyword's semantics are now recast as AlwaysInline and<br>
> the kw___forceinline token has its language mode set for KEYMS.<br>
><br>
> This preserves the semantics of the previous implementation but with<br>
> less duplication of code.<br>
><br>
> Modified:<br>
> cfe/trunk/include/clang/Basic/<u></u>Attr.td<br>
> cfe/trunk/include/clang/Basic/<u></u>TokenKinds.def<br>
> cfe/trunk/lib/CodeGen/<u></u>CodeGenFunction.cpp<br>
> cfe/trunk/lib/CodeGen/<u></u>CodeGenModule.cpp<br>
> cfe/trunk/lib/Sema/<u></u>SemaDeclAttr.cpp<br>
><br>
> Modified: cfe/trunk/include/clang/Basic/<u></u>Attr.td<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=202131&r1=202130&r2=202131&view=diff" target="_blank">http://llvm.org/viewvc/llvm-<u></u>project/cfe/trunk/include/<u></u>clang/Basic/Attr.td?rev=<u></u>202131&r1=202130&r2=202131&<u></u>view=diff</a><br>
> ==============================<u></u>==============================<u></u>==================<br>
> --- cfe/trunk/include/clang/Basic/<u></u>Attr.td (original)<br>
> +++ cfe/trunk/include/clang/Basic/<u></u>Attr.td Tue Feb 25 03:53:29 2014<br>
> @@ -357,7 +357,7 @@ def AlignMac68k : InheritableAttr {<br>
> }<br>
><br>
> def AlwaysInline : InheritableAttr {<br>
> - let Spellings = [GCC<"always_inline">];<br>
> + let Spellings = [GCC<"always_inline">, Keyword<"__forceinline">];<br>
> let Subjects = SubjectList<[Function]>;<br>
> let Documentation = [Undocumented];<br>
> }<br>
> @@ -1676,12 +1676,6 @@ def DLLImport : InheritableAttr, TargetS<br>
> let Documentation = [Undocumented];<br>
> }<br>
><br>
> -def ForceInline : InheritableAttr {<br>
> - let Spellings = [Keyword<"__forceinline">];<br>
> - let LangOpts = [MicrosoftExt];<br>
> - let Documentation = [Undocumented];<br>
> -}<br>
> -<br>
> def SelectAny : InheritableAttr {<br>
> let Spellings = [Declspec<"selectany">];<br>
> let LangOpts = [MicrosoftExt];<br>
><br>
> Modified: cfe/trunk/include/clang/Basic/<u></u>TokenKinds.def<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/TokenKinds.def?rev=202131&r1=202130&r2=202131&view=diff" target="_blank">http://llvm.org/viewvc/llvm-<u></u>project/cfe/trunk/include/<u></u>clang/Basic/TokenKinds.def?<u></u>rev=202131&r1=202130&r2=<u></u>202131&view=diff</a><br>
> ==============================<u></u>==============================<u></u>==================<br>
> --- cfe/trunk/include/clang/Basic/<u></u>TokenKinds.def (original)<br>
> +++ cfe/trunk/include/clang/Basic/<u></u>TokenKinds.def Tue Feb 25 03:53:29 2014<br>
> @@ -455,7 +455,7 @@ KEYWORD(__cdecl , KE<br>
> KEYWORD(__stdcall , KEYALL)<br>
> KEYWORD(__fastcall , KEYALL)<br>
> KEYWORD(__thiscall , KEYALL)<br>
> -KEYWORD(__forceinline , KEYALL)<br>
> +KEYWORD(__forceinline , KEYMS)<br>
> KEYWORD(__unaligned , KEYMS)<br>
><br>
> // OpenCL address space qualifiers<br>
><br>
> Modified: cfe/trunk/lib/CodeGen/<u></u>CodeGenFunction.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=202131&r1=202130&r2=202131&view=diff" target="_blank">http://llvm.org/viewvc/llvm-<u></u>project/cfe/trunk/lib/CodeGen/<u></u>CodeGenFunction.cpp?rev=<u></u>202131&r1=202130&r2=202131&<u></u>view=diff</a><br>
> ==============================<u></u>==============================<u></u>==================<br>
> --- cfe/trunk/lib/CodeGen/<u></u>CodeGenFunction.cpp (original)<br>
> +++ cfe/trunk/lib/CodeGen/<u></u>CodeGenFunction.cpp Tue Feb 25 03:53:29 2014<br>
> @@ -527,8 +527,7 @@ void CodeGenFunction::<u></u>StartFunction(Glob<br>
> Fn->addFnAttr(llvm::Attribute:<u></u>:InlineHint);<br>
> break;<br>
> }<br>
> - } else if (!FD->hasAttr<<u></u>AlwaysInlineAttr>() &&<br>
> - !FD->hasAttr<ForceInlineAttr>(<u></u>))<br>
> + } else if (!FD->hasAttr<<u></u>AlwaysInlineAttr>())<br>
> Fn->addFnAttr(llvm::Attribute:<u></u>:NoInline);<br>
> }<br>
><br>
><br>
> Modified: cfe/trunk/lib/CodeGen/<u></u>CodeGenModule.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=202131&r1=202130&r2=202131&view=diff" target="_blank">http://llvm.org/viewvc/llvm-<u></u>project/cfe/trunk/lib/CodeGen/<u></u>CodeGenModule.cpp?rev=202131&<u></u>r1=202130&r2=202131&view=diff</a><br>
> ==============================<u></u>==============================<u></u>==================<br>
> --- cfe/trunk/lib/CodeGen/<u></u>CodeGenModule.cpp (original)<br>
> +++ cfe/trunk/lib/CodeGen/<u></u>CodeGenModule.cpp Tue Feb 25 03:53:29 2014<br>
> @@ -635,8 +635,7 @@ void CodeGenModule::<u></u>SetLLVMFunctionAttri<br>
> B.addAttribute(llvm::<u></u>Attribute::NoDuplicate);<br>
> } else if (D->hasAttr<NoInlineAttr>()) {<br>
> B.addAttribute(llvm::<u></u>Attribute::NoInline);<br>
> - } else if ((D->hasAttr<AlwaysInlineAttr><u></u>() ||<br>
> - D->hasAttr<ForceInlineAttr>()) &&<br>
> + } else if (D->hasAttr<AlwaysInlineAttr>(<u></u>) &&<br>
> !F->getAttributes().<u></u>hasAttribute(llvm::<u></u>AttributeSet::FunctionIndex,<br>
> llvm::Attribute::NoInline)) {<br>
> // (noinline wins over always_inline, and we can't specify both in IR)<br>
> @@ -1245,8 +1244,7 @@ CodeGenModule::<u></u>shouldEmitFunction(Global<br>
> if (getFunctionLinkage(GD) != llvm::Function::<u></u>AvailableExternallyLinkage)<br>
> return true;<br>
> const FunctionDecl *F = cast<FunctionDecl>(GD.getDecl(<u></u>));<br>
> - if (CodeGenOpts.OptimizationLevel == 0 &&<br>
> - !F->hasAttr<AlwaysInlineAttr>(<u></u>) && !F->hasAttr<ForceInlineAttr>()<u></u>)<br>
> + if (CodeGenOpts.OptimizationLevel == 0 && !F->hasAttr<AlwaysInlineAttr>(<u></u>))<br>
> return false;<br>
> // PR9614. Avoid cases where the source code is lying to us. An available<br>
> // externally function should have an equivalent function somewhere else,<br>
><br>
> Modified: cfe/trunk/lib/Sema/<u></u>SemaDeclAttr.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=202131&r1=202130&r2=202131&view=diff" target="_blank">http://llvm.org/viewvc/llvm-<u></u>project/cfe/trunk/lib/Sema/<u></u>SemaDeclAttr.cpp?rev=202131&<u></u>r1=202130&r2=202131&view=diff</a><br>
> ==============================<u></u>==============================<u></u>==================<br>
> --- cfe/trunk/lib/Sema/<u></u>SemaDeclAttr.cpp (original)<br>
> +++ cfe/trunk/lib/Sema/<u></u>SemaDeclAttr.cpp Tue Feb 25 03:53:29 2014<br>
> @@ -4269,8 +4269,6 @@ static void ProcessDeclAttribute(Sema &S<br>
> break;<br>
> case AttributeList::AT_<u></u>MSInheritance:<br>
> handleMSInheritanceAttr(S, D, Attr); break;<br>
> - case AttributeList::AT_ForceInline:<br>
> - handleSimpleAttribute<<u></u>ForceInlineAttr>(S, D, Attr); break;<br>
> case AttributeList::AT_SelectAny:<br>
> handleSimpleAttribute<<u></u>SelectAnyAttr>(S, D, Attr); break;<br>
><br>
><br>
><br>
> ______________________________<u></u>_________________<br>
> cfe-commits mailing list<br>
> <a href="mailto:cfe-commits@cs.uiuc.edu" target="_blank">cfe-commits@cs.uiuc.edu</a><br>
> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/<u></u>mailman/listinfo/cfe-commits</a><br>
</blockquote></div></div>