[PATCH] Implement the flatten attribute.

Alp Toker alp at nuanti.com
Sat May 17 01:51:38 PDT 2014


On 17/05/2014 09:17, Peter Collingbourne wrote:
> This is a GNU attribute that causes functions called by a function with the
> attribute to be inlined where possible. It is implemented by giving calls
> in such functions the alwaysinline attribute.
>
> http://reviews.llvm.org/D3816
>
> Files:
>    include/clang/Basic/Attr.td
>    lib/CodeGen/CGCall.cpp
>    lib/CodeGen/CodeGenModule.cpp
>    lib/CodeGen/CodeGenModule.h
>    lib/CodeGen/MicrosoftCXXABI.cpp
>    lib/Sema/SemaDeclAttr.cpp
>    test/CodeGen/flatten.c
>
> D3816.9506.patch
>
>
> Index: include/clang/Basic/Attr.td
> ===================================================================
> --- include/clang/Basic/Attr.td
> +++ include/clang/Basic/Attr.td
> @@ -668,6 +668,12 @@
>     let Documentation = [Undocumented];
>   }
>   
> +def Flatten : InheritableAttr {
> +  let Spellings = [GNU<"flatten">];
> +  let Subjects = SubjectList<[Function]>;
> +  let Documentation = [Undocumented];
> +}
> +
>   def Format : InheritableAttr {
>     let Spellings = [GCC<"format">];
>     let Args = [IdentifierArgument<"Type">, IntArgument<"FormatIdx">,
> Index: lib/CodeGen/CGCall.cpp
> ===================================================================
> --- lib/CodeGen/CGCall.cpp
> +++ lib/CodeGen/CGCall.cpp
> @@ -1063,6 +1063,7 @@
>   }
>   
>   void CodeGenModule::ConstructAttributeList(const CGFunctionInfo &FI,
> +                                           const Decl *CallerDecl,
>                                              const Decl *TargetDecl,
>                                              AttributeListType &PAL,
>                                              unsigned &CallingConv,
> @@ -1075,6 +1076,11 @@
>     if (FI.isNoReturn())
>       FuncAttrs.addAttribute(llvm::Attribute::NoReturn);
>   
> +  if (CallerDecl) {
> +    if (CallerDecl->hasAttr<FlattenAttr>())
> +      FuncAttrs.addAttribute(llvm::Attribute::AlwaysInline);
> +  }
> +

If the callee is NoInline we should probably give that priority preserve 
correctness.

>     // FIXME: handle sseregparm someday...
>     if (TargetDecl) {
>       if (TargetDecl->hasAttr<ReturnsTwiceAttr>())
> @@ -2913,7 +2919,7 @@
>   
>     unsigned CallingConv;
>     CodeGen::AttributeListType AttributeList;
> -  CGM.ConstructAttributeList(CallInfo, TargetDecl, AttributeList,
> +  CGM.ConstructAttributeList(CallInfo, CurCodeDecl, TargetDecl, AttributeList,
>                                CallingConv, true);

I'd prefer to keep locality and handle the attribute in EmitCall(), 
instead of adding CallerDecl and generally passing 0 to it.

I don't usually work on CodeGen so I've attached my interpretation of 
the feature based on your patch for review :-)

Alp.


>     llvm::AttributeSet Attrs = llvm::AttributeSet::get(getLLVMContext(),
>                                                        AttributeList);
> Index: lib/CodeGen/CodeGenModule.cpp
> ===================================================================
> --- lib/CodeGen/CodeGenModule.cpp
> +++ lib/CodeGen/CodeGenModule.cpp
> @@ -576,7 +576,7 @@
>                                                 llvm::Function *F) {
>     unsigned CallingConv;
>     AttributeListType AttributeList;
> -  ConstructAttributeList(Info, D, AttributeList, CallingConv, false);
> +  ConstructAttributeList(Info, 0, D, AttributeList, CallingConv, false);
>     F->setAttributes(llvm::AttributeSet::get(getLLVMContext(), AttributeList));
>     F->setCallingConv(static_cast<llvm::CallingConv::ID>(CallingConv));
>   }
> Index: lib/CodeGen/CodeGenModule.h
> ===================================================================
> --- lib/CodeGen/CodeGenModule.h
> +++ lib/CodeGen/CodeGenModule.h
> @@ -906,12 +906,14 @@
>     /// function type.
>     ///
>     /// \param Info - The function type information.
> +  /// \param CallerDecl - The decl of the caller, if available
>     /// \param TargetDecl - The decl these attributes are being constructed
>     /// for. If supplied the attributes applied to this decl may contribute to the
>     /// function attributes and calling convention.
>     /// \param PAL [out] - On return, the attribute list to use.
>     /// \param CallingConv [out] - On return, the LLVM calling convention to use.
>     void ConstructAttributeList(const CGFunctionInfo &Info,
> +                              const Decl *CallerDecl,
>                                 const Decl *TargetDecl,
>                                 AttributeListType &PAL,
>                                 unsigned &CallingConv,
> Index: lib/CodeGen/MicrosoftCXXABI.cpp
> ===================================================================
> --- lib/CodeGen/MicrosoftCXXABI.cpp
> +++ lib/CodeGen/MicrosoftCXXABI.cpp
> @@ -1113,7 +1113,7 @@
>   
>     unsigned CallingConv;
>     CodeGen::AttributeListType AttributeList;
> -  CGM.ConstructAttributeList(FnInfo, MD, AttributeList, CallingConv, true);
> +  CGM.ConstructAttributeList(FnInfo, 0, MD, AttributeList, CallingConv, true);
>     llvm::AttributeSet Attrs =
>         llvm::AttributeSet::get(CGF.getLLVMContext(), AttributeList);
>   
> Index: lib/Sema/SemaDeclAttr.cpp
> ===================================================================
> --- lib/Sema/SemaDeclAttr.cpp
> +++ lib/Sema/SemaDeclAttr.cpp
> @@ -4140,6 +4140,9 @@
>     case AttributeList::AT_OptimizeNone:
>       handleOptimizeNoneAttr(S, D, Attr);
>       break;
> +  case AttributeList::AT_Flatten:
> +    handleSimpleAttribute<FlattenAttr>(S, D, Attr);
> +    break;
>     case AttributeList::AT_Format:
>       handleFormatAttr(S, D, Attr);
>       break;
> Index: test/CodeGen/flatten.c
> ===================================================================
> --- /dev/null
> +++ test/CodeGen/flatten.c
> @@ -0,0 +1,10 @@
> +// RUN: %clang -target x86_64-linux-gnu -S %s -emit-llvm -o - | FileCheck %s
> +
> +void f(void) {}
> +
> +__attribute__((flatten))
> +// CHECK: define void @g()
> +void g(void) {
> +  // CHECK-NOT: call {{.*}} @f
> +  f();
> +}
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

-- 
http://www.nuanti.com
the browser experts

-------------- next part --------------
diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td
index 5c5e597..43190a3 100644
--- a/include/clang/Basic/Attr.td
+++ b/include/clang/Basic/Attr.td
@@ -668,6 +668,12 @@ def MinSize : InheritableAttr {
   let Documentation = [Undocumented];
 }
 
+def Flatten : InheritableAttr {
+  let Spellings = [GNU<"flatten">];
+  let Subjects = SubjectList<[Function]>;
+  let Documentation = [Undocumented];
+}
+
 def Format : InheritableAttr {
   let Spellings = [GCC<"format">];
   let Args = [IdentifierArgument<"Type">, IntArgument<"FormatIdx">,
diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp
index 61bf985..48d1b40 100644
--- a/lib/CodeGen/CGCall.cpp
+++ b/lib/CodeGen/CGCall.cpp
@@ -2934,6 +2934,12 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
   if (callOrInvoke)
     *callOrInvoke = CS.getInstruction();
 
+  if (CurCodeDecl && CurCodeDecl->hasAttr<FlattenAttr>() &&
+      !CS.hasFnAttr(llvm::Attribute::NoInline))
+    Attrs =
+        Attrs.addAttribute(getLLVMContext(), llvm::AttributeSet::FunctionIndex,
+                           llvm::Attribute::AlwaysInline);
+
   CS.setAttributes(Attrs);
   CS.setCallingConv(static_cast<llvm::CallingConv::ID>(CallingConv));
 
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index 9caf918..7ce5932 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -4140,6 +4140,9 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
   case AttributeList::AT_OptimizeNone:
     handleOptimizeNoneAttr(S, D, Attr);
     break;
+  case AttributeList::AT_Flatten:
+    handleSimpleAttribute<FlattenAttr>(S, D, Attr);
+    break;
   case AttributeList::AT_Format:
     handleFormatAttr(S, D, Attr);
     break;
diff --git a/test/CodeGen/flatten.c b/test/CodeGen/flatten.c
new file mode 100644
index 0000000..7e897d1
--- /dev/null
+++ b/test/CodeGen/flatten.c
@@ -0,0 +1,19 @@
+// RUN: %clang -target x86_64-linux-gnu -S %s -emit-llvm -o - | FileCheck %s
+
+void f(void) {}
+
+__attribute__((noinline)) void ni(void) {}
+
+__attribute__((flatten))
+// CHECK: define void @g()
+void g(void) {
+  // CHECK-NOT: call {{.*}} @f
+  f();
+  // CHECK: call {{.*}} @ni
+  ni();
+}
+
+void h(void) {
+  // CHECK: call {{.*}} @f
+  f();
+}


More information about the cfe-commits mailing list