| //===-- llvm/Attributes.h - Container for Attributes ------------*- C++ -*-===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // This file contains the simple types necessary to represent the |
| // attributes associated with functions and their calls. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef LLVM_ATTRIBUTES_H |
| #define LLVM_ATTRIBUTES_H |
| |
| #include "llvm/Support/MathExtras.h" |
| #include <cassert> |
| #include <string> |
| |
| namespace llvm { |
| class Type; |
| |
| /// Attributes - A bitset of attributes. |
| typedef unsigned Attributes; |
| |
| namespace Attribute { |
| |
| /// Function parameters and results can have attributes to indicate how they |
| /// 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. |
| /// @brief Function attributes. |
| |
| const Attributes None = 0; ///< No attributes have been set |
| const Attributes ZExt = 1<<0; ///< Zero extended before/after call |
| const Attributes SExt = 1<<1; ///< Sign extended before/after call |
| const Attributes NoReturn = 1<<2; ///< Mark the function as not returning |
| const Attributes InReg = 1<<3; ///< Force argument to be passed in register |
| const Attributes StructRet = 1<<4; ///< Hidden pointer to structure to return |
| const Attributes NoUnwind = 1<<5; ///< Function doesn't unwind stack |
| const Attributes NoAlias = 1<<6; ///< Considered to not alias after call |
| const Attributes ByVal = 1<<7; ///< Pass structure by value |
| const Attributes Nest = 1<<8; ///< Nested function static chain |
| const Attributes ReadNone = 1<<9; ///< Function does not access memory |
| const Attributes ReadOnly = 1<<10; ///< Function only reads from memory |
| const Attributes NoInline = 1<<11; ///< inline=never |
| const Attributes AlwaysInline = 1<<12; ///< inline=always |
| const Attributes OptimizeForSize = 1<<13; ///< opt_size |
| const Attributes StackProtect = 1<<14; ///< Stack protection. |
| const Attributes StackProtectReq = 1<<15; ///< Stack protection required. |
| const Attributes Alignment = 31<<16; ///< Alignment of parameter (5 bits) |
| // stored as log2 of alignment with +1 bias |
| // 0 means unaligned different from align 1 |
| const Attributes NoCapture = 1<<21; ///< Function creates no aliases of pointer |
| const Attributes NoRedZone = 1<<22; /// disable redzone |
| const Attributes NoImplicitFloat = 1<<23; /// disable implicit floating point |
| /// instructions. |
| const Attributes Naked = 1<<24; ///< Naked function |
| const Attributes InlineHint = 1<<25; ///< source said inlining was |
| ///desirable |
| const Attributes 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)) |
| const Attributes ReturnsTwice = 1<<29; ///< Function can return twice |
| const Attributes UWTable = 1<<30; ///< Function must be in a unwind |
| ///table |
| const Attributes NonLazyBind = 1U<<31; ///< Function is called early and/or |
| /// often, so lazy binding isn't |
| /// worthwhile. |
| |
| /// 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 |
| /// an exception might pass by. |
| /// uwtable + nounwind = Needs an entry because the ABI says so. |
| |
| /// @brief Attributes that only apply to function parameters. |
| const Attributes ParameterOnly = ByVal | Nest | StructRet | NoCapture; |
| |
| /// @brief Attributes that may be applied to the function itself. These cannot |
| /// be used on return values or function parameters. |
| const Attributes FunctionOnly = NoReturn | NoUnwind | ReadNone | ReadOnly | |
| NoInline | AlwaysInline | OptimizeForSize | StackProtect | StackProtectReq | |
| NoRedZone | NoImplicitFloat | Naked | InlineHint | StackAlignment | |
| UWTable | NonLazyBind | ReturnsTwice; |
| |
| /// @brief Parameter attributes that do not apply to vararg call arguments. |
| const Attributes VarArgsIncompatible = StructRet; |
| |
| /// @brief Attributes that are mutually incompatible. |
| const Attributes MutuallyIncompatible[4] = { |
| ByVal | InReg | Nest | StructRet, |
| ZExt | SExt, |
| ReadNone | ReadOnly, |
| NoInline | AlwaysInline |
| }; |
| |
| /// @brief Which attributes cannot be applied to a type. |
| Attributes typeIncompatible(Type *Ty); |
| |
| /// This turns an int alignment (a power of 2, normally) into the |
| /// form used internally in Attributes. |
| inline Attributes constructAlignmentFromInt(unsigned i) { |
| // Default alignment, allow the target to define how to align it. |
| if (i == 0) |
| return 0; |
| |
| assert(isPowerOf2_32(i) && "Alignment must be a power of two."); |
| assert(i <= 0x40000000 && "Alignment too large."); |
| return (Log2_32(i)+1) << 16; |
| } |
| |
| /// This returns the alignment field of an attribute as a byte alignment value. |
| inline unsigned getAlignmentFromAttrs(Attributes A) { |
| Attributes Align = A & Attribute::Alignment; |
| if (Align == 0) |
| return 0; |
| |
| return 1U << ((Align >> 16) - 1); |
| } |
| |
| /// This turns an int stack alignment (which must be a power of 2) into |
| /// the form used internally in Attributes. |
| inline Attributes constructStackAlignmentFromInt(unsigned i) { |
| // Default alignment, allow the target to define how to align it. |
| if (i == 0) |
| return 0; |
| |
| assert(isPowerOf2_32(i) && "Alignment must be a power of two."); |
| assert(i <= 0x100 && "Alignment too large."); |
| return (Log2_32(i)+1) << 26; |
| } |
| |
| /// This returns the stack alignment field of an attribute as a byte alignment |
| /// value. |
| inline unsigned getStackAlignmentFromAttrs(Attributes A) { |
| Attributes StackAlign = A & Attribute::StackAlignment; |
| if (StackAlign == 0) |
| return 0; |
| |
| return 1U << ((StackAlign >> 26) - 1); |
| } |
| |
| |
| /// The set of Attributes set in Attributes is converted to a |
| /// string of equivalent mnemonics. This is, presumably, for writing out |
| /// the mnemonics for the assembly writer. |
| /// @brief Convert attribute bits to text |
| std::string getAsString(Attributes Attrs); |
| } // end namespace Attribute |
| |
| /// This is just a pair of values to associate a set of attributes |
| /// with an index. |
| struct AttributeWithIndex { |
| Attributes Attrs; ///< The attributes that are set, or'd together. |
| unsigned Index; ///< Index of the parameter for which the attributes apply. |
| ///< Index 0 is used for return value attributes. |
| ///< Index ~0U is used for function attributes. |
| |
| static AttributeWithIndex get(unsigned Idx, Attributes Attrs) { |
| AttributeWithIndex P; |
| P.Index = Idx; |
| P.Attrs = Attrs; |
| return P; |
| } |
| }; |
| |
| //===----------------------------------------------------------------------===// |
| // AttrListPtr Smart Pointer |
| //===----------------------------------------------------------------------===// |
| |
| class AttributeListImpl; |
| |
| /// AttrListPtr - 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. |
| AttributeListImpl *AttrList; |
| public: |
| AttrListPtr() : AttrList(0) {} |
| AttrListPtr(const AttrListPtr &P); |
| const AttrListPtr &operator=(const AttrListPtr &RHS); |
| ~AttrListPtr(); |
| |
| //===--------------------------------------------------------------------===// |
| // Attribute List Construction and Mutation |
| //===--------------------------------------------------------------------===// |
| |
| /// get - Return a Attributes list with the specified parameter in it. |
| static AttrListPtr get(const AttributeWithIndex *Attr, unsigned NumAttrs); |
| |
| /// get - Return a Attribute list with the parameters specified by the |
| /// consecutive random access iterator range. |
| template <typename Iter> |
| static AttrListPtr get(const Iter &I, const Iter &E) { |
| if (I == E) return AttrListPtr(); // Empty list. |
| return get(&*I, static_cast<unsigned>(E-I)); |
| } |
| |
| /// 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(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(unsigned Idx, Attributes Attrs) const; |
| |
| //===--------------------------------------------------------------------===// |
| // Attribute List Accessors |
| //===--------------------------------------------------------------------===// |
| /// getParamAttributes - The attributes for the specified index are |
| /// returned. |
| Attributes getParamAttributes(unsigned Idx) const { |
| assert (Idx && Idx != ~0U && "Invalid parameter index!"); |
| return getAttributes(Idx); |
| } |
| |
| /// getRetAttributes - The attributes for the ret value are |
| /// returned. |
| Attributes getRetAttributes() const { |
| return getAttributes(0); |
| } |
| |
| /// getFnAttributes - The function attributes are returned. |
| Attributes getFnAttributes() const { |
| return getAttributes(~0U); |
| } |
| |
| /// paramHasAttr - Return true if the specified parameter index has the |
| /// specified attribute set. |
| bool paramHasAttr(unsigned Idx, Attributes Attr) const { |
| return (getAttributes(Idx) & Attr) != 0; |
| } |
| |
| /// getParamAlignment - Return the alignment for the specified function |
| /// parameter. |
| unsigned getParamAlignment(unsigned Idx) const { |
| return Attribute::getAlignmentFromAttrs(getAttributes(Idx)); |
| } |
| |
| /// hasAttrSomewhere - Return true if the specified attribute is set for at |
| /// least one parameter or for the return value. |
| bool hasAttrSomewhere(Attributes Attr) const; |
| |
| /// operator==/!= - Provide equality predicates. |
| bool operator==(const AttrListPtr &RHS) const |
| { return AttrList == RHS.AttrList; } |
| bool operator!=(const AttrListPtr &RHS) const |
| { return AttrList != RHS.AttrList; } |
| |
| void dump() const; |
| |
| //===--------------------------------------------------------------------===// |
| // Attribute List Introspection |
| //===--------------------------------------------------------------------===// |
| |
| /// getRawPointer - Return a raw pointer that uniquely identifies this |
| /// attribute list. |
| void *getRawPointer() const { |
| return AttrList; |
| } |
| |
| // Attributes are stored as a dense set of slots, where there is one |
| // slot for each argument that has an attribute. This allows walking over the |
| // dense set instead of walking the sparse list of attributes. |
| |
| /// isEmpty - Return true if there are no attributes. |
| /// |
| bool isEmpty() const { |
| return AttrList == 0; |
| } |
| |
| /// getNumSlots - Return the number of slots used in this attribute list. |
| /// This is the number of arguments that have an attribute set on them |
| /// (including the function itself). |
| unsigned getNumSlots() const; |
| |
| /// getSlot - Return the AttributeWithIndex at the specified slot. This |
| /// 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; |
| |
| }; |
| |
| } // End llvm namespace |
| |
| #endif |