Skip to content

Commit

Permalink
Implement the flatten attribute.
Browse files Browse the repository at this point in the history
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
  • Loading branch information
pcc committed May 20, 2014
1 parent 650c8f2 commit 41af7c2
Show file tree
Hide file tree
Showing 7 changed files with 86 additions and 0 deletions.
6 changes: 6 additions & 0 deletions clang/include/clang/Basic/Attr.td
Expand Up @@ -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">,
Expand Down
8 changes: 8 additions & 0 deletions clang/include/clang/Basic/AttrDocs.td
Expand Up @@ -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 = [{
Expand Down
6 changes: 6 additions & 0 deletions clang/lib/CodeGen/CGCall.cpp
Expand Up @@ -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));

Expand Down
3 changes: 3 additions & 0 deletions clang/lib/Sema/SemaDeclAttr.cpp
Expand Up @@ -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;
Expand Down
19 changes: 19 additions & 0 deletions 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();
}
10 changes: 10 additions & 0 deletions 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();
}
34 changes: 34 additions & 0 deletions 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();
};

0 comments on commit 41af7c2

Please sign in to comment.