forked from OSchip/llvm-project
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
This commit is contained in:
parent
650c8f2a06
commit
41af7c2fdc
clang
include/clang/Basic
lib
test
|
@ -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">,
|
||||
|
|
|
@ -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 = [{
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
}
|
|
@ -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();
|
||||
}
|
|
@ -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();
|
||||
};
|
Loading…
Reference in New Issue