[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