From f385f4ca1c7c3975779400dc2acf494878a8d6d4 Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Mon, 8 Oct 2012 23:27:46 +0000 Subject: [PATCH] Use the Attributes::Builder to build the attributes in the parser. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@165458 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Attributes.h | 50 +++++++++++++++++++++++++++++++++++++- lib/AsmParser/LLParser.cpp | 40 +++++++++++++++--------------- lib/AsmParser/LLParser.h | 2 +- lib/VMCore/Attributes.cpp | 22 +++++++++++++++++ 4 files changed, 92 insertions(+), 22 deletions(-) diff --git a/include/llvm/Attributes.h b/include/llvm/Attributes.h index 07e2154aa36..c3198a555fd 100644 --- a/include/llvm/Attributes.h +++ b/include/llvm/Attributes.h @@ -144,12 +144,50 @@ class AttributesImpl; class Attributes { // Currently, we need less than 64 bits. AttributesImpl Attrs; - +#if 0 + enum Attribute { + None = 0, ///< No attributes have been set + ZExt = 1 << 0, ///< Zero extended before/after call + SExt = 1 << 1, ///< Sign extended before/after call + NoReturn = 1 << 2, ///< Mark the function as not returning + InReg = 1 << 3, ///< Force argument to be passed in register + StructRet = 1 << 4, ///< Hidden pointer to structure to return + NoUnwind = 1 << 5, ///< Function doesn't unwind stack + NoAlias = 1 << 6, ///< Considered to not alias after call + ByVal = 1 << 7, ///< Pass structure by value + Nest = 1 << 8, ///< Nested function static chain + ReadNone = 1 << 9, ///< Function does not access memory + ReadOnly = 1 << 10, ///< Function only reads from memory + NoInline = 1 << 11, ///< inline=never + AlwaysInline = 1 << 12, ///< inline=always + OptimizeForSize = 1 << 13, ///< opt_size + StackProtect = 1 << 14, ///< Stack protection. + StackProtectReq = 1 << 15, ///< Stack protection required. + Alignment = 31 << 16, ///< Alignment of parameter (5 bits) + ///< stored as log2 of alignment with +1 bias + ///< 0 means unaligned different from align 1 + NoCapture = 1 << 21, ///< Function creates no aliases of pointer + NoRedZone = 1 << 22, ///< Disable redzone + NoImplicitFloat = 1 << 23, ///< Disable implicit floating point insts + Naked = 1 << 24, ///< Naked function + InlineHint = 1 << 25, ///< Source said inlining was desirable + StackAlignment = 7 << 26, ///< Alignment of stack for function (3 bits) + ///< stored as log2 of alignment with +1 bias 0 + ///< means unaligned (different from + ///< alignstack={1)) + ReturnsTwice = 1 << 29, ///< Function can return twice + UWTable = 1 << 30, ///< Function must be in a unwind table + NonLazyBind = 1U << 31, ///< Function is called early and/or + ///< often, so lazy binding isn't worthwhile + AddressSafety = 1ULL << 32 ///< Address safety checking is on. + }; +#endif explicit Attributes(AttributesImpl *A); public: Attributes() : Attrs(0) {} explicit Attributes(uint64_t Val); /*implicit*/ Attributes(Attribute::AttrConst Val); + Attributes(const Attributes &A); class Builder { friend class Attributes; @@ -158,6 +196,13 @@ public: Builder() : Bits(0) {} Builder(const Attributes &A) : Bits(A.Raw()) {} + void clear() { Bits = 0; } + + bool hasAttributes() const; + bool hasAlignmentAttr() const; + + uint64_t getAlignment() const; + void addAddressSafetyAttr(); void addAlwaysInlineAttr(); void addByValAttr(); @@ -212,6 +257,9 @@ public: void removeStructRetAttr(); void removeUWTableAttr(); void removeZExtAttr(); + + void removeAlignmentAttr(); + void removeStackAlignmentAttr(); }; /// get - Return a uniquified Attributes object. This takes the uniquified diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp index fea41793304..048afae9f10 100644 --- a/lib/AsmParser/LLParser.cpp +++ b/lib/AsmParser/LLParser.cpp @@ -916,16 +916,16 @@ bool LLParser::ParseOptionalAddrSpace(unsigned &AddrSpace) { /// ParseOptionalAttrs - Parse a potentially empty attribute list. AttrKind /// indicates what kind of attribute list this is: 0: function arg, 1: result, /// 2: function attr. -bool LLParser::ParseOptionalAttrs(Attributes &Attrs, unsigned AttrKind) { - Attributes::Builder B; +bool LLParser::ParseOptionalAttrs(Attributes::Builder &B, unsigned AttrKind) { LocTy AttrLoc = Lex.getLoc(); bool HaveError = false; + B.clear(); + while (1) { lltok::Kind Token = Lex.getKind(); switch (Token) { default: // End of attributes. - Attrs = Attributes::get(B); // FIXME: Use the other version of get(). return HaveError; case lltok::kw_zeroext: B.addZExtAttr(); break; case lltok::kw_signext: B.addSExtAttr(); break; @@ -1435,7 +1435,7 @@ bool LLParser::ParseParameterList(SmallVectorImpl &ArgList, // Parse the argument. LocTy ArgLoc; Type *ArgTy = 0; - Attributes ArgAttrs; + Attributes::Builder ArgAttrs; Value *V; if (ParseType(ArgTy, ArgLoc)) return true; @@ -1443,7 +1443,7 @@ bool LLParser::ParseParameterList(SmallVectorImpl &ArgList, // Otherwise, handle normal operands. if (ParseOptionalAttrs(ArgAttrs, 0) || ParseValue(ArgTy, V, PFS)) return true; - ArgList.push_back(ParamInfo(ArgLoc, V, ArgAttrs)); + ArgList.push_back(ParamInfo(ArgLoc, V, Attributes::get(ArgAttrs))); } Lex.Lex(); // Lex the ')'. @@ -1475,7 +1475,7 @@ bool LLParser::ParseArgumentList(SmallVectorImpl &ArgList, } else { LocTy TypeLoc = Lex.getLoc(); Type *ArgTy = 0; - Attributes Attrs; + Attributes::Builder Attrs; std::string Name; if (ParseType(ArgTy) || @@ -1492,7 +1492,7 @@ bool LLParser::ParseArgumentList(SmallVectorImpl &ArgList, if (!FunctionType::isValidArgumentType(ArgTy)) return Error(TypeLoc, "invalid type for function argument"); - ArgList.push_back(ArgInfo(TypeLoc, ArgTy, Attrs, Name)); + ArgList.push_back(ArgInfo(TypeLoc, ArgTy, Attributes::get(Attrs), Name)); while (EatIfPresent(lltok::comma)) { // Handle ... at end of arg list. @@ -1518,7 +1518,7 @@ bool LLParser::ParseArgumentList(SmallVectorImpl &ArgList, if (!ArgTy->isFirstClassType()) return Error(TypeLoc, "invalid type for function argument"); - ArgList.push_back(ArgInfo(TypeLoc, ArgTy, Attrs, Name)); + ArgList.push_back(ArgInfo(TypeLoc, ArgTy, Attributes::get(Attrs), Name)); } } @@ -2672,7 +2672,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { unsigned Linkage; unsigned Visibility; - Attributes RetAttrs; + Attributes::Builder RetAttrs; CallingConv::ID CC; Type *RetType = 0; LocTy RetTypeLoc = Lex.getLoc(); @@ -2736,7 +2736,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { SmallVector ArgList; bool isVarArg; - Attributes FuncAttrs; + Attributes::Builder FuncAttrs; std::string Section; unsigned Alignment; std::string GC; @@ -2755,9 +2755,9 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { return true; // If the alignment was parsed as an attribute, move to the alignment field. - if (FuncAttrs & Attribute::Alignment) { + if (FuncAttrs.hasAlignmentAttr()) { Alignment = FuncAttrs.getAlignment(); - FuncAttrs &= ~Attribute::Alignment; + FuncAttrs.removeAlignmentAttr(); } // Okay, if we got here, the function is syntactically valid. Convert types @@ -2766,7 +2766,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { SmallVector Attrs; if (RetAttrs.hasAttributes()) - Attrs.push_back(AttributeWithIndex::get(0, RetAttrs)); + Attrs.push_back(AttributeWithIndex::get(0, Attributes::get(RetAttrs))); for (unsigned i = 0, e = ArgList.size(); i != e; ++i) { ParamTypeList.push_back(ArgList[i].Ty); @@ -2775,7 +2775,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { } if (FuncAttrs.hasAttributes()) - Attrs.push_back(AttributeWithIndex::get(~0, FuncAttrs)); + Attrs.push_back(AttributeWithIndex::get(~0, Attributes::get(FuncAttrs))); AttrListPtr PAL = AttrListPtr::get(Attrs); @@ -3247,7 +3247,7 @@ bool LLParser::ParseIndirectBr(Instruction *&Inst, PerFunctionState &PFS) { /// OptionalAttrs 'to' TypeAndValue 'unwind' TypeAndValue bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) { LocTy CallLoc = Lex.getLoc(); - Attributes RetAttrs, FnAttrs; + Attributes::Builder RetAttrs, FnAttrs; CallingConv::ID CC; Type *RetType = 0; LocTy RetTypeLoc; @@ -3293,7 +3293,7 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) { // Set up the Attributes for the function. SmallVector Attrs; if (RetAttrs.hasAttributes()) - Attrs.push_back(AttributeWithIndex::get(0, RetAttrs)); + Attrs.push_back(AttributeWithIndex::get(0, Attributes::get(RetAttrs))); SmallVector Args; @@ -3321,7 +3321,7 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) { return Error(CallLoc, "not enough parameters specified for call"); if (FnAttrs.hasAttributes()) - Attrs.push_back(AttributeWithIndex::get(~0, FnAttrs)); + Attrs.push_back(AttributeWithIndex::get(~0, Attributes::get(FnAttrs))); // Finish off the Attributes and check them AttrListPtr PAL = AttrListPtr::get(Attrs); @@ -3646,7 +3646,7 @@ bool LLParser::ParseLandingPad(Instruction *&Inst, PerFunctionState &PFS) { /// ParameterList OptionalAttrs bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS, bool isTail) { - Attributes RetAttrs, FnAttrs; + Attributes::Builder RetAttrs, FnAttrs; CallingConv::ID CC; Type *RetType = 0; LocTy RetTypeLoc; @@ -3689,7 +3689,7 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS, // Set up the Attributes for the function. SmallVector Attrs; if (RetAttrs.hasAttributes()) - Attrs.push_back(AttributeWithIndex::get(0, RetAttrs)); + Attrs.push_back(AttributeWithIndex::get(0, Attributes::get(RetAttrs))); SmallVector Args; @@ -3717,7 +3717,7 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS, return Error(CallLoc, "not enough parameters specified for call"); if (FnAttrs.hasAttributes()) - Attrs.push_back(AttributeWithIndex::get(~0, FnAttrs)); + Attrs.push_back(AttributeWithIndex::get(~0, Attributes::get(FnAttrs))); // Finish off the Attributes and check them AttrListPtr PAL = AttrListPtr::get(Attrs); diff --git a/lib/AsmParser/LLParser.h b/lib/AsmParser/LLParser.h index 257c726229e..671eaf64291 100644 --- a/lib/AsmParser/LLParser.h +++ b/lib/AsmParser/LLParser.h @@ -175,7 +175,7 @@ namespace llvm { bool ParseTLSModel(GlobalVariable::ThreadLocalMode &TLM); bool ParseOptionalThreadLocal(GlobalVariable::ThreadLocalMode &TLM); bool ParseOptionalAddrSpace(unsigned &AddrSpace); - bool ParseOptionalAttrs(Attributes &Attrs, unsigned AttrKind); + bool ParseOptionalAttrs(Attributes::Builder &Attrs, unsigned AttrKind); bool ParseOptionalLinkage(unsigned &Linkage, bool &HasLinkage); bool ParseOptionalLinkage(unsigned &Linkage) { bool HasLinkage; return ParseOptionalLinkage(Linkage, HasLinkage); diff --git a/lib/VMCore/Attributes.cpp b/lib/VMCore/Attributes.cpp index 1fcebdf5ba2..6905e4df39c 100644 --- a/lib/VMCore/Attributes.cpp +++ b/lib/VMCore/Attributes.cpp @@ -33,6 +33,8 @@ Attributes::Attributes(Attribute::AttrConst Val) : Attrs(Val.v) {} Attributes::Attributes(AttributesImpl *A) : Attrs(A->Bits) {} +Attributes::Attributes(const Attributes &A) : Attrs(A.Attrs) {} + // FIXME: This is temporary until we have implemented the uniquified version of // AttributesImpl. Attributes Attributes::get(Attributes::Builder &B) { @@ -451,6 +453,26 @@ void Attributes::Builder::removeZExtAttr() { Bits &= ~Attribute::ZExt_i; } +void Attributes::Builder::removeAlignmentAttr() { + Bits &= ~Attribute::Alignment_i; +} +void Attributes::Builder::removeStackAlignmentAttr() { + Bits &= ~Attribute::StackAlignment_i; +} + +bool Attributes::Builder::hasAttributes() const { + return Bits != 0; +} +bool Attributes::Builder::hasAlignmentAttr() const { + return Bits & Attribute::Alignment_i; +} + +uint64_t Attributes::Builder::getAlignment() const { + if (!hasAlignmentAttr()) + return 0; + return 1U << (((Bits & Attribute::Alignment_i) >> 16) - 1); +} + //===----------------------------------------------------------------------===// // AttributeImpl Definition //===----------------------------------------------------------------------===//