summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoman Divacky <rdivacky@freebsd.org>2014-01-15 19:07:16 +0000
committerRoman Divacky <rdivacky@freebsd.org>2014-01-15 19:07:16 +0000
commitdd9bfb2c1a2ad53fa3f8dfe3d8a6aa94de694297 (patch)
treea482f40b219c4607db7bc472a6d0bb3d9fd9232e
parent2e13b1c7f1005b1d9d9483f94c25b9eb92316cc9 (diff)
Make -fno-inline attach NoInline attribute to all functions that are not
marked as AlwaysInline or ForceInline. This moves us to what gcc does with -fno-inline. The attribute approach was discussed to be better than switching to InlineAlways inliner in presence of LTO. llvm-svn: 199324
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.cpp11
-rw-r--r--clang/test/CodeGen/noinline.c7
2 files changed, 15 insertions, 3 deletions
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index 108c14778198..cffbca37bddc 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -509,15 +509,20 @@ void CodeGenFunction::StartFunction(GlobalDecl GD,
}
// Pass inline keyword to optimizer if it appears explicitly on any
- // declaration.
- if (!CGM.getCodeGenOpts().NoInline)
- if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D))
+ // declaration. Also, in the case of -fno-inline attach NoInline
+ // attribute to all function that are not marked AlwaysInline or ForceInline.
+ if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D)) {
+ if (!CGM.getCodeGenOpts().NoInline) {
for (FunctionDecl::redecl_iterator RI = FD->redecls_begin(),
RE = FD->redecls_end(); RI != RE; ++RI)
if (RI->isInlineSpecified()) {
Fn->addFnAttr(llvm::Attribute::InlineHint);
break;
}
+ } else if (!FD->hasAttr<AlwaysInlineAttr>() &&
+ !FD->hasAttr<ForceInlineAttr>())
+ Fn->addFnAttr(llvm::Attribute::NoInline);
+ }
if (getLangOpts().OpenCL) {
// Add metadata for a kernel function.
diff --git a/clang/test/CodeGen/noinline.c b/clang/test/CodeGen/noinline.c
index e64a1a539f4b..bd5a9d8c35ff 100644
--- a/clang/test/CodeGen/noinline.c
+++ b/clang/test/CodeGen/noinline.c
@@ -5,10 +5,17 @@
inline int dont_inline_me(int a, int b) { return(a+b); }
+inline __attribute__ ((__always_inline__)) int inline_me(int a, int b) { return(a*b); }
+
volatile int *pa = (int*) 0x1000;
void foo() {
// NOINLINE: @foo
// NOINLINE: dont_inline_me
// NOINLINE-NOT: inlinehint
pa[0] = dont_inline_me(pa[1],pa[2]);
+// NOINLINE-NOT: inline_me
+ pa[3] = inline_me(pa[4],pa[5]);
}
+
+// NOINLINE: Function Attrs: noinline
+// NOINLINE: @dont_inline_me