The 'optnone' attribute means don't inline anything into this function

(except functions marked always_inline).
Functions with 'optnone' must also have 'noinline' so they don't get
inlined into any other function.

Based on work by Andrea Di Biagio.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@195046 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Paul Robinson 2013-11-18 21:44:03 +00:00
parent 3560dd2dcd
commit fe45fd084d
6 changed files with 67 additions and 10 deletions

View File

@ -941,9 +941,10 @@ example:
attribute; this attribute is also incompatible
with the ``minsize`` attribute and the ``optsize`` attribute.
The inliner should never inline this function in any situation.
This attribute requires the ``noinline`` attribute to be specified on
the function as well, so the function is never inlined into any caller.
Only functions with the ``alwaysinline`` attribute are valid
candidates for inlining inside the body of this function.
candidates for inlining into the body of this function.
``optsize``
This attribute suggests that optimization passes and code generator
passes make choices that keep the code size of this function low,

View File

@ -1206,6 +1206,10 @@ InlineCost InlineCostAnalysis::getInlineCost(CallSite CS, Function *Callee,
if (!functionsHaveCompatibleAttributes(CS.getCaller(), Callee))
return llvm::InlineCost::getNever();
// Don't inline this call if the caller has the optnone attribute.
if (CS.getCaller()->hasFnAttribute(Attribute::OptimizeNone))
return llvm::InlineCost::getNever();
// Don't inline functions which can be redefined at link-time to mean
// something else. Don't inline functions marked noinline or call sites
// marked noinline.

View File

@ -927,9 +927,9 @@ void Verifier::VerifyFunctionAttrs(FunctionType *FT, AttributeSet Attrs,
if (Attrs.hasAttribute(AttributeSet::FunctionIndex,
Attribute::OptimizeNone)) {
Assert1(!Attrs.hasAttribute(AttributeSet::FunctionIndex,
Attribute::AlwaysInline),
"Attributes 'alwaysinline and optnone' are incompatible!", V);
Assert1(Attrs.hasAttribute(AttributeSet::FunctionIndex,
Attribute::NoInline),
"Attribute 'optnone' requires 'noinline'!", V);
Assert1(!Attrs.hasAttribute(AttributeSet::FunctionIndex,
Attribute::OptimizeForSize),

View File

@ -207,7 +207,7 @@ define void @f34()
ret void;
}
define void @f35() optnone
define void @f35() optnone noinline
; CHECK: define void @f35() #23
{
ret void;
@ -236,6 +236,6 @@ define void @f35() optnone
; CHECK: attributes #20 = { "cpu"="cortex-a8" }
; CHECK: attributes #21 = { sspstrong }
; CHECK: attributes #22 = { minsize }
; CHECK: attributes #23 = { optnone }
; CHECK: attributes #23 = { noinline optnone }
; CHECK: attributes #24 = { nobuiltin }

View File

@ -1,12 +1,12 @@
; RUN: llvm-as < %s | llvm-dis | FileCheck %s
; Check for the presence of attribute noopt in the disassembly.
; Check for the presence of attribute optnone in the disassembly.
; CHECK: @foo() #0
define void @foo() #0 {
ret void
}
; CHECK: attributes #0 = { optnone }
attributes #0 = { optnone }
; CHECK: attributes #0 = { noinline optnone }
attributes #0 = { optnone noinline }

View File

@ -0,0 +1,52 @@
; RUN: opt < %s -inline -S | FileCheck %s
; Test that functions with attribute optnone are not inlined.
; Also test that only functions with attribute alwaysinline are
; valid candidates for inlining if the caller has the optnone attribute.
; Function Attrs: alwaysinline nounwind readnone uwtable
define i32 @alwaysInlineFunction(i32 %a) #0 {
entry:
%mul = mul i32 %a, %a
ret i32 %mul
}
; Function Attrs: nounwind readnone uwtable
define i32 @simpleFunction(i32 %a) #1 {
entry:
%add = add i32 %a, %a
ret i32 %add
}
; Function Attrs: nounwind noinline optnone readnone uwtable
define i32 @OptnoneFunction(i32 %a) #2 {
entry:
%0 = tail call i32 @alwaysInlineFunction(i32 %a)
%1 = tail call i32 @simpleFunction(i32 %a)
%add = add i32 %0, %1
ret i32 %add
}
; CHECK-LABEL: @OptnoneFunction
; CHECK-NOT: call i32 @alwaysInlineFunction(i32 %a)
; CHECK: call i32 @simpleFunction(i32 %a)
; CHECK: ret
; Function Attrs: nounwind readnone uwtable
define i32 @bar(i32 %a) #1 {
entry:
%0 = tail call i32 @OptnoneFunction(i32 5)
%1 = tail call i32 @simpleFunction(i32 6)
%add = add i32 %0, %1
ret i32 %add
}
; CHECK-LABEL: @bar
; CHECK: call i32 @OptnoneFunction(i32 5)
; CHECK-NOT: call i32 @simpleFunction(i32 6)
; CHECK: ret
attributes #0 = { alwaysinline nounwind readnone uwtable }
attributes #1 = { nounwind readnone uwtable }
attributes #2 = { nounwind noinline optnone readnone uwtable }