mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-26 05:32:25 +00:00
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:
parent
3560dd2dcd
commit
fe45fd084d
@ -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,
|
||||
|
@ -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.
|
||||
|
@ -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),
|
||||
|
@ -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 }
|
||||
|
||||
|
@ -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 }
|
||||
|
||||
|
52
test/Transforms/Inline/inline-optnone.ll
Normal file
52
test/Transforms/Inline/inline-optnone.ll
Normal 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 }
|
Loading…
Reference in New Issue
Block a user