mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-03 01:12:53 +00:00
Implement function notes as function attributes.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@56716 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
e7261863c5
commit
2c9c3e7368
@ -26,8 +26,8 @@
|
||||
<li><a href="#functionstructure">Functions</a></li>
|
||||
<li><a href="#aliasstructure">Aliases</a>
|
||||
<li><a href="#paramattrs">Parameter Attributes</a></li>
|
||||
<li><a href="#fnattrs">Function Attributes</a></li>
|
||||
<li><a href="#gc">Garbage Collector Names</a></li>
|
||||
<li><a href="#notes">Function Notes</a></li>
|
||||
<li><a href="#moduleasm">Module-Level Inline Assembly</a></li>
|
||||
<li><a href="#datalayout">Data Layout</a></li>
|
||||
</ol>
|
||||
@ -826,8 +826,8 @@ a power of 2.</p>
|
||||
|
||||
<div class="doc_code">
|
||||
<pre>
|
||||
declare i32 @printf(i8* noalias , ...) nounwind
|
||||
declare i32 @atoi(i8*) nounwind readonly
|
||||
declare i32 @printf(i8* noalias , ...)
|
||||
declare i32 @atoi(i8 zeroext*)
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
@ -870,29 +870,9 @@ declare i32 @atoi(i8*) nounwind readonly
|
||||
parameter. The caller is responsible for ensuring that this is the case,
|
||||
usually by placing the value in a stack allocation.</dd>
|
||||
|
||||
<dt><tt>noreturn</tt></dt>
|
||||
<dd>This function attribute indicates that the function never returns. This
|
||||
indicates to LLVM that every call to this function should be treated as if
|
||||
an <tt>unreachable</tt> instruction immediately followed the call.</dd>
|
||||
|
||||
<dt><tt>nounwind</tt></dt>
|
||||
<dd>This function attribute indicates that no exceptions unwind out of the
|
||||
function. Usually this is because the function makes no use of exceptions,
|
||||
but it may also be that the function catches any exceptions thrown when
|
||||
executing it.</dd>
|
||||
|
||||
<dt><tt>nest</tt></dt>
|
||||
<dd>This indicates that the pointer parameter can be excised using the
|
||||
<a href="#int_trampoline">trampoline intrinsics</a>.</dd>
|
||||
<dt><tt>readonly</tt></dt>
|
||||
<dd>This function attribute indicates that the function has no side-effects
|
||||
except for producing a return value or throwing an exception. The value
|
||||
returned must only depend on the function arguments and/or global variables.
|
||||
It may use values obtained by dereferencing pointers.</dd>
|
||||
<dt><tt>readnone</tt></dt>
|
||||
<dd>A <tt>readnone</tt> function has the same restrictions as a <tt>readonly</tt>
|
||||
function, but in addition it is not allowed to dereference any pointer arguments
|
||||
or global variables.
|
||||
</dl>
|
||||
|
||||
</div>
|
||||
@ -916,38 +896,65 @@ the named garbage collection algorithm.</p>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<div class="doc_subsection">
|
||||
<a name="notes">Function Notes</a>
|
||||
<a name="fnattrs">Function Attributes</a>
|
||||
</div>
|
||||
|
||||
<div class="doc_text">
|
||||
<p>The function definition may list function notes which are used by
|
||||
various passes.</p>
|
||||
|
||||
<p>Function attributes are set to communicate additional information about
|
||||
a function. Function attributes are considered to be part of the function,
|
||||
not of the function type, so functions with different parameter attributes
|
||||
can have the same function type.</p>
|
||||
|
||||
<p>Function attributes are simple keywords that follow the type specified. If
|
||||
multiple attributes are needed, they are space separated. For
|
||||
example:</p>
|
||||
|
||||
<div class="doc_code">
|
||||
<pre>
|
||||
define void @f() notes(inline=Always) { ... }
|
||||
define void @f() notes(inline=Always,opt-size) { ... }
|
||||
define void @f() notes(inline=Never,opt-size) { ... }
|
||||
define void @f() notes(opt-size) { ... }
|
||||
define void @f() noinline { ... }
|
||||
define void @f() alwaysinline { ... }
|
||||
define void @f() alwaysinline optsize { ... }
|
||||
define void @f() optsize
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<dl>
|
||||
<dt><tt>inline=Always</tt></dt>
|
||||
<dd>This note requests inliner to inline this function irrespective of inlining
|
||||
size threshold for this function.</dd>
|
||||
<dt><tt>alwaysinline</tt></dt>
|
||||
<dd>This attribute requests inliner to inline this function irrespective of
|
||||
inlining size threshold for this function.</dd>
|
||||
|
||||
<dt><tt>inline=Never</tt></dt>
|
||||
<dd>This note requests inliner to never inline this function in any situation.
|
||||
This note may not be used together with <tt>inline=Always</tt> note.</dd>
|
||||
<dt><tt>noinline</tt></dt>
|
||||
<dd>This attributes requests inliner to never inline this function in any
|
||||
situation. This attribute may not be used together with <tt>alwaysinline</tt>
|
||||
attribute.</dd>
|
||||
|
||||
<dt><tt>opt-size</tt></dt>
|
||||
<dd>This note suggests optimization passes and code generator passes to make
|
||||
choices that help reduce code size.</dd>
|
||||
<dt><tt>optsize</tt></dt>
|
||||
<dd>This attribute suggests optimization passes and code generator passes to
|
||||
make choices that help reduce code size.</dd>
|
||||
|
||||
<dt><tt>noreturn</tt></dt>
|
||||
<dd>This function attribute indicates that the function never returns. This
|
||||
indicates to LLVM that every call to this function should be treated as if
|
||||
an <tt>unreachable</tt> instruction immediately followed the call.</dd>
|
||||
|
||||
<dt><tt>nounwind</tt></dt>
|
||||
<dd>This function attribute indicates that no exceptions unwind out of the
|
||||
function. Usually this is because the function makes no use of exceptions,
|
||||
but it may also be that the function catches any exceptions thrown when
|
||||
executing it.</dd>
|
||||
|
||||
<dt><tt>readonly</tt></dt>
|
||||
<dd>This function attribute indicates that the function has no side-effects
|
||||
except for producing a return value or throwing an exception. The value
|
||||
returned must only depend on the function arguments and/or global variables.
|
||||
It may use values obtained by dereferencing pointers.</dd>
|
||||
<dt><tt>readnone</tt></dt>
|
||||
<dd>A <tt>readnone</tt> function has the same restrictions as a <tt>readonly</tt>
|
||||
function, but in addition it is not allowed to dereference any pointer arguments
|
||||
or global variables.
|
||||
</dl>
|
||||
|
||||
<p>Any notes that are not documented here are considered invalid notes.</p>
|
||||
</div>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
|
@ -149,16 +149,16 @@ public:
|
||||
void setAttributes(const AttrListPtr &attrs) { AttributeList = attrs; }
|
||||
|
||||
|
||||
/// hasNote - Return true if this function has given note.
|
||||
bool hasNote(Attributes N) const {
|
||||
// Notes are stored at ~0 index in parameter attribute list
|
||||
return (paramHasAttr(~0, N));
|
||||
/// hasFnAttr - Return true if this function has given attribute.
|
||||
bool hasFnAttr(Attributes N) const {
|
||||
// Function Attributes are stored at ~0 index
|
||||
return AttributeList.paramHasAttr(~0U, N);
|
||||
}
|
||||
|
||||
/// setNotes - Set notes for this function
|
||||
/// addFnAttr - Add function attributes
|
||||
///
|
||||
void setNotes(const Attributes N) {
|
||||
// Notes are stored at ~0 index in parameter attribute list
|
||||
void addFnAttr(const Attributes N) {
|
||||
// Function Attributes are stored at ~0 index
|
||||
addAttribute(~0, N);
|
||||
}
|
||||
|
||||
|
@ -496,11 +496,9 @@ int LLLexer::LexIdentifier() {
|
||||
KEYWORD("readnone", READNONE);
|
||||
KEYWORD("readonly", READONLY);
|
||||
|
||||
KEYWORD("notes", FNNOTE);
|
||||
KEYWORD("inline", INLINE);
|
||||
KEYWORD("always", ALWAYS);
|
||||
KEYWORD("never", NEVER);
|
||||
KEYWORD("opt_size", OPTIMIZEFORSIZE);
|
||||
KEYWORD("noinline", NOINLINE);
|
||||
KEYWORD("alwaysinline", ALWAYSINLINE);
|
||||
KEYWORD("optsize", OPTSIZE);
|
||||
|
||||
KEYWORD("type", TYPE);
|
||||
KEYWORD("opaque", OPAQUE);
|
||||
|
@ -189,14 +189,12 @@
|
||||
READNONE = 405,
|
||||
READONLY = 406,
|
||||
GC = 407,
|
||||
FNNOTE = 408,
|
||||
INLINE = 409,
|
||||
ALWAYS = 410,
|
||||
NEVER = 411,
|
||||
OPTIMIZEFORSIZE = 412,
|
||||
DEFAULT = 413,
|
||||
HIDDEN = 414,
|
||||
PROTECTED = 415
|
||||
OPTSIZE = 408,
|
||||
NOINLINE = 409,
|
||||
ALWAYSINLINE = 410,
|
||||
DEFAULT = 411,
|
||||
HIDDEN = 412,
|
||||
PROTECTED = 413
|
||||
};
|
||||
#endif
|
||||
/* Tokens. */
|
||||
@ -350,21 +348,19 @@
|
||||
#define READNONE 405
|
||||
#define READONLY 406
|
||||
#define GC 407
|
||||
#define FNNOTE 408
|
||||
#define INLINE 409
|
||||
#define ALWAYS 410
|
||||
#define NEVER 411
|
||||
#define OPTIMIZEFORSIZE 412
|
||||
#define DEFAULT 413
|
||||
#define HIDDEN 414
|
||||
#define PROTECTED 415
|
||||
#define OPTSIZE 408
|
||||
#define NOINLINE 409
|
||||
#define ALWAYSINLINE 410
|
||||
#define DEFAULT 411
|
||||
#define HIDDEN 412
|
||||
#define PROTECTED 413
|
||||
|
||||
|
||||
|
||||
|
||||
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
|
||||
typedef union YYSTYPE
|
||||
#line 970 "/Volumes/MacOS9/gcc/llvm/lib/AsmParser/llvmAsmParser.y"
|
||||
#line 970 "/Volumes/Nanpura/mainline/llvm/lib/AsmParser/llvmAsmParser.y"
|
||||
{
|
||||
llvm::Module *ModuleVal;
|
||||
llvm::Function *FunctionVal;
|
||||
@ -413,7 +409,7 @@ typedef union YYSTYPE
|
||||
llvm::FCmpInst::Predicate FPredicate;
|
||||
}
|
||||
/* Line 1529 of yacc.c. */
|
||||
#line 417 "llvmAsmParser.tab.h"
|
||||
#line 413 "llvmAsmParser.tab.h"
|
||||
YYSTYPE;
|
||||
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
|
||||
# define YYSTYPE_IS_DECLARED 1
|
||||
|
@ -1089,8 +1089,6 @@ Module *llvm::RunVMAsmParser(llvm::MemoryBuffer *MB) {
|
||||
%type <UIntVal> OptCallingConv LocalNumber
|
||||
%type <Attributes> OptAttributes Attribute
|
||||
%type <Attributes> OptFuncAttrs FuncAttr
|
||||
%type <Attributes> OptFuncNotes FuncNote
|
||||
%type <Attributes> FuncNoteList
|
||||
|
||||
// Basic Block Terminating Operators
|
||||
%token <TermOpVal> RET BR SWITCH INVOKE UNWIND UNREACHABLE
|
||||
@ -1122,10 +1120,7 @@ Module *llvm::RunVMAsmParser(llvm::MemoryBuffer *MB) {
|
||||
|
||||
// Function Attributes
|
||||
%token SIGNEXT ZEROEXT NORETURN INREG SRET NOUNWIND NOALIAS BYVAL NEST
|
||||
%token READNONE READONLY GC
|
||||
|
||||
// Function Notes
|
||||
%token FNNOTE INLINE ALWAYS NEVER OPTIMIZEFORSIZE
|
||||
%token READNONE READONLY GC OPTSIZE NOINLINE ALWAYSINLINE
|
||||
|
||||
// Visibility Styles
|
||||
%token DEFAULT HIDDEN PROTECTED
|
||||
@ -1284,6 +1279,9 @@ FuncAttr : NORETURN { $$ = Attribute::NoReturn; }
|
||||
| SIGNEXT { $$ = Attribute::SExt; }
|
||||
| READNONE { $$ = Attribute::ReadNone; }
|
||||
| READONLY { $$ = Attribute::ReadOnly; }
|
||||
| NOINLINE { $$ = Attribute::NoInline }
|
||||
| ALWAYSINLINE { $$ = Attribute::AlwaysInline }
|
||||
| OPTSIZE { $$ = Attribute::OptimizeForSize }
|
||||
;
|
||||
|
||||
OptFuncAttrs : /* empty */ { $$ = Attribute::None; }
|
||||
@ -1292,31 +1290,6 @@ OptFuncAttrs : /* empty */ { $$ = Attribute::None; }
|
||||
}
|
||||
;
|
||||
|
||||
FuncNoteList : FuncNote { $$ = $1; }
|
||||
| FuncNoteList ',' FuncNote {
|
||||
unsigned tmp = $1 | $3;
|
||||
if ($3 == Attribute::NoInline
|
||||
&& ($1 & Attribute::AlwaysInline))
|
||||
GEN_ERROR("Function Notes may include only one inline notes!")
|
||||
if ($3 == Attribute::AlwaysInline
|
||||
&& ($1 & Attribute::NoInline))
|
||||
GEN_ERROR("Function Notes may include only one inline notes!")
|
||||
$$ = tmp;
|
||||
CHECK_FOR_ERROR
|
||||
}
|
||||
;
|
||||
|
||||
FuncNote : INLINE '=' NEVER { $$ = Attribute::NoInline; }
|
||||
| INLINE '=' ALWAYS { $$ = Attribute::AlwaysInline; }
|
||||
| OPTIMIZEFORSIZE { $$ = Attribute::OptimizeForSize; }
|
||||
;
|
||||
|
||||
OptFuncNotes : /* empty */ { $$ = Attribute::None; }
|
||||
| FNNOTE '(' FuncNoteList ')' {
|
||||
$$ = $3;
|
||||
}
|
||||
;
|
||||
|
||||
OptGC : /* empty */ { $$ = 0; }
|
||||
| GC STRINGCONSTANT {
|
||||
$$ = $2;
|
||||
@ -2332,7 +2305,7 @@ ArgList : ArgListH {
|
||||
};
|
||||
|
||||
FunctionHeaderH : OptCallingConv ResultTypes GlobalName '(' ArgList ')'
|
||||
OptFuncAttrs OptSection OptAlign OptGC OptFuncNotes {
|
||||
OptFuncAttrs OptSection OptAlign OptGC {
|
||||
std::string FunctionName(*$3);
|
||||
delete $3; // Free strdup'd memory!
|
||||
|
||||
@ -2453,9 +2426,6 @@ FunctionHeaderH : OptCallingConv ResultTypes GlobalName '(' ArgList ')'
|
||||
Fn->setGC($10->c_str());
|
||||
delete $10;
|
||||
}
|
||||
if ($11) {
|
||||
Fn->setNotes($11);
|
||||
}
|
||||
|
||||
// Add all of the arguments we parsed to the function...
|
||||
if ($5) { // Is null if empty...
|
||||
|
@ -1089,8 +1089,6 @@ Module *llvm::RunVMAsmParser(llvm::MemoryBuffer *MB) {
|
||||
%type <UIntVal> OptCallingConv LocalNumber
|
||||
%type <Attributes> OptAttributes Attribute
|
||||
%type <Attributes> OptFuncAttrs FuncAttr
|
||||
%type <Attributes> OptFuncNotes FuncNote
|
||||
%type <Attributes> FuncNoteList
|
||||
|
||||
// Basic Block Terminating Operators
|
||||
%token <TermOpVal> RET BR SWITCH INVOKE UNWIND UNREACHABLE
|
||||
@ -1122,10 +1120,7 @@ Module *llvm::RunVMAsmParser(llvm::MemoryBuffer *MB) {
|
||||
|
||||
// Function Attributes
|
||||
%token SIGNEXT ZEROEXT NORETURN INREG SRET NOUNWIND NOALIAS BYVAL NEST
|
||||
%token READNONE READONLY GC
|
||||
|
||||
// Function Notes
|
||||
%token FNNOTE INLINE ALWAYS NEVER OPTIMIZEFORSIZE
|
||||
%token READNONE READONLY GC OPTSIZE NOINLINE ALWAYSINLINE
|
||||
|
||||
// Visibility Styles
|
||||
%token DEFAULT HIDDEN PROTECTED
|
||||
@ -1284,6 +1279,9 @@ FuncAttr : NORETURN { $$ = Attribute::NoReturn; }
|
||||
| SIGNEXT { $$ = Attribute::SExt; }
|
||||
| READNONE { $$ = Attribute::ReadNone; }
|
||||
| READONLY { $$ = Attribute::ReadOnly; }
|
||||
| NOINLINE { $$ = Attribute::NoInline }
|
||||
| ALWAYSINLINE { $$ = Attribute::AlwaysInline }
|
||||
| OPTSIZE { $$ = Attribute::OptimizeForSize }
|
||||
;
|
||||
|
||||
OptFuncAttrs : /* empty */ { $$ = Attribute::None; }
|
||||
@ -1292,31 +1290,6 @@ OptFuncAttrs : /* empty */ { $$ = Attribute::None; }
|
||||
}
|
||||
;
|
||||
|
||||
FuncNoteList : FuncNote { $$ = $1; }
|
||||
| FuncNoteList ',' FuncNote {
|
||||
unsigned tmp = $1 | $3;
|
||||
if ($3 == Attribute::NoInline
|
||||
&& ($1 & Attribute::AlwaysInline))
|
||||
GEN_ERROR("Function Notes may include only one inline notes!")
|
||||
if ($3 == Attribute::AlwaysInline
|
||||
&& ($1 & Attribute::NoInline))
|
||||
GEN_ERROR("Function Notes may include only one inline notes!")
|
||||
$$ = tmp;
|
||||
CHECK_FOR_ERROR
|
||||
}
|
||||
;
|
||||
|
||||
FuncNote : INLINE '=' NEVER { $$ = Attribute::NoInline; }
|
||||
| INLINE '=' ALWAYS { $$ = Attribute::AlwaysInline; }
|
||||
| OPTIMIZEFORSIZE { $$ = Attribute::OptimizeForSize; }
|
||||
;
|
||||
|
||||
OptFuncNotes : /* empty */ { $$ = Attribute::None; }
|
||||
| FNNOTE '(' FuncNoteList ')' {
|
||||
$$ = $3;
|
||||
}
|
||||
;
|
||||
|
||||
OptGC : /* empty */ { $$ = 0; }
|
||||
| GC STRINGCONSTANT {
|
||||
$$ = $2;
|
||||
@ -2332,7 +2305,7 @@ ArgList : ArgListH {
|
||||
};
|
||||
|
||||
FunctionHeaderH : OptCallingConv ResultTypes GlobalName '(' ArgList ')'
|
||||
OptFuncAttrs OptSection OptAlign OptGC OptFuncNotes {
|
||||
OptFuncAttrs OptSection OptAlign OptGC {
|
||||
std::string FunctionName(*$3);
|
||||
delete $3; // Free strdup'd memory!
|
||||
|
||||
@ -2453,9 +2426,6 @@ FunctionHeaderH : OptCallingConv ResultTypes GlobalName '(' ArgList ')'
|
||||
Fn->setGC($10->c_str());
|
||||
delete $10;
|
||||
}
|
||||
if ($11) {
|
||||
Fn->setNotes($11);
|
||||
}
|
||||
|
||||
// Add all of the arguments we parsed to the function...
|
||||
if ($5) { // Is null if empty...
|
||||
|
@ -154,7 +154,7 @@ void X86ATTAsmPrinter::emitFunctionHeader(const MachineFunction &MF) {
|
||||
SwitchToSection(TAI->SectionForGlobal(F));
|
||||
|
||||
unsigned FnAlign = OptimizeForSize ? 1 : 4;
|
||||
if (!F->isDeclaration() && F->hasNote(Attribute::OptimizeForSize))
|
||||
if (!F->isDeclaration() && F->hasFnAttr(Attribute::OptimizeForSize))
|
||||
FnAlign = 1;
|
||||
switch (F->getLinkage()) {
|
||||
default: assert(0 && "Unknown linkage type!");
|
||||
|
@ -141,7 +141,7 @@ bool X86IntelAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
|
||||
SwitchToTextSection("_text", F);
|
||||
|
||||
unsigned FnAlign = OptimizeForSize ? 1 : 4;
|
||||
if (!F->isDeclaration() && F->hasNote(Attribute::OptimizeForSize))
|
||||
if (!F->isDeclaration() && F->hasFnAttr(Attribute::OptimizeForSize))
|
||||
FnAlign = 1;
|
||||
switch (F->getLinkage()) {
|
||||
default: assert(0 && "Unsupported linkage type!");
|
||||
|
@ -63,7 +63,7 @@ bool AlwaysInliner::doInitialization(CallGraph &CG) {
|
||||
|
||||
for (Module::iterator I = M.begin(), E = M.end();
|
||||
I != E; ++I)
|
||||
if (!I->isDeclaration() && !I->hasNote(Attribute::AlwaysInline))
|
||||
if (!I->isDeclaration() && !I->hasFnAttr(Attribute::AlwaysInline))
|
||||
NeverInline.insert(I);
|
||||
|
||||
return false;
|
||||
|
@ -65,7 +65,7 @@ bool SimpleInliner::doInitialization(CallGraph &CG) {
|
||||
|
||||
for (Module::iterator I = M.begin(), E = M.end();
|
||||
I != E; ++I)
|
||||
if (!I->isDeclaration() && I->hasNote(Attribute::NoInline))
|
||||
if (!I->isDeclaration() && I->hasFnAttr(Attribute::NoInline))
|
||||
NeverInline.insert(I);
|
||||
|
||||
// Get llvm.noinline
|
||||
|
@ -141,7 +141,8 @@ bool Inliner::runOnSCC(const std::vector<CallGraphNode*> &SCC) {
|
||||
|
||||
int CurrentThreshold = InlineThreshold;
|
||||
Function *Fn = CS.getCaller();
|
||||
if (Fn && !Fn->isDeclaration() && Fn->hasNote(Attribute::OptimizeForSize)
|
||||
if (Fn && !Fn->isDeclaration()
|
||||
&& Fn->hasFnAttr(Attribute::OptimizeForSize)
|
||||
&& InlineThreshold != 50) {
|
||||
CurrentThreshold = 50;
|
||||
}
|
||||
|
@ -430,7 +430,7 @@ bool LoopUnswitch::UnswitchIfProfitable(Value *LoopCond, Constant *Val){
|
||||
Function *F = loopHeader->getParent();
|
||||
|
||||
// Do not unswitch if the function is optimized for size.
|
||||
if (!F->isDeclaration() && F->hasNote(Attribute::OptimizeForSize))
|
||||
if (!F->isDeclaration() && F->hasFnAttr(Attribute::OptimizeForSize))
|
||||
return false;
|
||||
|
||||
// Check to see if it would be profitable to unswitch current loop.
|
||||
|
@ -222,7 +222,7 @@ int InlineCostAnalyzer::getInlineCost(CallSite CS,
|
||||
if (CalleeFI.NeverInline)
|
||||
return 2000000000;
|
||||
|
||||
if (!Callee->isDeclaration() && Callee->hasNote(Attribute::AlwaysInline))
|
||||
if (!Callee->isDeclaration() && Callee->hasFnAttr(Attribute::AlwaysInline))
|
||||
return -2000000000;
|
||||
|
||||
// Add to the inline quality for properties that make the call valuable to
|
||||
|
@ -1413,34 +1413,6 @@ void AssemblyWriter::printFunction(const Function *F) {
|
||||
if (F->isDeclaration()) {
|
||||
Out << "\n";
|
||||
} else {
|
||||
|
||||
bool insideNotes = false;
|
||||
if (F->hasNote(Attribute::AlwaysInline)) {
|
||||
Out << " notes(";
|
||||
insideNotes = true;
|
||||
Out << "inline=always";
|
||||
}
|
||||
if (F->hasNote(Attribute::NoInline)) {
|
||||
if (insideNotes)
|
||||
Out << ",";
|
||||
else {
|
||||
Out << " notes(";
|
||||
insideNotes = true;
|
||||
}
|
||||
Out << "inline=never";
|
||||
}
|
||||
if (F->hasNote(Attribute::OptimizeForSize)) {
|
||||
if (insideNotes)
|
||||
Out << ",";
|
||||
else {
|
||||
Out << " notes(";
|
||||
insideNotes = true;
|
||||
}
|
||||
Out << "opt_size";
|
||||
}
|
||||
if (insideNotes)
|
||||
Out << ")";
|
||||
|
||||
Out << " {";
|
||||
|
||||
// Output all of its basic blocks... for the function
|
||||
|
@ -1,7 +1,7 @@
|
||||
; RUN: llvm-as < %s | llc -march=arm
|
||||
; RUN: llvm-as < %s | llc -march=thumb
|
||||
|
||||
define double @t(double %x, double %y) nounwind notes(opt_size) {
|
||||
define double @t(double %x, double %y) nounwind optsize {
|
||||
entry:
|
||||
%0 = tail call double @llvm.pow.f64( double %x, double %y ) ; <double> [#uses=1]
|
||||
ret double %0
|
||||
|
@ -1,6 +1,6 @@
|
||||
; RUN: llvm-as < %s | opt -inline-threshold=0 -inline | llvm-dis | not grep call
|
||||
|
||||
define i32 @fn2() notes(inline=always) {
|
||||
define i32 @fn2() alwaysinline {
|
||||
ret i32 1
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
; RUN: llvm-as < %s | opt -inline | llvm-dis | grep call | count 1
|
||||
|
||||
define i32 @fn2() notes(inline=never) {
|
||||
define i32 @fn2() noinline {
|
||||
ret i32 1
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user