aboutsummaryrefslogtreecommitdiff
path: root/include/llvm/Attributes.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/Attributes.h')
-rw-r--r--include/llvm/Attributes.h349
1 files changed, 220 insertions, 129 deletions
diff --git a/include/llvm/Attributes.h b/include/llvm/Attributes.h
index 9dc2c1aa57..c9589603f9 100644
--- a/include/llvm/Attributes.h
+++ b/include/llvm/Attributes.h
@@ -22,6 +22,7 @@
namespace llvm {
+class LLVMContext;
class Type;
namespace Attribute {
@@ -96,16 +97,160 @@ DECLARE_LLVM_ATTRIBUTE(AddressSafety,1ULL<<32) ///< Address safety checking is o
#undef DECLARE_LLVM_ATTRIBUTE
+/// 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 AttrConst ParameterOnly = {ByVal_i | Nest_i |
+ StructRet_i | NoCapture_i};
+
+/// @brief Attributes that may be applied to the function itself. These cannot
+/// be used on return values or function parameters.
+const AttrConst FunctionOnly = {NoReturn_i | NoUnwind_i | ReadNone_i |
+ ReadOnly_i | NoInline_i | AlwaysInline_i | OptimizeForSize_i |
+ StackProtect_i | StackProtectReq_i | NoRedZone_i | NoImplicitFloat_i |
+ Naked_i | InlineHint_i | StackAlignment_i |
+ UWTable_i | NonLazyBind_i | ReturnsTwice_i | AddressSafety_i};
+
+/// @brief Parameter attributes that do not apply to vararg call arguments.
+const AttrConst VarArgsIncompatible = {StructRet_i};
+
+/// @brief Attributes that are mutually incompatible.
+const AttrConst MutuallyIncompatible[5] = {
+ {ByVal_i | Nest_i | StructRet_i},
+ {ByVal_i | Nest_i | InReg_i },
+ {ZExt_i | SExt_i},
+ {ReadNone_i | ReadOnly_i},
+ {NoInline_i | AlwaysInline_i}
+};
+
} // namespace Attribute
+/// AttributeImpl - The internal representation of the Attributes class. This is
+/// uniquified.
+class AttributesImpl;
+
/// Attributes - A bitset of attributes.
class Attributes {
// Currently, we need less than 64 bits.
uint64_t Bits;
+
+ explicit Attributes(AttributesImpl *A);
public:
- Attributes() : Bits(0) { }
- explicit Attributes(uint64_t Val) : Bits(Val) { }
- /*implicit*/ Attributes(Attribute::AttrConst Val) : Bits(Val.v) { }
+ Attributes() : Bits(0) {}
+ explicit Attributes(uint64_t Val) : Bits(Val) {}
+ /*implicit*/ Attributes(Attribute::AttrConst Val) : Bits(Val.v) {}
+
+ class Builder {
+ friend class Attributes;
+ uint64_t Bits;
+ public:
+ Builder() : Bits(0) {}
+ Builder(const Attributes &A) : Bits(A.Bits) {}
+
+ void addZExtAttr() {
+ Bits |= Attribute::ZExt_i;
+ }
+ void addSExtAttr() {
+ Bits |= Attribute::SExt_i;
+ }
+ void addNoReturnAttr() {
+ Bits |= Attribute::NoReturn_i;
+ }
+ void addInRegAttr() {
+ Bits |= Attribute::InReg_i;
+ }
+ void addStructRetAttr() {
+ Bits |= Attribute::StructRet_i;
+ }
+ void addNoUnwindAttr() {
+ Bits |= Attribute::NoUnwind_i;
+ }
+ void addNoAliasAttr() {
+ Bits |= Attribute::NoAlias_i;
+ }
+ void addByValAttr() {
+ Bits |= Attribute::ByVal_i;
+ }
+ void addNestAttr() {
+ Bits |= Attribute::Nest_i;
+ }
+ void addReadNoneAttr() {
+ Bits |= Attribute::ReadNone_i;
+ }
+ void addReadOnlyAttr() {
+ Bits |= Attribute::ReadOnly_i;
+ }
+ void addNoInlineAttr() {
+ Bits |= Attribute::NoInline_i;
+ }
+ void addAlwaysInlineAttr() {
+ Bits |= Attribute::AlwaysInline_i;
+ }
+ void addOptimizeForSizeAttr() {
+ Bits |= Attribute::OptimizeForSize_i;
+ }
+ void addStackProtectAttr() {
+ Bits |= Attribute::StackProtect_i;
+ }
+ void addStackProtectReqAttr() {
+ Bits |= Attribute::StackProtectReq_i;
+ }
+ void addNoCaptureAttr() {
+ Bits |= Attribute::NoCapture_i;
+ }
+ void addNoRedZoneAttr() {
+ Bits |= Attribute::NoRedZone_i;
+ }
+ void addNoImplicitFloatAttr() {
+ Bits |= Attribute::NoImplicitFloat_i;
+ }
+ void addNakedAttr() {
+ Bits |= Attribute::Naked_i;
+ }
+ void addInlineHintAttr() {
+ Bits |= Attribute::InlineHint_i;
+ }
+ void addReturnsTwiceAttr() {
+ Bits |= Attribute::ReturnsTwice_i;
+ }
+ void addUWTableAttr() {
+ Bits |= Attribute::UWTable_i;
+ }
+ void addNonLazyBindAttr() {
+ Bits |= Attribute::NonLazyBind_i;
+ }
+ void addAddressSafetyAttr() {
+ Bits |= Attribute::AddressSafety_i;
+ }
+ void addAlignmentAttr(unsigned Align) {
+ if (Align == 0) return;
+ assert(isPowerOf2_32(Align) && "Alignment must be a power of two.");
+ assert(Align <= 0x40000000 && "Alignment too large.");
+ Bits |= (Log2_32(Align) + 1) << 16;
+ }
+ void addStackAlignmentAttr(unsigned Align) {
+ // Default alignment, allow the target to define how to align it.
+ if (Align == 0) return;
+
+ assert(isPowerOf2_32(Align) && "Alignment must be a power of two.");
+ assert(Align <= 0x100 && "Alignment too large.");
+ Bits |= (Log2_32(Align) + 1) << 26;
+ }
+ };
+
+ /// get - Return a uniquified Attributes object. This takes the uniquified
+ /// value from the Builder and wraps it in the Attributes class.
+ static Attributes get(LLVMContext &Context, Builder &B);
// Attribute query methods.
// FIXME: StackAlignment & Alignment attributes have no predicate methods.
@@ -198,20 +343,12 @@ public:
return Bits & Attribute::AddressSafety_i;
}
- uint64_t getRawAlignment() const {
- return Bits & Attribute::Alignment_i;
- }
- uint64_t getRawStackAlignment() const {
- return Bits & Attribute::StackAlignment_i;
- }
-
/// This returns the alignment field of an attribute as a byte alignment
/// value.
unsigned getAlignment() const {
if (!hasAlignmentAttr())
return 0;
-
- return 1U << ((getRawAlignment() >> 16) - 1);
+ return 1U << (((Bits & Attribute::Alignment_i) >> 16) - 1);
}
/// This returns the stack alignment field of an attribute as a byte alignment
@@ -219,32 +356,7 @@ public:
unsigned getStackAlignment() const {
if (!hasStackAlignmentAttr())
return 0;
-
- return 1U << ((getRawStackAlignment() >> 26) - 1);
- }
-
- /// This turns an int alignment (a power of 2, normally) into the form used
- /// internally in Attributes.
- static Attributes constructAlignmentFromInt(unsigned i) {
- // Default alignment, allow the target to define how to align it.
- if (i == 0)
- return Attribute::None;
-
- assert(isPowerOf2_32(i) && "Alignment must be a power of two.");
- assert(i <= 0x40000000 && "Alignment too large.");
- return Attributes((Log2_32(i)+1) << 16);
- }
-
- /// This turns an int stack alignment (which must be a power of 2) into the
- /// form used internally in Attributes.
- static Attributes constructStackAlignmentFromInt(unsigned i) {
- // Default alignment, allow the target to define how to align it.
- if (i == 0)
- return Attribute::None;
-
- assert(isPowerOf2_32(i) && "Alignment must be a power of two.");
- assert(i <= 0x100 && "Alignment too large.");
- return Attributes((Log2_32(i)+1) << 26);
+ return 1U << (((Bits & Attribute::StackAlignment_i) >> 26) - 1);
}
// This is a "safe bool() operator".
@@ -276,107 +388,86 @@ public:
Attributes operator ~ () const { return Attributes(~Bits); }
uint64_t Raw() const { return Bits; }
- /// 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() const;
-};
-
-namespace Attribute {
+ /// This turns an int alignment (a power of 2, normally) into the form used
+ /// internally in Attributes.
+ static Attributes constructAlignmentFromInt(unsigned i) {
+ // Default alignment, allow the target to define how to align it.
+ if (i == 0)
+ return Attribute::None;
-/// 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.
+ assert(isPowerOf2_32(i) && "Alignment must be a power of two.");
+ assert(i <= 0x40000000 && "Alignment too large.");
+ return Attributes((Log2_32(i)+1) << 16);
+ }
-/// @brief Attributes that only apply to function parameters.
-const AttrConst ParameterOnly = {ByVal_i | Nest_i |
- StructRet_i | NoCapture_i};
+ /// This turns an int stack alignment (which must be a power of 2) into the
+ /// form used internally in Attributes.
+ static Attributes constructStackAlignmentFromInt(unsigned i) {
+ // Default alignment, allow the target to define how to align it.
+ if (i == 0)
+ return Attribute::None;
-/// @brief Attributes that may be applied to the function itself. These cannot
-/// be used on return values or function parameters.
-const AttrConst FunctionOnly = {NoReturn_i | NoUnwind_i | ReadNone_i |
- ReadOnly_i | NoInline_i | AlwaysInline_i | OptimizeForSize_i |
- StackProtect_i | StackProtectReq_i | NoRedZone_i | NoImplicitFloat_i |
- Naked_i | InlineHint_i | StackAlignment_i |
- UWTable_i | NonLazyBind_i | ReturnsTwice_i | AddressSafety_i};
+ assert(isPowerOf2_32(i) && "Alignment must be a power of two.");
+ assert(i <= 0x100 && "Alignment too large.");
+ return Attributes((Log2_32(i)+1) << 26);
+ }
-/// @brief Parameter attributes that do not apply to vararg call arguments.
-const AttrConst VarArgsIncompatible = {StructRet_i};
+ /// @brief Which attributes cannot be applied to a type.
+ static Attributes typeIncompatible(Type *Ty);
+
+ /// 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.hasAlignmentAttr())
+ EncodedAttrs |= (1ULL << 16) <<
+ (((Attrs.Bits & Attribute::Alignment_i) - 1) >> 16);
+ EncodedAttrs |= (Attrs.Raw() & (0xfffULL << 21)) << 11;
+ return EncodedAttrs;
+ }
+
+ /// 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 Attrs(EncodedAttrs & 0xffff);
+ if (Alignment)
+ Attrs |= Attributes::constructAlignmentFromInt(Alignment);
+ Attrs |= Attributes((EncodedAttrs & (0xfffULL << 32)) >> 11);
+ return Attrs;
+ }
-/// @brief Attributes that are mutually incompatible.
-const AttrConst MutuallyIncompatible[5] = {
- {ByVal_i | Nest_i | StructRet_i},
- {ByVal_i | Nest_i | InReg_i },
- {ZExt_i | SExt_i},
- {ReadNone_i | ReadOnly_i},
- {NoInline_i | AlwaysInline_i}
+ /// 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() const;
};
-/// @brief Which attributes cannot be applied to a type.
-Attributes typeIncompatible(Type *Ty);
-
-/// 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.
-inline 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.hasAlignmentAttr())
- EncodedAttrs |= (1ull << 16) <<
- ((Attrs.getRawAlignment() - 1) >> 16);
- EncodedAttrs |= (Attrs.Raw() & (0xfffull << 21)) << 11;
-
- return EncodedAttrs;
-}
-
-/// 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'.
-inline 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 Attrs(EncodedAttrs & 0xffff);
- if (Alignment)
- Attrs |= Attributes::constructAlignmentFromInt(Alignment);
- Attrs |= Attributes((EncodedAttrs & (0xfffull << 32)) >> 11);
-
- return 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.
+ 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;