X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FAttributes.h;h=ed18ca4c403ea42b42a6ef997108a19c6d2c8e84;hb=b09c146b116359616f6cbd4c8b3328607e00ff42;hp=08cfb86898c9e45305876f7702ca3638387da64b;hpb=c416795feaaa2052f7b46fa7a3f9b6ec3751b1eb;p=oota-llvm.git diff --git a/include/llvm/Attributes.h b/include/llvm/Attributes.h index 08cfb86898c..ed18ca4c403 100644 --- a/include/llvm/Attributes.h +++ b/include/llvm/Attributes.h @@ -15,21 +15,18 @@ #ifndef LLVM_ATTRIBUTES_H #define LLVM_ATTRIBUTES_H -#include "llvm/AttributesImpl.h" -#include "llvm/Support/MathExtras.h" #include "llvm/ADT/ArrayRef.h" +#include "llvm/Support/MathExtras.h" #include #include namespace llvm { +class AttrBuilder; +class AttributesImpl; class LLVMContext; class Type; -/// AttributeImpl - The internal representation of the Attributes class. This is -/// uniquified. -class AttributesImpl; - /// Attributes - A bitset of attributes. class Attributes { public: @@ -37,15 +34,15 @@ public: /// should be treated by optimizations and code generation. This enumeration /// lists the attributes that can be associated with parameters, function /// results or the function itself. - /// + /// /// Note that uwtable is about the ABI or the user mandating an entry in the /// unwind table. The nounwind attribute is about an exception passing by the /// function. - /// + /// /// In a theoretical system that uses tables for profiling and sjlj for /// exceptions, they would be fully independent. In a normal system that uses /// tables for both, the semantics are: - /// + /// /// nil = Needs an entry because an exception might pass by. /// nounwind = No need for an entry /// uwtable = Needs an entry because the ABI says so and because @@ -53,129 +50,59 @@ public: /// uwtable + nounwind = Needs an entry because the ABI says so. enum AttrVal { - None = 0, ///< No attributes have been set - AddressSafety = 1, ///< Address safety checking is on. - Alignment = 2, ///< Alignment of parameter (5 bits) + // IR-Level Attributes + None, ///< No attributes have been set + AddressSafety, ///< Address safety checking is on. + Alignment, ///< Alignment of parameter (5 bits) ///< stored as log2 of alignment with +1 bias ///< 0 means unaligned different from align 1 - AlwaysInline = 3, ///< inline=always - ByVal = 4, ///< Pass structure by value - InlineHint = 5, ///< Source said inlining was desirable - InReg = 6, ///< Force argument to be passed in register - Naked = 7, ///< Naked function - Nest = 8, ///< Nested function static chain - NoAlias = 9, ///< Considered to not alias after call - NoCapture = 10, ///< Function creates no aliases of pointer - NoImplicitFloat = 11, ///< Disable implicit floating point insts - NoInline = 12, ///< inline=never - NonLazyBind = 13, ///< Function is called early and/or + AlwaysInline, ///< inline=always + ByVal, ///< Pass structure by value + InlineHint, ///< Source said inlining was desirable + InReg, ///< Force argument to be passed in register + MinSize, ///< Function must be optimized for size first + Naked, ///< Naked function + Nest, ///< Nested function static chain + NoAlias, ///< Considered to not alias after call + NoCapture, ///< Function creates no aliases of pointer + NoImplicitFloat, ///< Disable implicit floating point insts + NoInline, ///< inline=never + NonLazyBind, ///< Function is called early and/or ///< often, so lazy binding isn't worthwhile - NoRedZone = 14, ///< Disable redzone - NoReturn = 15, ///< Mark the function as not returning - NoUnwind = 16, ///< Function doesn't unwind stack - OptimizeForSize = 17, ///< opt_size - ReadNone = 18, ///< Function does not access memory - ReadOnly = 19, ///< Function only reads from memory - ReturnsTwice = 20, ///< Function can return twice - SExt = 21, ///< Sign extended before/after call - StackAlignment = 22, ///< Alignment of stack for function (3 bits) + NoRedZone, ///< Disable redzone + NoReturn, ///< Mark the function as not returning + NoUnwind, ///< Function doesn't unwind stack + OptimizeForSize, ///< opt_size + ReadNone, ///< Function does not access memory + ReadOnly, ///< Function only reads from memory + ReturnsTwice, ///< Function can return twice + SExt, ///< Sign extended before/after call + StackAlignment, ///< Alignment of stack for function (3 bits) ///< stored as log2 of alignment with +1 bias 0 ///< means unaligned (different from ///< alignstack={1)) - StackProtect = 23, ///< Stack protection. - StackProtectReq = 24, ///< Stack protection required. - StructRet = 25, ///< Hidden pointer to structure to return - UWTable = 26, ///< Function must be in a unwind table - ZExt = 27 ///< Zero extended before/after call + StackProtect, ///< Stack protection. + StackProtectReq, ///< Stack protection required. + StructRet, ///< Hidden pointer to structure to return + UWTable, ///< Function must be in a unwind table + ZExt ///< Zero extended before/after call }; private: - AttributesImpl Attrs; - - explicit Attributes(AttributesImpl *A); + AttributesImpl *Attrs; + Attributes(AttributesImpl *A) : Attrs(A) {} public: Attributes() : Attrs(0) {} - explicit Attributes(uint64_t Val); - explicit Attributes(LLVMContext &C, AttrVal Val); - Attributes(const Attributes &A); - - class Builder { - friend class Attributes; - uint64_t Bits; - public: - Builder() : Bits(0) {} - explicit Builder(uint64_t B) : Bits(B) {} - Builder(const Attributes &A) : Bits(A.Raw()) {} - - void clear() { Bits = 0; } - - bool hasAttribute(Attributes::AttrVal A) const; - bool hasAttributes() const; - bool hasAttributes(const Attributes &A) const; - bool hasAlignmentAttr() const; - - uint64_t getAlignment() const; - uint64_t getStackAlignment() const; - - Builder &addAttribute(Attributes::AttrVal Val); - Builder &removeAttribute(Attributes::AttrVal Val); - - /// addRawValue - Add the raw value to the internal representation. This - /// should be used ONLY for decoding bitcode! - Builder &addRawValue(uint64_t Val); - - /// addAlignmentAttr - This turns an int alignment (which must be a power of - /// 2) into the form used internally in Attributes. - Builder &addAlignmentAttr(unsigned Align); - - /// addStackAlignmentAttr - This turns an int stack alignment (which must be - /// a power of 2) into the form used internally in Attributes. - Builder &addStackAlignmentAttr(unsigned Align); - - Builder &addAttributes(const Attributes &A); - Builder &removeAttributes(const Attributes &A); - - /// @brief Remove attributes that are used on functions only. - void removeFunctionOnlyAttrs() { - removeAttribute(Attributes::NoReturn) - .removeAttribute(Attributes::NoUnwind) - .removeAttribute(Attributes::ReadNone) - .removeAttribute(Attributes::ReadOnly) - .removeAttribute(Attributes::NoInline) - .removeAttribute(Attributes::AlwaysInline) - .removeAttribute(Attributes::OptimizeForSize) - .removeAttribute(Attributes::StackProtect) - .removeAttribute(Attributes::StackProtectReq) - .removeAttribute(Attributes::NoRedZone) - .removeAttribute(Attributes::NoImplicitFloat) - .removeAttribute(Attributes::Naked) - .removeAttribute(Attributes::InlineHint) - .removeAttribute(Attributes::StackAlignment) - .removeAttribute(Attributes::UWTable) - .removeAttribute(Attributes::NonLazyBind) - .removeAttribute(Attributes::ReturnsTwice) - .removeAttribute(Attributes::AddressSafety); - } - - bool operator==(const Builder &B) { - return Bits == B.Bits; - } - bool operator!=(const Builder &B) { - return Bits != B.Bits; - } - }; /// get - Return a uniquified Attributes object. This takes the uniquified /// value from the Builder and wraps it in the Attributes class. - static Attributes get(Builder &B); - static Attributes get(LLVMContext &Context, Builder &B); + static Attributes get(LLVMContext &Context, ArrayRef Vals); + static Attributes get(LLVMContext &Context, AttrBuilder &B); /// @brief Return true if the attribute is present. bool hasAttribute(AttrVal Val) const; /// @brief Return true if attributes exist - bool hasAttributes() const { - return Attrs.hasAttributes(); - } + bool hasAttributes() const; /// @brief Return true if the attributes are a non-null intersection. bool hasAttributes(const Attributes &A) const; @@ -221,23 +148,17 @@ public: hasAttribute(Attributes::UWTable) || hasAttribute(Attributes::NonLazyBind) || hasAttribute(Attributes::ReturnsTwice) || - hasAttribute(Attributes::AddressSafety); + hasAttribute(Attributes::AddressSafety) || + hasAttribute(Attributes::MinSize); } - bool isEmptyOrSingleton() const; - - // This is a "safe bool() operator". - operator const void *() const { return Attrs.Bits ? this : 0; } - bool operator == (const Attributes &A) const { - return Attrs.Bits == A.Attrs.Bits; + bool operator==(const Attributes &A) const { + return Attrs == A.Attrs; } - bool operator != (const Attributes &A) const { - return Attrs.Bits != A.Attrs.Bits; + bool operator!=(const Attributes &A) const { + return Attrs != A.Attrs; } - Attributes operator & (const Attributes &A) const; - Attributes &operator &= (const Attributes &A); - uint64_t Raw() const; /// @brief Which attributes cannot be applied to a type. @@ -246,41 +167,14 @@ public: /// encodeLLVMAttributesForBitcode - This returns an integer containing an /// encoding of all the LLVM attributes found in the given attribute bitset. /// Any change to this encoding is a breaking change to bitcode compatibility. - static uint64_t encodeLLVMAttributesForBitcode(Attributes Attrs) { - // FIXME: It doesn't make sense to store the alignment information as an - // expanded out value, we should store it as a log2 value. However, we - // can't just change that here without breaking bitcode compatibility. If - // this ever becomes a problem in practice, we should introduce new tag - // numbers in the bitcode file and have those tags use a more efficiently - // encoded alignment field. - - // Store the alignment in the bitcode as a 16-bit raw value instead of a - // 5-bit log2 encoded value. Shift the bits above the alignment up by 11 - // bits. - uint64_t EncodedAttrs = Attrs.Raw() & 0xffff; - if (Attrs.hasAttribute(Attributes::Alignment)) - EncodedAttrs |= Attrs.getAlignment() << 16; - EncodedAttrs |= (Attrs.Raw() & (0xfffULL << 21)) << 11; - return EncodedAttrs; - } + static uint64_t encodeLLVMAttributesForBitcode(Attributes Attrs); /// decodeLLVMAttributesForBitcode - This returns an attribute bitset /// containing the LLVM attributes that have been decoded from the given /// integer. This function must stay in sync with /// 'encodeLLVMAttributesForBitcode'. - static Attributes decodeLLVMAttributesForBitcode(uint64_t EncodedAttrs) { - // The alignment is stored as a 16-bit raw value from bits 31--16. We shift - // the bits above 31 down by 11 bits. - unsigned Alignment = (EncodedAttrs & (0xffffULL << 16)) >> 16; - assert((!Alignment || isPowerOf2_32(Alignment)) && - "Alignment must be a power of two."); - - Attributes::Builder B(EncodedAttrs & 0xffff); - if (Alignment) - B.addAlignmentAttr(Alignment); - B.addRawValue((EncodedAttrs & (0xfffULL << 32)) >> 11); - return Attributes::get(B); - } + static Attributes decodeLLVMAttributesForBitcode(LLVMContext &C, + uint64_t EncodedAttrs); /// getAsString - The set of Attributes set in Attributes is converted to a /// string of equivalent mnemonics. This is, presumably, for writing out the @@ -289,6 +183,96 @@ public: std::string getAsString() const; }; +//===----------------------------------------------------------------------===// +/// AttrBuilder - This class is used in conjunction with the Attributes::get +/// method to create an Attributes object. The object itself is uniquified. The +/// Builder's value, however, is not. So this can be used as a quick way to test +/// for equality, presence of attributes, etc. +class AttrBuilder { + uint64_t Bits; +public: + AttrBuilder() : Bits(0) {} + explicit AttrBuilder(uint64_t B) : Bits(B) {} + AttrBuilder(const Attributes &A) : Bits(A.Raw()) {} + + void clear() { Bits = 0; } + + /// addAttribute - Add an attribute to the builder. + AttrBuilder &addAttribute(Attributes::AttrVal Val); + + /// removeAttribute - Remove an attribute from the builder. + AttrBuilder &removeAttribute(Attributes::AttrVal Val); + + /// addAttribute - Add the attributes from A to the builder. + AttrBuilder &addAttributes(const Attributes &A); + + /// removeAttribute - Remove the attributes from A from the builder. + AttrBuilder &removeAttributes(const Attributes &A); + + /// hasAttribute - Return true if the builder has the specified attribute. + bool hasAttribute(Attributes::AttrVal A) const; + + /// hasAttributes - Return true if the builder has IR-level attributes. + bool hasAttributes() const; + + /// hasAttributes - Return true if the builder has any attribute that's in the + /// specified attribute. + bool hasAttributes(const Attributes &A) const; + + /// hasAlignmentAttr - Return true if the builder has an alignment attribute. + bool hasAlignmentAttr() const; + + /// getAlignment - Retrieve the alignment attribute, if it exists. + uint64_t getAlignment() const; + + /// getStackAlignment - Retrieve the stack alignment attribute, if it exists. + uint64_t getStackAlignment() const; + + /// addAlignmentAttr - This turns an int alignment (which must be a power of + /// 2) into the form used internally in Attributes. + AttrBuilder &addAlignmentAttr(unsigned Align); + + /// addStackAlignmentAttr - This turns an int stack alignment (which must be a + /// power of 2) into the form used internally in Attributes. + AttrBuilder &addStackAlignmentAttr(unsigned Align); + + /// addRawValue - Add the raw value to the internal representation. + /// N.B. This should be used ONLY for decoding LLVM bitcode! + AttrBuilder &addRawValue(uint64_t Val); + + /// @brief Remove attributes that are used on functions only. + void removeFunctionOnlyAttrs() { + removeAttribute(Attributes::NoReturn) + .removeAttribute(Attributes::NoUnwind) + .removeAttribute(Attributes::ReadNone) + .removeAttribute(Attributes::ReadOnly) + .removeAttribute(Attributes::NoInline) + .removeAttribute(Attributes::AlwaysInline) + .removeAttribute(Attributes::OptimizeForSize) + .removeAttribute(Attributes::StackProtect) + .removeAttribute(Attributes::StackProtectReq) + .removeAttribute(Attributes::NoRedZone) + .removeAttribute(Attributes::NoImplicitFloat) + .removeAttribute(Attributes::Naked) + .removeAttribute(Attributes::InlineHint) + .removeAttribute(Attributes::StackAlignment) + .removeAttribute(Attributes::UWTable) + .removeAttribute(Attributes::NonLazyBind) + .removeAttribute(Attributes::ReturnsTwice) + .removeAttribute(Attributes::AddressSafety) + .removeAttribute(Attributes::MinSize); + } + + uint64_t Raw() const { return Bits; } + + bool operator==(const AttrBuilder &B) { + return Bits == B.Bits; + } + bool operator!=(const AttrBuilder &B) { + return Bits != B.Bits; + } +}; + //===----------------------------------------------------------------------===// // AttributeWithIndex //===----------------------------------------------------------------------===// @@ -301,18 +285,9 @@ struct AttributeWithIndex { ///< Index 0 is used for return value attributes. ///< Index ~0U is used for function attributes. - static AttributeWithIndex get(unsigned Idx, + static AttributeWithIndex get(LLVMContext &C, unsigned Idx, ArrayRef Attrs) { - Attributes::Builder B; - - for (ArrayRef::iterator I = Attrs.begin(), - E = Attrs.end(); I != E; ++I) - B.addAttribute(*I); - - AttributeWithIndex P; - P.Index = Idx; - P.Attrs = Attributes::get(B); - return P; + return get(Idx, Attributes::get(C, Attrs)); } static AttributeWithIndex get(unsigned Idx, Attributes Attrs) { AttributeWithIndex P; @@ -323,39 +298,50 @@ struct AttributeWithIndex { }; //===----------------------------------------------------------------------===// -// AttrListPtr Smart Pointer +// AttributeSet Smart Pointer //===----------------------------------------------------------------------===// class AttributeListImpl; -/// AttrListPtr - This class manages the ref count for the opaque +/// AttributeSet - This class manages the ref count for the opaque /// AttributeListImpl object and provides accessors for it. -class AttrListPtr { - /// AttrList - The attributes that we are managing. This can be null - /// to represent the empty attributes list. +class AttributeSet { +public: + enum AttrIndex { + ReturnIndex = 0U, + FunctionIndex = ~0U + }; +private: + /// @brief The attributes that we are managing. This can be null to represent + /// the empty attributes list. AttributeListImpl *AttrList; + + /// @brief The attributes for the specified index are returned. Attributes + /// for the result are denoted with Idx = 0. + Attributes getAttributes(unsigned Idx) const; + + explicit AttributeSet(AttributeListImpl *LI) : AttrList(LI) {} public: - AttrListPtr() : AttrList(0) {} - AttrListPtr(const AttrListPtr &P); - const AttrListPtr &operator=(const AttrListPtr &RHS); - ~AttrListPtr(); + AttributeSet() : AttrList(0) {} + AttributeSet(const AttributeSet &P) : AttrList(P.AttrList) {} + const AttributeSet &operator=(const AttributeSet &RHS); //===--------------------------------------------------------------------===// // Attribute List Construction and Mutation //===--------------------------------------------------------------------===// /// get - Return a Attributes list with the specified parameters in it. - static AttrListPtr get(ArrayRef Attrs); + static AttributeSet get(LLVMContext &C, ArrayRef Attrs); /// addAttr - Add the specified attribute at the specified index to this /// attribute list. Since attribute lists are immutable, this /// returns the new list. - AttrListPtr addAttr(LLVMContext &C, unsigned Idx, Attributes Attrs) const; + AttributeSet addAttr(LLVMContext &C, unsigned Idx, Attributes Attrs) const; /// removeAttr - Remove the specified attribute at the specified index from /// this attribute list. Since attribute lists are immutable, this /// returns the new list. - AttrListPtr removeAttr(LLVMContext &C, unsigned Idx, Attributes Attrs) const; + AttributeSet removeAttr(LLVMContext &C, unsigned Idx, Attributes Attrs) const; //===--------------------------------------------------------------------===// // Attribute List Accessors @@ -369,12 +355,12 @@ public: /// getRetAttributes - The attributes for the ret value are /// returned. Attributes getRetAttributes() const { - return getAttributes(0); + return getAttributes(ReturnIndex); } /// getFnAttributes - The function attributes are returned. Attributes getFnAttributes() const { - return getAttributes(~0U); + return getAttributes(FunctionIndex); } /// paramHasAttr - Return true if the specified parameter index has the @@ -397,13 +383,11 @@ public: Attributes &getAttributesAtIndex(unsigned i) const; /// operator==/!= - Provide equality predicates. - bool operator==(const AttrListPtr &RHS) const + bool operator==(const AttributeSet &RHS) const { return AttrList == RHS.AttrList; } - bool operator!=(const AttrListPtr &RHS) const + bool operator!=(const AttributeSet &RHS) const { return AttrList != RHS.AttrList; } - void dump() const; - //===--------------------------------------------------------------------===// // Attribute List Introspection //===--------------------------------------------------------------------===// @@ -433,12 +417,7 @@ public: /// holds a index number plus a set of attributes. const AttributeWithIndex &getSlot(unsigned Slot) const; -private: - explicit AttrListPtr(AttributeListImpl *L); - - /// getAttributes - The attributes for the specified index are - /// returned. Attributes for the result are denoted with Idx = 0. - Attributes getAttributes(unsigned Idx) const; + void dump() const; }; } // End llvm namespace