summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Collingbourne <peter@pcc.me.uk>2014-05-20 17:12:51 +0000
committerPeter Collingbourne <peter@pcc.me.uk>2014-05-20 17:12:51 +0000
commit41af7c2fdc8cc2ef186669dcb21cac58d5bd69ee (patch)
treee14576af7ea247b91481c99de20e727be5992c24
parent650c8f2a06f138d795d0188ec8276638e13f7c9d (diff)
downloadbcm5719-llvm-41af7c2fdc8cc2ef186669dcb21cac58d5bd69ee.tar.gz
bcm5719-llvm-41af7c2fdc8cc2ef186669dcb21cac58d5bd69ee.zip
Implement the flatten attribute.
This is a GNU attribute that causes calls within the attributed function to be inlined where possible. It is implemented by giving such calls the alwaysinline attribute. Differential Revision: http://reviews.llvm.org/D3816 llvm-svn: 209217
-rw-r--r--clang/include/clang/Basic/Attr.td6
-rw-r--r--clang/include/clang/Basic/AttrDocs.td8
-rw-r--r--clang/lib/CodeGen/CGCall.cpp6
-rw-r--r--clang/lib/Sema/SemaDeclAttr.cpp3
-rw-r--r--clang/test/CodeGen/flatten.c19
-rw-r--r--clang/test/CodeGenCXX/flatten.cpp10
-rw-r--r--clang/test/SemaCXX/attr-flatten.cpp34
7 files changed, 86 insertions, 0 deletions
diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index e054d6a8fb9..1b011b06868 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -668,6 +668,12 @@ def MinSize : InheritableAttr {
let Documentation = [Undocumented];
}
+def Flatten : InheritableAttr {
+ let Spellings = [GCC<"flatten">];
+ let Subjects = SubjectList<[Function], ErrorDiag>;
+ let Documentation = [FlattenDocs];
+}
+
def Format : InheritableAttr {
let Spellings = [GCC<"format">];
let Args = [IdentifierArgument<"Type">, IntArgument<"FormatIdx">,
diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td
index a0c2028512a..9694e210909 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -877,6 +877,14 @@ expression is compared to the type tag. There are two supported flags:
}];
}
+def FlattenDocs : Documentation {
+ let Category = DocCatFunction;
+ let Content = [{
+The ``flatten`` attribute causes calls within the attributed function to be
+inlined if possible.
+ }];
+}
+
def FormatDocs : Documentation {
let Category = DocCatFunction;
let Content = [{
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index e477a54c67e..31665f8851a 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -2935,6 +2935,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/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index b7c1d5d15b7..9775c58639c 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -4147,6 +4147,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/clang/test/CodeGen/flatten.c b/clang/test/CodeGen/flatten.c
new file mode 100644
index 00000000000..d766d543e01
--- /dev/null
+++ b/clang/test/CodeGen/flatten.c
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -triple=x86_64-linux-gnu %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();
+}
diff --git a/clang/test/CodeGenCXX/flatten.cpp b/clang/test/CodeGenCXX/flatten.cpp
new file mode 100644
index 00000000000..9e0f67f7898
--- /dev/null
+++ b/clang/test/CodeGenCXX/flatten.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -triple=x86_64-linux-gnu -std=c++11 %s -emit-llvm -o - | FileCheck %s
+
+void f(void) {}
+
+[[gnu::flatten]]
+// CHECK: define void @_Z1gv()
+void g(void) {
+ // CHECK-NOT: call {{.*}} @_Z1fv
+ f();
+}
diff --git a/clang/test/SemaCXX/attr-flatten.cpp b/clang/test/SemaCXX/attr-flatten.cpp
new file mode 100644
index 00000000000..afcba72b642
--- /dev/null
+++ b/clang/test/SemaCXX/attr-flatten.cpp
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
+
+int i __attribute__((flatten)); // expected-error {{'flatten' attribute only applies to functions}}
+
+void f1() __attribute__((flatten));
+void f2() __attribute__((flatten(1))); // expected-error {{'flatten' attribute takes no arguments}}
+
+template <typename T>
+void tf1() __attribute__((flatten));
+
+int f3(int __attribute__((flatten)), int); // expected-error{{'flatten' attribute only applies to functions}}
+
+struct A {
+ int f __attribute__((flatten)); // expected-error{{'flatten' attribute only applies to functions}}
+ void mf1() __attribute__((flatten));
+ static void mf2() __attribute__((flatten));
+};
+
+int ci [[gnu::flatten]]; // expected-error {{'flatten' attribute only applies to functions}}
+
+[[gnu::flatten]] void cf1();
+[[gnu::flatten(1)]] void cf2(); // expected-error {{'flatten' attribute takes no arguments}}
+
+template <typename T>
+[[gnu::flatten]]
+void ctf1();
+
+int cf3(int c[[gnu::flatten]], int); // expected-error{{'flatten' attribute only applies to functions}}
+
+struct CA {
+ int f [[gnu::flatten]]; // expected-error{{'flatten' attribute only applies to functions}}
+ [[gnu::flatten]] void mf1();
+ [[gnu::flatten]] static void mf2();
+};
OpenPOWER on IntegriCloud