From d9b4a5f859188cbb168c223071b413e58c53c925 Mon Sep 17 00:00:00 2001 From: Devang Patel Date: Tue, 23 Sep 2008 22:35:17 +0000 Subject: [PATCH] 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 --- include/llvm/Function.h | 20 ++++++----------- include/llvm/ParameterAttributes.h | 7 ++++++ lib/AsmParser/llvmAsmParser.h.cvs | 4 ++-- lib/AsmParser/llvmAsmParser.y | 22 ++++++++++--------- lib/AsmParser/llvmAsmParser.y.cvs | 22 ++++++++++--------- lib/Bitcode/Reader/BitcodeReader.cpp | 4 ---- lib/Bitcode/Writer/BitcodeWriter.cpp | 1 - .../X86/AsmPrinter/X86ATTAsmPrinter.cpp | 2 +- .../X86/AsmPrinter/X86IntelAsmPrinter.cpp | 2 +- lib/Transforms/IPO/InlineAlways.cpp | 2 +- lib/Transforms/IPO/InlineSimple.cpp | 2 +- lib/Transforms/IPO/Inliner.cpp | 2 +- lib/Transforms/Scalar/LoopUnswitch.cpp | 2 +- lib/Transforms/Utils/InlineCost.cpp | 2 +- lib/VMCore/AsmWriter.cpp | 6 ++--- lib/VMCore/Function.cpp | 1 - lib/VMCore/ParameterAttributes.cpp | 1 + lib/VMCore/Verifier.cpp | 19 ++++++++++++---- 18 files changed, 66 insertions(+), 55 deletions(-) diff --git a/include/llvm/Function.h b/include/llvm/Function.h index 3aef7c5da9c..fea9e0fc48b 100644 --- a/include/llvm/Function.h +++ b/include/llvm/Function.h @@ -51,12 +51,6 @@ template<> struct ilist_traits 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, public ilist_node { public: @@ -76,7 +70,6 @@ private: mutable ArgumentListType ArgumentList; ///< The formal arguments ValueSymbolTable *SymTab; ///< Symbol table of args/instructions PAListPtr ParamAttrs; ///< Parameter attributes - FunctionNotes Notes; ///< Function properties // The Calling Convention is stored in Value::SubclassData. /*unsigned CallingConvention;*/ @@ -155,18 +148,19 @@ public: /// 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. - bool hasNote(FunctionNotes N) const { - return (!isDeclaration() && (Notes & N)); + bool hasNote(ParameterAttributes N) const { + // Notes are stored at ~0 index in parameter attribute list + return (!isDeclaration() && paramHasAttr(~0, N)); } /// 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 /// to use during code generation. diff --git a/include/llvm/ParameterAttributes.h b/include/llvm/ParameterAttributes.h index 16f798ee2a4..848bb504294 100644 --- a/include/llvm/ParameterAttributes.h +++ b/include/llvm/ParameterAttributes.h @@ -46,6 +46,13 @@ const Attributes ReadNone = 1<<9; ///< Function does not access memory const Attributes ReadOnly = 1<<10; ///< Function only reads from memory const Attributes Alignment = 0xffff<<16; ///< Alignment of parameter (16 bits) // 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. const Attributes ParameterOnly = ByVal | Nest | StructRet; diff --git a/lib/AsmParser/llvmAsmParser.h.cvs b/lib/AsmParser/llvmAsmParser.h.cvs index 7275b9e0262..a45ec5254c0 100644 --- a/lib/AsmParser/llvmAsmParser.h.cvs +++ b/lib/AsmParser/llvmAsmParser.h.cvs @@ -366,7 +366,7 @@ #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED 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::Function *FunctionVal; @@ -395,7 +395,7 @@ typedef union YYSTYPE llvm::GlobalValue::LinkageTypes Linkage; llvm::GlobalValue::VisibilityTypes Visibility; llvm::ParameterAttributes ParamAttrs; - llvm::FunctionNotes FunctionNotes; + llvm::ParameterAttributes FunctionNotes; llvm::APInt *APIntVal; int64_t SInt64Val; uint64_t UInt64Val; diff --git a/lib/AsmParser/llvmAsmParser.y b/lib/AsmParser/llvmAsmParser.y index a298dde4342..5cfc47dc9d7 100644 --- a/lib/AsmParser/llvmAsmParser.y +++ b/lib/AsmParser/llvmAsmParser.y @@ -995,7 +995,7 @@ Module *llvm::RunVMAsmParser(llvm::MemoryBuffer *MB) { llvm::GlobalValue::LinkageTypes Linkage; llvm::GlobalValue::VisibilityTypes Visibility; llvm::ParameterAttributes ParamAttrs; - llvm::FunctionNotes FunctionNotes; + llvm::ParameterAttributes FunctionNotes; llvm::APInt *APIntVal; int64_t SInt64Val; uint64_t UInt64Val; @@ -1091,8 +1091,8 @@ Module *llvm::RunVMAsmParser(llvm::MemoryBuffer *MB) { %type OptCallingConv LocalNumber %type OptParamAttrs ParamAttr %type OptFuncAttrs FuncAttr -%type OptFuncNotes FuncNote -%type FuncNoteList +%type OptFuncNotes FuncNote +%type FuncNoteList // Basic Block Terminating Operators %token RET BR SWITCH INVOKE UNWIND UNREACHABLE @@ -1297,22 +1297,24 @@ OptFuncAttrs : /* empty */ { $$ = ParamAttr::None; } FuncNoteList : FuncNote { $$ = $1; } | FuncNoteList ',' FuncNote { - FunctionNotes tmp = $1 | $3; - if ($3 == FN_NOTE_NoInline && ($1 & FN_NOTE_AlwaysInline)) + unsigned tmp = $1 | $3; + if ($3 == ParamAttr::FN_NOTE_NoInline + && ($1 & ParamAttr::FN_NOTE_AlwaysInline)) 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!") $$ = tmp; CHECK_FOR_ERROR } ; -FuncNote : INLINE '=' NEVER { $$ = FN_NOTE_NoInline; } - | INLINE '=' ALWAYS { $$ = FN_NOTE_AlwaysInline; } - | OPTIMIZEFORSIZE { $$ = FN_NOTE_OptimizeForSize; } +FuncNote : INLINE '=' NEVER { $$ = ParamAttr::FN_NOTE_NoInline; } + | INLINE '=' ALWAYS { $$ = ParamAttr::FN_NOTE_AlwaysInline; } + | OPTIMIZEFORSIZE { $$ = ParamAttr::FN_NOTE_OptimizeForSize; } ; -OptFuncNotes : /* empty */ { $$ = FN_NOTE_None; } +OptFuncNotes : /* empty */ { $$ = ParamAttr::FN_NOTE_None; } | FNNOTE '(' FuncNoteList ')' { $$ = $3; } diff --git a/lib/AsmParser/llvmAsmParser.y.cvs b/lib/AsmParser/llvmAsmParser.y.cvs index a298dde4342..5cfc47dc9d7 100644 --- a/lib/AsmParser/llvmAsmParser.y.cvs +++ b/lib/AsmParser/llvmAsmParser.y.cvs @@ -995,7 +995,7 @@ Module *llvm::RunVMAsmParser(llvm::MemoryBuffer *MB) { llvm::GlobalValue::LinkageTypes Linkage; llvm::GlobalValue::VisibilityTypes Visibility; llvm::ParameterAttributes ParamAttrs; - llvm::FunctionNotes FunctionNotes; + llvm::ParameterAttributes FunctionNotes; llvm::APInt *APIntVal; int64_t SInt64Val; uint64_t UInt64Val; @@ -1091,8 +1091,8 @@ Module *llvm::RunVMAsmParser(llvm::MemoryBuffer *MB) { %type OptCallingConv LocalNumber %type OptParamAttrs ParamAttr %type OptFuncAttrs FuncAttr -%type OptFuncNotes FuncNote -%type FuncNoteList +%type OptFuncNotes FuncNote +%type FuncNoteList // Basic Block Terminating Operators %token RET BR SWITCH INVOKE UNWIND UNREACHABLE @@ -1297,22 +1297,24 @@ OptFuncAttrs : /* empty */ { $$ = ParamAttr::None; } FuncNoteList : FuncNote { $$ = $1; } | FuncNoteList ',' FuncNote { - FunctionNotes tmp = $1 | $3; - if ($3 == FN_NOTE_NoInline && ($1 & FN_NOTE_AlwaysInline)) + unsigned tmp = $1 | $3; + if ($3 == ParamAttr::FN_NOTE_NoInline + && ($1 & ParamAttr::FN_NOTE_AlwaysInline)) 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!") $$ = tmp; CHECK_FOR_ERROR } ; -FuncNote : INLINE '=' NEVER { $$ = FN_NOTE_NoInline; } - | INLINE '=' ALWAYS { $$ = FN_NOTE_AlwaysInline; } - | OPTIMIZEFORSIZE { $$ = FN_NOTE_OptimizeForSize; } +FuncNote : INLINE '=' NEVER { $$ = ParamAttr::FN_NOTE_NoInline; } + | INLINE '=' ALWAYS { $$ = ParamAttr::FN_NOTE_AlwaysInline; } + | OPTIMIZEFORSIZE { $$ = ParamAttr::FN_NOTE_OptimizeForSize; } ; -OptFuncNotes : /* empty */ { $$ = FN_NOTE_None; } +OptFuncNotes : /* empty */ { $$ = ParamAttr::FN_NOTE_None; } | FNNOTE '(' FuncNoteList ')' { $$ = $3; } diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index 975075c60e5..cfe2ba95441 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -1197,10 +1197,6 @@ bool BitcodeReader::ParseModule(const std::string &ModuleID) { return Error("Invalid GC ID"); Func->setGC(GCTable[Record[8]-1].c_str()); } - if (!isProto && Record.size() > 9 && Record[9]) { - Func->setNotes(Record[9]); - } - ValueList.push_back(Func); // If this is a function with a body, remember the prototype we are diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp index c647828eeb4..931e944a410 100644 --- a/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -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(getEncodedVisibility(F)); Vals.push_back(F->hasGC() ? GCMap[F->getGC()] : 0); - Vals.push_back(F->getNotes()); unsigned AbbrevToUse = 0; Stream.EmitRecord(bitc::MODULE_CODE_FUNCTION, Vals, AbbrevToUse); diff --git a/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp b/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp index aae38a04238..a783bd279aa 100644 --- a/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp +++ b/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp @@ -160,7 +160,7 @@ void X86ATTAsmPrinter::emitFunctionHeader(const MachineFunction &MF) { SwitchToTextSection(SectionName.c_str()); unsigned FnAlign = OptimizeForSize ? 1 : 4; - if (F->hasNote(FN_NOTE_OptimizeForSize)) + if (F->hasNote(ParamAttr::FN_NOTE_OptimizeForSize)) FnAlign = 1; switch (F->getLinkage()) { default: assert(0 && "Unknown linkage type!"); diff --git a/lib/Target/X86/AsmPrinter/X86IntelAsmPrinter.cpp b/lib/Target/X86/AsmPrinter/X86IntelAsmPrinter.cpp index 12a083aa74e..559e9ebd5b3 100644 --- a/lib/Target/X86/AsmPrinter/X86IntelAsmPrinter.cpp +++ b/lib/Target/X86/AsmPrinter/X86IntelAsmPrinter.cpp @@ -147,7 +147,7 @@ bool X86IntelAsmPrinter::runOnMachineFunction(MachineFunction &MF) { SwitchToTextSection(getSectionForFunction(*F).c_str(), F); unsigned FnAlign = OptimizeForSize ? 1 : 4; - if (F->hasNote(FN_NOTE_OptimizeForSize)) + if (F->hasNote(ParamAttr::FN_NOTE_OptimizeForSize)) FnAlign = 1; switch (F->getLinkage()) { default: assert(0 && "Unsupported linkage type!"); diff --git a/lib/Transforms/IPO/InlineAlways.cpp b/lib/Transforms/IPO/InlineAlways.cpp index ddcc79cf59b..4793a17b842 100644 --- a/lib/Transforms/IPO/InlineAlways.cpp +++ b/lib/Transforms/IPO/InlineAlways.cpp @@ -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(FN_NOTE_AlwaysInline)) + if (!I->isDeclaration() && !I->hasNote(ParamAttr::FN_NOTE_AlwaysInline)) NeverInline.insert(I); return false; diff --git a/lib/Transforms/IPO/InlineSimple.cpp b/lib/Transforms/IPO/InlineSimple.cpp index 6fb695dc18e..6db4c908b77 100644 --- a/lib/Transforms/IPO/InlineSimple.cpp +++ b/lib/Transforms/IPO/InlineSimple.cpp @@ -65,7 +65,7 @@ bool SimpleInliner::doInitialization(CallGraph &CG) { for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) - if (I->hasNote(FN_NOTE_NoInline)) + if (I->hasNote(ParamAttr::FN_NOTE_NoInline)) NeverInline.insert(I); // Get llvm.noinline diff --git a/lib/Transforms/IPO/Inliner.cpp b/lib/Transforms/IPO/Inliner.cpp index 447bd6fb7d3..2af5a7264df 100644 --- a/lib/Transforms/IPO/Inliner.cpp +++ b/lib/Transforms/IPO/Inliner.cpp @@ -141,7 +141,7 @@ bool Inliner::runOnSCC(const std::vector &SCC) { int CurrentThreshold = InlineThreshold; Function *Fn = CS.getCaller(); - if (Fn && Fn->hasNote(FN_NOTE_OptimizeForSize) + if (Fn && Fn->hasNote(ParamAttr::FN_NOTE_OptimizeForSize) && InlineThreshold != 50) { CurrentThreshold = 50; } diff --git a/lib/Transforms/Scalar/LoopUnswitch.cpp b/lib/Transforms/Scalar/LoopUnswitch.cpp index aa9158ed502..178bf783971 100644 --- a/lib/Transforms/Scalar/LoopUnswitch.cpp +++ b/lib/Transforms/Scalar/LoopUnswitch.cpp @@ -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->hasNote(FN_NOTE_OptimizeForSize)) + if (F->hasNote(ParamAttr::FN_NOTE_OptimizeForSize)) return false; // Check to see if it would be profitable to unswitch current loop. diff --git a/lib/Transforms/Utils/InlineCost.cpp b/lib/Transforms/Utils/InlineCost.cpp index 2a39158d24e..eb825287be6 100644 --- a/lib/Transforms/Utils/InlineCost.cpp +++ b/lib/Transforms/Utils/InlineCost.cpp @@ -222,7 +222,7 @@ int InlineCostAnalyzer::getInlineCost(CallSite CS, if (CalleeFI.NeverInline) return 2000000000; - if (Callee->hasNote(FN_NOTE_AlwaysInline)) + if (Callee->hasNote(ParamAttr::FN_NOTE_AlwaysInline)) return -2000000000; // Add to the inline quality for properties that make the call valuable to diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp index ab8b59bc275..32c468b4809 100644 --- a/lib/VMCore/AsmWriter.cpp +++ b/lib/VMCore/AsmWriter.cpp @@ -1412,12 +1412,12 @@ void AssemblyWriter::printFunction(const Function *F) { } else { bool insideNotes = false; - if (F->hasNote(FN_NOTE_AlwaysInline)) { + if (F->hasNote(ParamAttr::FN_NOTE_AlwaysInline)) { Out << "notes("; insideNotes = true; Out << "inline=always"; } - if (F->hasNote(FN_NOTE_NoInline)) { + if (F->hasNote(ParamAttr::FN_NOTE_NoInline)) { if (insideNotes) Out << ","; else { @@ -1426,7 +1426,7 @@ void AssemblyWriter::printFunction(const Function *F) { } Out << "inline=never"; } - if (F->hasNote(FN_NOTE_OptimizeForSize)) { + if (F->hasNote(ParamAttr::FN_NOTE_OptimizeForSize)) { if (insideNotes) Out << ","; else { diff --git a/lib/VMCore/Function.cpp b/lib/VMCore/Function.cpp index c1546a8e53f..93e39df8307 100644 --- a/lib/VMCore/Function.cpp +++ b/lib/VMCore/Function.cpp @@ -174,7 +174,6 @@ Function::Function(const FunctionType *Ty, LinkageTypes Linkage, if (unsigned IID = getIntrinsicID(true)) setParamAttrs(Intrinsic::getParamAttrs(Intrinsic::ID(IID))); - Notes = 0; } Function::~Function() { diff --git a/lib/VMCore/ParameterAttributes.cpp b/lib/VMCore/ParameterAttributes.cpp index d16f54de23a..f1a38c4a91a 100644 --- a/lib/VMCore/ParameterAttributes.cpp +++ b/lib/VMCore/ParameterAttributes.cpp @@ -186,6 +186,7 @@ const ParamAttrsWithIndex &PAListPtr::getSlot(unsigned Slot) const { /// getParamAttrs - The parameter attributes for the specified parameter are /// returned. Parameters for the result are denoted with Idx = 0. +/// Function notes are denoted with idx = ~0. ParameterAttributes PAListPtr::getParamAttrs(unsigned Idx) const { if (PAList == 0) return ParamAttr::None; diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp index be053aba944..f4a59c25242 100644 --- a/lib/VMCore/Verifier.cpp +++ b/lib/VMCore/Verifier.cpp @@ -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. // void Verifier::visitFunction(Function &F) { @@ -497,8 +510,7 @@ void Verifier::visitFunction(Function &F) { const PAListPtr &Attrs = F.getParamAttrs(); - Assert1(Attrs.isEmpty() || - Attrs.getSlot(Attrs.getNumSlots()-1).Index <= FT->getNumParams(), + Assert1(VerifyAttributeCount(Attrs, FT->getNumParams()), "Attributes after last parameter!", &F); // Check function attributes. @@ -955,8 +967,7 @@ void Verifier::VerifyCallSite(CallSite CS) { const PAListPtr &Attrs = CS.getParamAttrs(); - Assert1(Attrs.isEmpty() || - Attrs.getSlot(Attrs.getNumSlots()-1).Index <= CS.arg_size(), + Assert1(VerifyAttributeCount(Attrs, CS.arg_size()), "Attributes after last parameter!", I); // Verify call attributes.