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:
Devang Patel 2008-09-23 22:35:17 +00:00
parent b2c3e3fdd9
commit d9b4a5f859
18 changed files with 66 additions and 55 deletions

View File

@ -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.

View File

@ -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;

View File

@ -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;

View File

@ -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;
} }

View File

@ -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;
} }

View File

@ -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

View File

@ -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);

View File

@ -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!");

View File

@ -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!");

View File

@ -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;

View File

@ -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

View File

@ -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;
} }

View File

@ -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.

View File

@ -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

View File

@ -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 {

View File

@ -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() {

View File

@ -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;

View File

@ -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.