summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'llvm')
-rw-r--r--llvm/lib/Transforms/IPO/FunctionAttrs.cpp20
-rw-r--r--llvm/test/Transforms/FunctionAttrs/optnone.ll24
2 files changed, 37 insertions, 7 deletions
diff --git a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
index 5299e648b63..7e0cfa9eb70 100644
--- a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
+++ b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
@@ -161,8 +161,9 @@ bool FunctionAttrs::AddReadAttrs(const CallGraphSCC &SCC) {
for (CallGraphSCC::iterator I = SCC.begin(), E = SCC.end(); I != E; ++I) {
Function *F = (*I)->getFunction();
- if (!F)
- // External node - may write memory. Just give up.
+ if (!F || F->hasFnAttribute(Attribute::OptimizeNone))
+ // External node or node we don't want to optimize - assume it may write
+ // memory and give up.
return false;
AliasAnalysis::ModRefBehavior MRB = AA->getModRefBehavior(F);
@@ -527,7 +528,8 @@ bool FunctionAttrs::AddArgumentAttrs(const CallGraphSCC &SCC) {
// looking up whether a given CallGraphNode is in this SCC.
for (CallGraphSCC::iterator I = SCC.begin(), E = SCC.end(); I != E; ++I) {
Function *F = (*I)->getFunction();
- if (F && !F->isDeclaration() && !F->mayBeOverridden())
+ if (F && !F->isDeclaration() && !F->mayBeOverridden() &&
+ !F->hasFnAttribute(Attribute::OptimizeNone))
SCCNodes.insert(F);
}
@@ -541,8 +543,9 @@ bool FunctionAttrs::AddArgumentAttrs(const CallGraphSCC &SCC) {
for (CallGraphSCC::iterator I = SCC.begin(), E = SCC.end(); I != E; ++I) {
Function *F = (*I)->getFunction();
- if (!F)
- // External node - only a problem for arguments that we pass to it.
+ if (!F || F->hasFnAttribute(Attribute::OptimizeNone))
+ // External node or function we're trying not to optimize - only a problem
+ // for arguments that we pass to it.
continue;
// Definitions with weak linkage may be overridden at linktime with
@@ -794,8 +797,8 @@ bool FunctionAttrs::AddNoAliasAttrs(const CallGraphSCC &SCC) {
for (CallGraphSCC::iterator I = SCC.begin(), E = SCC.end(); I != E; ++I) {
Function *F = (*I)->getFunction();
- if (!F)
- // External node - skip it;
+ if (!F || F->hasFnAttribute(Attribute::OptimizeNone))
+ // External node or node we don't want to optimize - skip it;
return false;
// Already noalias.
@@ -834,6 +837,9 @@ bool FunctionAttrs::AddNoAliasAttrs(const CallGraphSCC &SCC) {
/// given function and set any applicable attributes. Returns true
/// if any attributes were set and false otherwise.
bool FunctionAttrs::inferPrototypeAttributes(Function &F) {
+ if (F.hasFnAttribute(Attribute::OptimizeNone))
+ return false;
+
FunctionType *FTy = F.getFunctionType();
LibFunc::Func TheLibFunc;
if (!(TLI->getLibFunc(F.getName(), TheLibFunc) && TLI->has(TheLibFunc)))
diff --git a/llvm/test/Transforms/FunctionAttrs/optnone.ll b/llvm/test/Transforms/FunctionAttrs/optnone.ll
new file mode 100644
index 00000000000..7694bfe13aa
--- /dev/null
+++ b/llvm/test/Transforms/FunctionAttrs/optnone.ll
@@ -0,0 +1,24 @@
+; RUN: opt < %s -functionattrs -S | FileCheck %s
+
+@x = global i32 0
+
+define void @test_opt(i8* %p) {
+; CHECK-LABEL: @test_opt
+; CHECK: (i8* nocapture readnone %p) #0 {
+ ret void
+}
+
+define void @test_optnone(i8* %p) noinline optnone {
+; CHECK-LABEL: @test_optnone
+; CHECK: (i8* %p) #1 {
+ ret void
+}
+
+declare i8 @strlen(i8*) noinline optnone
+; CHECK-LABEL: @strlen
+; CHECK: (i8*) #1
+
+; CHECK-LABEL: attributes #0
+; CHECK: = { readnone }
+; CHECK-LABEL: attributes #1
+; CHECK: = { noinline optnone }
OpenPOWER on IntegriCloud