r202131 - Attr: Remove ForceInline

Aaron Ballman aaron at aaronballman.com
Tue Feb 25 05:24:05 PST 2014


I don't believe the semantics for __forceinline and always_inline
really match up. As best I can tell, always_inline will *always*
inline the function, regardless of optimization level, which is not
something that __forceinline does. As a simple example:

__forceinline int i() { return 9; }

int main(void) {
  int j = i();
  return 0;
}

In debug mode in MSVC 2013, this produces (in part):

; 3    : int main(void) {

push ebp
mov ebp, esp
sub esp, 204 ; 000000ccH
push ebx
push esi
push edi
lea edi, DWORD PTR [ebp-204]
mov ecx, 51 ; 00000033H
mov eax, -858993460 ; ccccccccH
rep stosd

; 4    :   int j = i();

call ?i@@YAHXZ ; i
mov DWORD PTR _j$[ebp], eax

; 5    :   return 0;

xor eax, eax

; 6    : }

When I compile in GCC (using always_inline) at -O0, I get:

main:
push rbp
mov rbp, rsp
mov eax, 9
mov DWORD PTR [rbp-4], eax
mov eax, 0
pop rbp
ret

Clang may not support __forceinline semantics properly yet, but I am
not keen on this behavior change. It also deviates from the
documentation for both (gcc claims "this attribute inlines the
function even if no optimization level was specified." and msvc claims
"You cannot force the compiler to inline a particular function, even
with the __forceinline keyword.").

~Aaron

On Tue, Feb 25, 2014 at 4:53 AM, David Majnemer
<david.majnemer at gmail.com> wrote:
> Author: majnemer
> Date: Tue Feb 25 03:53:29 2014
> New Revision: 202131
>
> URL: http://llvm.org/viewvc/llvm-project?rev=202131&view=rev
> Log:
> Attr: Remove ForceInline
>
> The __forceinline keyword's semantics are now recast as AlwaysInline and
> the kw___forceinline token has its language mode set for KEYMS.
>
> This preserves the semantics of the previous implementation but with
> less duplication of code.
>
> Modified:
>     cfe/trunk/include/clang/Basic/Attr.td
>     cfe/trunk/include/clang/Basic/TokenKinds.def
>     cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
>     cfe/trunk/lib/CodeGen/CodeGenModule.cpp
>     cfe/trunk/lib/Sema/SemaDeclAttr.cpp
>
> Modified: cfe/trunk/include/clang/Basic/Attr.td
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=202131&r1=202130&r2=202131&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Basic/Attr.td (original)
> +++ cfe/trunk/include/clang/Basic/Attr.td Tue Feb 25 03:53:29 2014
> @@ -357,7 +357,7 @@ def AlignMac68k : InheritableAttr {
>  }
>
>  def AlwaysInline : InheritableAttr {
> -  let Spellings = [GCC<"always_inline">];
> +  let Spellings = [GCC<"always_inline">, Keyword<"__forceinline">];
>    let Subjects = SubjectList<[Function]>;
>    let Documentation = [Undocumented];
>  }
> @@ -1676,12 +1676,6 @@ def DLLImport : InheritableAttr, TargetS
>    let Documentation = [Undocumented];
>  }
>
> -def ForceInline : InheritableAttr {
> -  let Spellings = [Keyword<"__forceinline">];
> -  let LangOpts = [MicrosoftExt];
> -  let Documentation = [Undocumented];
> -}
> -
>  def SelectAny : InheritableAttr {
>    let Spellings = [Declspec<"selectany">];
>    let LangOpts = [MicrosoftExt];
>
> Modified: cfe/trunk/include/clang/Basic/TokenKinds.def
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/TokenKinds.def?rev=202131&r1=202130&r2=202131&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Basic/TokenKinds.def (original)
> +++ cfe/trunk/include/clang/Basic/TokenKinds.def Tue Feb 25 03:53:29 2014
> @@ -455,7 +455,7 @@ KEYWORD(__cdecl                     , KE
>  KEYWORD(__stdcall                   , KEYALL)
>  KEYWORD(__fastcall                  , KEYALL)
>  KEYWORD(__thiscall                  , KEYALL)
> -KEYWORD(__forceinline               , KEYALL)
> +KEYWORD(__forceinline               , KEYMS)
>  KEYWORD(__unaligned                 , KEYMS)
>
>  // OpenCL address space qualifiers
>
> Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=202131&r1=202130&r2=202131&view=diff
> ==============================================================================
> --- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp (original)
> +++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp Tue Feb 25 03:53:29 2014
> @@ -527,8 +527,7 @@ void CodeGenFunction::StartFunction(Glob
>            Fn->addFnAttr(llvm::Attribute::InlineHint);
>            break;
>          }
> -    } else if (!FD->hasAttr<AlwaysInlineAttr>() &&
> -               !FD->hasAttr<ForceInlineAttr>())
> +    } else if (!FD->hasAttr<AlwaysInlineAttr>())
>        Fn->addFnAttr(llvm::Attribute::NoInline);
>    }
>
>
> Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=202131&r1=202130&r2=202131&view=diff
> ==============================================================================
> --- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
> +++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Tue Feb 25 03:53:29 2014
> @@ -635,8 +635,7 @@ void CodeGenModule::SetLLVMFunctionAttri
>      B.addAttribute(llvm::Attribute::NoDuplicate);
>    } else if (D->hasAttr<NoInlineAttr>()) {
>      B.addAttribute(llvm::Attribute::NoInline);
> -  } else if ((D->hasAttr<AlwaysInlineAttr>() ||
> -              D->hasAttr<ForceInlineAttr>()) &&
> +  } else if (D->hasAttr<AlwaysInlineAttr>() &&
>               !F->getAttributes().hasAttribute(llvm::AttributeSet::FunctionIndex,
>                                                llvm::Attribute::NoInline)) {
>      // (noinline wins over always_inline, and we can't specify both in IR)
> @@ -1245,8 +1244,7 @@ CodeGenModule::shouldEmitFunction(Global
>    if (getFunctionLinkage(GD) != llvm::Function::AvailableExternallyLinkage)
>      return true;
>    const FunctionDecl *F = cast<FunctionDecl>(GD.getDecl());
> -  if (CodeGenOpts.OptimizationLevel == 0 &&
> -      !F->hasAttr<AlwaysInlineAttr>() && !F->hasAttr<ForceInlineAttr>())
> +  if (CodeGenOpts.OptimizationLevel == 0 && !F->hasAttr<AlwaysInlineAttr>())
>      return false;
>    // PR9614. Avoid cases where the source code is lying to us. An available
>    // externally function should have an equivalent function somewhere else,
>
> Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=202131&r1=202130&r2=202131&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Tue Feb 25 03:53:29 2014
> @@ -4269,8 +4269,6 @@ static void ProcessDeclAttribute(Sema &S
>      break;
>    case AttributeList::AT_MSInheritance:
>      handleMSInheritanceAttr(S, D, Attr); break;
> -  case AttributeList::AT_ForceInline:
> -    handleSimpleAttribute<ForceInlineAttr>(S, D, Attr); break;
>    case AttributeList::AT_SelectAny:
>      handleSimpleAttribute<SelectAnyAttr>(S, D, Attr); break;
>
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits



More information about the cfe-commits mailing list