mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-14 11:32:34 +00:00
Use parameter attribute store (soon to be renamed) for
Function Notes also. Function notes are stored at index ~0. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@56511 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
b2c3e3fdd9
commit
d9b4a5f859
@ -51,12 +51,6 @@ template<> struct ilist_traits<Argument>
|
|||||||
static int getListOffset();
|
static int getListOffset();
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef unsigned FunctionNotes;
|
|
||||||
const FunctionNotes FN_NOTE_None = 0;
|
|
||||||
const FunctionNotes FN_NOTE_NoInline = 1<<0;
|
|
||||||
const FunctionNotes FN_NOTE_AlwaysInline = 1<<1;
|
|
||||||
const FunctionNotes FN_NOTE_OptimizeForSize = 1<<2;
|
|
||||||
|
|
||||||
class Function : public GlobalValue, public Annotable,
|
class Function : public GlobalValue, public Annotable,
|
||||||
public ilist_node<Function> {
|
public ilist_node<Function> {
|
||||||
public:
|
public:
|
||||||
@ -76,7 +70,6 @@ private:
|
|||||||
mutable ArgumentListType ArgumentList; ///< The formal arguments
|
mutable ArgumentListType ArgumentList; ///< The formal arguments
|
||||||
ValueSymbolTable *SymTab; ///< Symbol table of args/instructions
|
ValueSymbolTable *SymTab; ///< Symbol table of args/instructions
|
||||||
PAListPtr ParamAttrs; ///< Parameter attributes
|
PAListPtr ParamAttrs; ///< Parameter attributes
|
||||||
FunctionNotes Notes; ///< Function properties
|
|
||||||
|
|
||||||
// The Calling Convention is stored in Value::SubclassData.
|
// The Calling Convention is stored in Value::SubclassData.
|
||||||
/*unsigned CallingConvention;*/
|
/*unsigned CallingConvention;*/
|
||||||
@ -155,18 +148,19 @@ public:
|
|||||||
///
|
///
|
||||||
void setParamAttrs(const PAListPtr &attrs) { ParamAttrs = attrs; }
|
void setParamAttrs(const PAListPtr &attrs) { ParamAttrs = attrs; }
|
||||||
|
|
||||||
/// getNotes - Return function notes
|
|
||||||
///
|
|
||||||
const FunctionNotes &getNotes() const { return Notes; }
|
|
||||||
|
|
||||||
/// hasNote - Return true if this function has given note.
|
/// hasNote - Return true if this function has given note.
|
||||||
bool hasNote(FunctionNotes N) const {
|
bool hasNote(ParameterAttributes N) const {
|
||||||
return (!isDeclaration() && (Notes & N));
|
// Notes are stored at ~0 index in parameter attribute list
|
||||||
|
return (!isDeclaration() && paramHasAttr(~0, N));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// setNotes - Set notes for this function
|
/// setNotes - Set notes for this function
|
||||||
///
|
///
|
||||||
void setNotes(const FunctionNotes P) { Notes = Notes | P;}
|
void setNotes(const ParameterAttributes N) {
|
||||||
|
// Notes are stored at ~0 index in parameter attribute list
|
||||||
|
addParamAttr(~0, N);
|
||||||
|
}
|
||||||
|
|
||||||
/// hasGC/getGC/setGC/clearGC - The name of the garbage collection algorithm
|
/// hasGC/getGC/setGC/clearGC - The name of the garbage collection algorithm
|
||||||
/// to use during code generation.
|
/// to use during code generation.
|
||||||
|
@ -47,6 +47,13 @@ const Attributes ReadOnly = 1<<10; ///< Function only reads from memory
|
|||||||
const Attributes Alignment = 0xffff<<16; ///< Alignment of parameter (16 bits)
|
const Attributes Alignment = 0xffff<<16; ///< Alignment of parameter (16 bits)
|
||||||
// 0 = unknown, else in clear (not log)
|
// 0 = unknown, else in clear (not log)
|
||||||
|
|
||||||
|
/// Function notes are implemented as attributes stored at index ~0 in
|
||||||
|
/// parameter attribute list.
|
||||||
|
const Attributes FN_NOTE_None = 0;
|
||||||
|
const Attributes FN_NOTE_NoInline = 1<<0; // inline=never
|
||||||
|
const Attributes FN_NOTE_AlwaysInline = 1<<1; // inline=always
|
||||||
|
const Attributes FN_NOTE_OptimizeForSize = 1<<2; // opt_size
|
||||||
|
|
||||||
/// @brief Attributes that only apply to function parameters.
|
/// @brief Attributes that only apply to function parameters.
|
||||||
const Attributes ParameterOnly = ByVal | Nest | StructRet;
|
const Attributes ParameterOnly = ByVal | Nest | StructRet;
|
||||||
|
|
||||||
|
@ -366,7 +366,7 @@
|
|||||||
|
|
||||||
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
|
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
|
||||||
typedef union YYSTYPE
|
typedef union YYSTYPE
|
||||||
#line 970 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y"
|
#line 970 "/Volumes/Nanpura/mainline/llvm/lib/AsmParser/llvmAsmParser.y"
|
||||||
{
|
{
|
||||||
llvm::Module *ModuleVal;
|
llvm::Module *ModuleVal;
|
||||||
llvm::Function *FunctionVal;
|
llvm::Function *FunctionVal;
|
||||||
@ -395,7 +395,7 @@ typedef union YYSTYPE
|
|||||||
llvm::GlobalValue::LinkageTypes Linkage;
|
llvm::GlobalValue::LinkageTypes Linkage;
|
||||||
llvm::GlobalValue::VisibilityTypes Visibility;
|
llvm::GlobalValue::VisibilityTypes Visibility;
|
||||||
llvm::ParameterAttributes ParamAttrs;
|
llvm::ParameterAttributes ParamAttrs;
|
||||||
llvm::FunctionNotes FunctionNotes;
|
llvm::ParameterAttributes FunctionNotes;
|
||||||
llvm::APInt *APIntVal;
|
llvm::APInt *APIntVal;
|
||||||
int64_t SInt64Val;
|
int64_t SInt64Val;
|
||||||
uint64_t UInt64Val;
|
uint64_t UInt64Val;
|
||||||
|
@ -995,7 +995,7 @@ Module *llvm::RunVMAsmParser(llvm::MemoryBuffer *MB) {
|
|||||||
llvm::GlobalValue::LinkageTypes Linkage;
|
llvm::GlobalValue::LinkageTypes Linkage;
|
||||||
llvm::GlobalValue::VisibilityTypes Visibility;
|
llvm::GlobalValue::VisibilityTypes Visibility;
|
||||||
llvm::ParameterAttributes ParamAttrs;
|
llvm::ParameterAttributes ParamAttrs;
|
||||||
llvm::FunctionNotes FunctionNotes;
|
llvm::ParameterAttributes FunctionNotes;
|
||||||
llvm::APInt *APIntVal;
|
llvm::APInt *APIntVal;
|
||||||
int64_t SInt64Val;
|
int64_t SInt64Val;
|
||||||
uint64_t UInt64Val;
|
uint64_t UInt64Val;
|
||||||
@ -1091,8 +1091,8 @@ Module *llvm::RunVMAsmParser(llvm::MemoryBuffer *MB) {
|
|||||||
%type <UIntVal> OptCallingConv LocalNumber
|
%type <UIntVal> OptCallingConv LocalNumber
|
||||||
%type <ParamAttrs> OptParamAttrs ParamAttr
|
%type <ParamAttrs> OptParamAttrs ParamAttr
|
||||||
%type <ParamAttrs> OptFuncAttrs FuncAttr
|
%type <ParamAttrs> OptFuncAttrs FuncAttr
|
||||||
%type <FunctionNotes> OptFuncNotes FuncNote
|
%type <ParamAttrs> OptFuncNotes FuncNote
|
||||||
%type <FunctionNotes> FuncNoteList
|
%type <ParamAttrs> FuncNoteList
|
||||||
|
|
||||||
// Basic Block Terminating Operators
|
// Basic Block Terminating Operators
|
||||||
%token <TermOpVal> RET BR SWITCH INVOKE UNWIND UNREACHABLE
|
%token <TermOpVal> RET BR SWITCH INVOKE UNWIND UNREACHABLE
|
||||||
@ -1297,22 +1297,24 @@ OptFuncAttrs : /* empty */ { $$ = ParamAttr::None; }
|
|||||||
|
|
||||||
FuncNoteList : FuncNote { $$ = $1; }
|
FuncNoteList : FuncNote { $$ = $1; }
|
||||||
| FuncNoteList ',' FuncNote {
|
| FuncNoteList ',' FuncNote {
|
||||||
FunctionNotes tmp = $1 | $3;
|
unsigned tmp = $1 | $3;
|
||||||
if ($3 == FN_NOTE_NoInline && ($1 & FN_NOTE_AlwaysInline))
|
if ($3 == ParamAttr::FN_NOTE_NoInline
|
||||||
|
&& ($1 & ParamAttr::FN_NOTE_AlwaysInline))
|
||||||
GEN_ERROR("Function Notes may include only one inline notes!")
|
GEN_ERROR("Function Notes may include only one inline notes!")
|
||||||
if ($3 == FN_NOTE_AlwaysInline && ($1 & FN_NOTE_NoInline))
|
if ($3 == ParamAttr::FN_NOTE_AlwaysInline
|
||||||
|
&& ($1 & ParamAttr::FN_NOTE_NoInline))
|
||||||
GEN_ERROR("Function Notes may include only one inline notes!")
|
GEN_ERROR("Function Notes may include only one inline notes!")
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
CHECK_FOR_ERROR
|
CHECK_FOR_ERROR
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
FuncNote : INLINE '=' NEVER { $$ = FN_NOTE_NoInline; }
|
FuncNote : INLINE '=' NEVER { $$ = ParamAttr::FN_NOTE_NoInline; }
|
||||||
| INLINE '=' ALWAYS { $$ = FN_NOTE_AlwaysInline; }
|
| INLINE '=' ALWAYS { $$ = ParamAttr::FN_NOTE_AlwaysInline; }
|
||||||
| OPTIMIZEFORSIZE { $$ = FN_NOTE_OptimizeForSize; }
|
| OPTIMIZEFORSIZE { $$ = ParamAttr::FN_NOTE_OptimizeForSize; }
|
||||||
;
|
;
|
||||||
|
|
||||||
OptFuncNotes : /* empty */ { $$ = FN_NOTE_None; }
|
OptFuncNotes : /* empty */ { $$ = ParamAttr::FN_NOTE_None; }
|
||||||
| FNNOTE '(' FuncNoteList ')' {
|
| FNNOTE '(' FuncNoteList ')' {
|
||||||
$$ = $3;
|
$$ = $3;
|
||||||
}
|
}
|
||||||
|
@ -995,7 +995,7 @@ Module *llvm::RunVMAsmParser(llvm::MemoryBuffer *MB) {
|
|||||||
llvm::GlobalValue::LinkageTypes Linkage;
|
llvm::GlobalValue::LinkageTypes Linkage;
|
||||||
llvm::GlobalValue::VisibilityTypes Visibility;
|
llvm::GlobalValue::VisibilityTypes Visibility;
|
||||||
llvm::ParameterAttributes ParamAttrs;
|
llvm::ParameterAttributes ParamAttrs;
|
||||||
llvm::FunctionNotes FunctionNotes;
|
llvm::ParameterAttributes FunctionNotes;
|
||||||
llvm::APInt *APIntVal;
|
llvm::APInt *APIntVal;
|
||||||
int64_t SInt64Val;
|
int64_t SInt64Val;
|
||||||
uint64_t UInt64Val;
|
uint64_t UInt64Val;
|
||||||
@ -1091,8 +1091,8 @@ Module *llvm::RunVMAsmParser(llvm::MemoryBuffer *MB) {
|
|||||||
%type <UIntVal> OptCallingConv LocalNumber
|
%type <UIntVal> OptCallingConv LocalNumber
|
||||||
%type <ParamAttrs> OptParamAttrs ParamAttr
|
%type <ParamAttrs> OptParamAttrs ParamAttr
|
||||||
%type <ParamAttrs> OptFuncAttrs FuncAttr
|
%type <ParamAttrs> OptFuncAttrs FuncAttr
|
||||||
%type <FunctionNotes> OptFuncNotes FuncNote
|
%type <ParamAttrs> OptFuncNotes FuncNote
|
||||||
%type <FunctionNotes> FuncNoteList
|
%type <ParamAttrs> FuncNoteList
|
||||||
|
|
||||||
// Basic Block Terminating Operators
|
// Basic Block Terminating Operators
|
||||||
%token <TermOpVal> RET BR SWITCH INVOKE UNWIND UNREACHABLE
|
%token <TermOpVal> RET BR SWITCH INVOKE UNWIND UNREACHABLE
|
||||||
@ -1297,22 +1297,24 @@ OptFuncAttrs : /* empty */ { $$ = ParamAttr::None; }
|
|||||||
|
|
||||||
FuncNoteList : FuncNote { $$ = $1; }
|
FuncNoteList : FuncNote { $$ = $1; }
|
||||||
| FuncNoteList ',' FuncNote {
|
| FuncNoteList ',' FuncNote {
|
||||||
FunctionNotes tmp = $1 | $3;
|
unsigned tmp = $1 | $3;
|
||||||
if ($3 == FN_NOTE_NoInline && ($1 & FN_NOTE_AlwaysInline))
|
if ($3 == ParamAttr::FN_NOTE_NoInline
|
||||||
|
&& ($1 & ParamAttr::FN_NOTE_AlwaysInline))
|
||||||
GEN_ERROR("Function Notes may include only one inline notes!")
|
GEN_ERROR("Function Notes may include only one inline notes!")
|
||||||
if ($3 == FN_NOTE_AlwaysInline && ($1 & FN_NOTE_NoInline))
|
if ($3 == ParamAttr::FN_NOTE_AlwaysInline
|
||||||
|
&& ($1 & ParamAttr::FN_NOTE_NoInline))
|
||||||
GEN_ERROR("Function Notes may include only one inline notes!")
|
GEN_ERROR("Function Notes may include only one inline notes!")
|
||||||
$$ = tmp;
|
$$ = tmp;
|
||||||
CHECK_FOR_ERROR
|
CHECK_FOR_ERROR
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
FuncNote : INLINE '=' NEVER { $$ = FN_NOTE_NoInline; }
|
FuncNote : INLINE '=' NEVER { $$ = ParamAttr::FN_NOTE_NoInline; }
|
||||||
| INLINE '=' ALWAYS { $$ = FN_NOTE_AlwaysInline; }
|
| INLINE '=' ALWAYS { $$ = ParamAttr::FN_NOTE_AlwaysInline; }
|
||||||
| OPTIMIZEFORSIZE { $$ = FN_NOTE_OptimizeForSize; }
|
| OPTIMIZEFORSIZE { $$ = ParamAttr::FN_NOTE_OptimizeForSize; }
|
||||||
;
|
;
|
||||||
|
|
||||||
OptFuncNotes : /* empty */ { $$ = FN_NOTE_None; }
|
OptFuncNotes : /* empty */ { $$ = ParamAttr::FN_NOTE_None; }
|
||||||
| FNNOTE '(' FuncNoteList ')' {
|
| FNNOTE '(' FuncNoteList ')' {
|
||||||
$$ = $3;
|
$$ = $3;
|
||||||
}
|
}
|
||||||
|
@ -1197,10 +1197,6 @@ bool BitcodeReader::ParseModule(const std::string &ModuleID) {
|
|||||||
return Error("Invalid GC ID");
|
return Error("Invalid GC ID");
|
||||||
Func->setGC(GCTable[Record[8]-1].c_str());
|
Func->setGC(GCTable[Record[8]-1].c_str());
|
||||||
}
|
}
|
||||||
if (!isProto && Record.size() > 9 && Record[9]) {
|
|
||||||
Func->setNotes(Record[9]);
|
|
||||||
}
|
|
||||||
|
|
||||||
ValueList.push_back(Func);
|
ValueList.push_back(Func);
|
||||||
|
|
||||||
// If this is a function with a body, remember the prototype we are
|
// If this is a function with a body, remember the prototype we are
|
||||||
|
@ -412,7 +412,6 @@ static void WriteModuleInfo(const Module *M, const ValueEnumerator &VE,
|
|||||||
Vals.push_back(F->hasSection() ? SectionMap[F->getSection()] : 0);
|
Vals.push_back(F->hasSection() ? SectionMap[F->getSection()] : 0);
|
||||||
Vals.push_back(getEncodedVisibility(F));
|
Vals.push_back(getEncodedVisibility(F));
|
||||||
Vals.push_back(F->hasGC() ? GCMap[F->getGC()] : 0);
|
Vals.push_back(F->hasGC() ? GCMap[F->getGC()] : 0);
|
||||||
Vals.push_back(F->getNotes());
|
|
||||||
|
|
||||||
unsigned AbbrevToUse = 0;
|
unsigned AbbrevToUse = 0;
|
||||||
Stream.EmitRecord(bitc::MODULE_CODE_FUNCTION, Vals, AbbrevToUse);
|
Stream.EmitRecord(bitc::MODULE_CODE_FUNCTION, Vals, AbbrevToUse);
|
||||||
|
@ -160,7 +160,7 @@ void X86ATTAsmPrinter::emitFunctionHeader(const MachineFunction &MF) {
|
|||||||
SwitchToTextSection(SectionName.c_str());
|
SwitchToTextSection(SectionName.c_str());
|
||||||
|
|
||||||
unsigned FnAlign = OptimizeForSize ? 1 : 4;
|
unsigned FnAlign = OptimizeForSize ? 1 : 4;
|
||||||
if (F->hasNote(FN_NOTE_OptimizeForSize))
|
if (F->hasNote(ParamAttr::FN_NOTE_OptimizeForSize))
|
||||||
FnAlign = 1;
|
FnAlign = 1;
|
||||||
switch (F->getLinkage()) {
|
switch (F->getLinkage()) {
|
||||||
default: assert(0 && "Unknown linkage type!");
|
default: assert(0 && "Unknown linkage type!");
|
||||||
|
@ -147,7 +147,7 @@ bool X86IntelAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
|
|||||||
SwitchToTextSection(getSectionForFunction(*F).c_str(), F);
|
SwitchToTextSection(getSectionForFunction(*F).c_str(), F);
|
||||||
|
|
||||||
unsigned FnAlign = OptimizeForSize ? 1 : 4;
|
unsigned FnAlign = OptimizeForSize ? 1 : 4;
|
||||||
if (F->hasNote(FN_NOTE_OptimizeForSize))
|
if (F->hasNote(ParamAttr::FN_NOTE_OptimizeForSize))
|
||||||
FnAlign = 1;
|
FnAlign = 1;
|
||||||
switch (F->getLinkage()) {
|
switch (F->getLinkage()) {
|
||||||
default: assert(0 && "Unsupported linkage type!");
|
default: assert(0 && "Unsupported linkage type!");
|
||||||
|
@ -63,7 +63,7 @@ bool AlwaysInliner::doInitialization(CallGraph &CG) {
|
|||||||
|
|
||||||
for (Module::iterator I = M.begin(), E = M.end();
|
for (Module::iterator I = M.begin(), E = M.end();
|
||||||
I != E; ++I)
|
I != E; ++I)
|
||||||
if (!I->isDeclaration() && !I->hasNote(FN_NOTE_AlwaysInline))
|
if (!I->isDeclaration() && !I->hasNote(ParamAttr::FN_NOTE_AlwaysInline))
|
||||||
NeverInline.insert(I);
|
NeverInline.insert(I);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -65,7 +65,7 @@ bool SimpleInliner::doInitialization(CallGraph &CG) {
|
|||||||
|
|
||||||
for (Module::iterator I = M.begin(), E = M.end();
|
for (Module::iterator I = M.begin(), E = M.end();
|
||||||
I != E; ++I)
|
I != E; ++I)
|
||||||
if (I->hasNote(FN_NOTE_NoInline))
|
if (I->hasNote(ParamAttr::FN_NOTE_NoInline))
|
||||||
NeverInline.insert(I);
|
NeverInline.insert(I);
|
||||||
|
|
||||||
// Get llvm.noinline
|
// Get llvm.noinline
|
||||||
|
@ -141,7 +141,7 @@ bool Inliner::runOnSCC(const std::vector<CallGraphNode*> &SCC) {
|
|||||||
|
|
||||||
int CurrentThreshold = InlineThreshold;
|
int CurrentThreshold = InlineThreshold;
|
||||||
Function *Fn = CS.getCaller();
|
Function *Fn = CS.getCaller();
|
||||||
if (Fn && Fn->hasNote(FN_NOTE_OptimizeForSize)
|
if (Fn && Fn->hasNote(ParamAttr::FN_NOTE_OptimizeForSize)
|
||||||
&& InlineThreshold != 50) {
|
&& InlineThreshold != 50) {
|
||||||
CurrentThreshold = 50;
|
CurrentThreshold = 50;
|
||||||
}
|
}
|
||||||
|
@ -430,7 +430,7 @@ bool LoopUnswitch::UnswitchIfProfitable(Value *LoopCond, Constant *Val){
|
|||||||
Function *F = loopHeader->getParent();
|
Function *F = loopHeader->getParent();
|
||||||
|
|
||||||
// Do not unswitch if the function is optimized for size.
|
// Do not unswitch if the function is optimized for size.
|
||||||
if (F->hasNote(FN_NOTE_OptimizeForSize))
|
if (F->hasNote(ParamAttr::FN_NOTE_OptimizeForSize))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Check to see if it would be profitable to unswitch current loop.
|
// Check to see if it would be profitable to unswitch current loop.
|
||||||
|
@ -222,7 +222,7 @@ int InlineCostAnalyzer::getInlineCost(CallSite CS,
|
|||||||
if (CalleeFI.NeverInline)
|
if (CalleeFI.NeverInline)
|
||||||
return 2000000000;
|
return 2000000000;
|
||||||
|
|
||||||
if (Callee->hasNote(FN_NOTE_AlwaysInline))
|
if (Callee->hasNote(ParamAttr::FN_NOTE_AlwaysInline))
|
||||||
return -2000000000;
|
return -2000000000;
|
||||||
|
|
||||||
// Add to the inline quality for properties that make the call valuable to
|
// Add to the inline quality for properties that make the call valuable to
|
||||||
|
@ -1412,12 +1412,12 @@ void AssemblyWriter::printFunction(const Function *F) {
|
|||||||
} else {
|
} else {
|
||||||
|
|
||||||
bool insideNotes = false;
|
bool insideNotes = false;
|
||||||
if (F->hasNote(FN_NOTE_AlwaysInline)) {
|
if (F->hasNote(ParamAttr::FN_NOTE_AlwaysInline)) {
|
||||||
Out << "notes(";
|
Out << "notes(";
|
||||||
insideNotes = true;
|
insideNotes = true;
|
||||||
Out << "inline=always";
|
Out << "inline=always";
|
||||||
}
|
}
|
||||||
if (F->hasNote(FN_NOTE_NoInline)) {
|
if (F->hasNote(ParamAttr::FN_NOTE_NoInline)) {
|
||||||
if (insideNotes)
|
if (insideNotes)
|
||||||
Out << ",";
|
Out << ",";
|
||||||
else {
|
else {
|
||||||
@ -1426,7 +1426,7 @@ void AssemblyWriter::printFunction(const Function *F) {
|
|||||||
}
|
}
|
||||||
Out << "inline=never";
|
Out << "inline=never";
|
||||||
}
|
}
|
||||||
if (F->hasNote(FN_NOTE_OptimizeForSize)) {
|
if (F->hasNote(ParamAttr::FN_NOTE_OptimizeForSize)) {
|
||||||
if (insideNotes)
|
if (insideNotes)
|
||||||
Out << ",";
|
Out << ",";
|
||||||
else {
|
else {
|
||||||
|
@ -174,7 +174,6 @@ Function::Function(const FunctionType *Ty, LinkageTypes Linkage,
|
|||||||
if (unsigned IID = getIntrinsicID(true))
|
if (unsigned IID = getIntrinsicID(true))
|
||||||
setParamAttrs(Intrinsic::getParamAttrs(Intrinsic::ID(IID)));
|
setParamAttrs(Intrinsic::getParamAttrs(Intrinsic::ID(IID)));
|
||||||
|
|
||||||
Notes = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Function::~Function() {
|
Function::~Function() {
|
||||||
|
@ -186,6 +186,7 @@ const ParamAttrsWithIndex &PAListPtr::getSlot(unsigned Slot) const {
|
|||||||
|
|
||||||
/// getParamAttrs - The parameter attributes for the specified parameter are
|
/// getParamAttrs - The parameter attributes for the specified parameter are
|
||||||
/// returned. Parameters for the result are denoted with Idx = 0.
|
/// returned. Parameters for the result are denoted with Idx = 0.
|
||||||
|
/// Function notes are denoted with idx = ~0.
|
||||||
ParameterAttributes PAListPtr::getParamAttrs(unsigned Idx) const {
|
ParameterAttributes PAListPtr::getParamAttrs(unsigned Idx) const {
|
||||||
if (PAList == 0) return ParamAttr::None;
|
if (PAList == 0) return ParamAttr::None;
|
||||||
|
|
||||||
|
@ -477,6 +477,19 @@ void Verifier::VerifyFunctionAttrs(const FunctionType *FT,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool VerifyAttributeCount(const PAListPtr &Attrs, unsigned Params) {
|
||||||
|
if (Attrs.isEmpty())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
unsigned LastSlot = Attrs.getNumSlots() - 1;
|
||||||
|
unsigned LastIndex = Attrs.getSlot(LastSlot).Index;
|
||||||
|
if (LastIndex <= Params
|
||||||
|
|| (LastIndex == (unsigned)~0
|
||||||
|
&& (LastSlot == 0 || Attrs.getSlot(LastSlot - 1).Index <= Params)))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
// visitFunction - Verify that a function is ok.
|
// visitFunction - Verify that a function is ok.
|
||||||
//
|
//
|
||||||
void Verifier::visitFunction(Function &F) {
|
void Verifier::visitFunction(Function &F) {
|
||||||
@ -497,8 +510,7 @@ void Verifier::visitFunction(Function &F) {
|
|||||||
|
|
||||||
const PAListPtr &Attrs = F.getParamAttrs();
|
const PAListPtr &Attrs = F.getParamAttrs();
|
||||||
|
|
||||||
Assert1(Attrs.isEmpty() ||
|
Assert1(VerifyAttributeCount(Attrs, FT->getNumParams()),
|
||||||
Attrs.getSlot(Attrs.getNumSlots()-1).Index <= FT->getNumParams(),
|
|
||||||
"Attributes after last parameter!", &F);
|
"Attributes after last parameter!", &F);
|
||||||
|
|
||||||
// Check function attributes.
|
// Check function attributes.
|
||||||
@ -955,8 +967,7 @@ void Verifier::VerifyCallSite(CallSite CS) {
|
|||||||
|
|
||||||
const PAListPtr &Attrs = CS.getParamAttrs();
|
const PAListPtr &Attrs = CS.getParamAttrs();
|
||||||
|
|
||||||
Assert1(Attrs.isEmpty() ||
|
Assert1(VerifyAttributeCount(Attrs, CS.arg_size()),
|
||||||
Attrs.getSlot(Attrs.getNumSlots()-1).Index <= CS.arg_size(),
|
|
||||||
"Attributes after last parameter!", I);
|
"Attributes after last parameter!", I);
|
||||||
|
|
||||||
// Verify call attributes.
|
// Verify call attributes.
|
||||||
|
Loading…
Reference in New Issue
Block a user