diff options
author | Derek Schuff <dschuff@chromium.org> | 2012-10-16 17:00:45 -0700 |
---|---|---|
committer | Derek Schuff <dschuff@chromium.org> | 2012-10-16 17:00:45 -0700 |
commit | b46cdaf9e7d5c0e0b6ba3b8cc20059525b7365aa (patch) | |
tree | b8eb5dd8b0407f17967a1fc698eb246041be21fe | |
parent | 585d24067c8df126cc65c22223fc224dc8106d90 (diff) | |
parent | 320db3f8052c9f506d9ea043ba5da534df40aa08 (diff) |
Merge commit '320db3f8052c9f506d9ea043ba5da534df40aa08'
91 files changed, 1561 insertions, 605 deletions
diff --git a/include/llvm-c/Core.h b/include/llvm-c/Core.h index badc70ba22..620d0887be 100644 --- a/include/llvm-c/Core.h +++ b/include/llvm-c/Core.h @@ -1803,7 +1803,7 @@ LLVMAttribute LLVMGetAttribute(LLVMValueRef Arg); * Set the alignment for a function parameter. * * @see llvm::Argument::addAttr() - * @see llvm::Attributes::Builder::addAlignmentAttr() + * @see llvm::AttrBuilder::addAlignmentAttr() */ void LLVMSetParamAlignment(LLVMValueRef Arg, unsigned align); diff --git a/include/llvm/ADT/BitVector.h b/include/llvm/ADT/BitVector.h index 26ec346b18..9d6388f7ee 100644 --- a/include/llvm/ADT/BitVector.h +++ b/include/llvm/ADT/BitVector.h @@ -237,6 +237,34 @@ public: return *this; } + /// set - Efficiently set a range of bits in [I, E) + BitVector &set(unsigned I, unsigned E) { + assert(I <= E && "Attempted to set backwards range!"); + assert(E <= size() && "Attempted to set out-of-bounds range!"); + + if (I == E) return *this; + + if (I / BITWORD_SIZE == E / BITWORD_SIZE) { + BitWord EMask = 1UL << (E % BITWORD_SIZE); + BitWord IMask = 1UL << (I % BITWORD_SIZE); + BitWord Mask = EMask - IMask; + Bits[I / BITWORD_SIZE] |= Mask; + return *this; + } + + BitWord PrefixMask = ~0UL << (I % BITWORD_SIZE); + Bits[I / BITWORD_SIZE] |= PrefixMask; + I = RoundUpToAlignment(I, BITWORD_SIZE); + + for (; I + BITWORD_SIZE <= E; I += BITWORD_SIZE) + Bits[I / BITWORD_SIZE] = ~0UL; + + BitWord PostfixMask = (1UL << (E % BITWORD_SIZE)) - 1; + Bits[I / BITWORD_SIZE] |= PostfixMask; + + return *this; + } + BitVector &reset() { init_words(Bits, Capacity, false); return *this; @@ -247,6 +275,34 @@ public: return *this; } + /// reset - Efficiently reset a range of bits in [I, E) + BitVector &reset(unsigned I, unsigned E) { + assert(I <= E && "Attempted to reset backwards range!"); + assert(E <= size() && "Attempted to reset out-of-bounds range!"); + + if (I == E) return *this; + + if (I / BITWORD_SIZE == E / BITWORD_SIZE) { + BitWord EMask = 1UL << (E % BITWORD_SIZE); + BitWord IMask = 1UL << (I % BITWORD_SIZE); + BitWord Mask = EMask - IMask; + Bits[I / BITWORD_SIZE] &= ~Mask; + return *this; + } + + BitWord PrefixMask = ~0UL << (I % BITWORD_SIZE); + Bits[I / BITWORD_SIZE] &= ~PrefixMask; + I = RoundUpToAlignment(I, BITWORD_SIZE); + + for (; I + BITWORD_SIZE <= E; I += BITWORD_SIZE) + Bits[I / BITWORD_SIZE] = 0UL; + + BitWord PostfixMask = (1UL << (E % BITWORD_SIZE)) - 1; + Bits[I / BITWORD_SIZE] &= ~PostfixMask; + + return *this; + } + BitVector &flip() { for (unsigned i = 0; i < NumBitWords(size()); ++i) Bits[i] = ~Bits[i]; diff --git a/include/llvm/ADT/SmallBitVector.h b/include/llvm/ADT/SmallBitVector.h index 7a645e0c72..a9cd54e13b 100644 --- a/include/llvm/ADT/SmallBitVector.h +++ b/include/llvm/ADT/SmallBitVector.h @@ -300,6 +300,21 @@ public: return *this; } + /// set - Efficiently set a range of bits in [I, E) + SmallBitVector &set(unsigned I, unsigned E) { + assert(I <= E && "Attempted to set backwards range!"); + assert(E <= size() && "Attempted to set out-of-bounds range!"); + if (I == E) return *this; + if (isSmall()) { + uintptr_t EMask = ((uintptr_t)1) << E; + uintptr_t IMask = ((uintptr_t)1) << I; + uintptr_t Mask = EMask - IMask; + setSmallBits(getSmallBits() | Mask); + } else + getPointer()->set(I, E); + return *this; + } + SmallBitVector &reset() { if (isSmall()) setSmallBits(0); @@ -316,6 +331,21 @@ public: return *this; } + /// reset - Efficiently reset a range of bits in [I, E) + SmallBitVector &reset(unsigned I, unsigned E) { + assert(I <= E && "Attempted to reset backwards range!"); + assert(E <= size() && "Attempted to reset out-of-bounds range!"); + if (I == E) return *this; + if (isSmall()) { + uintptr_t EMask = ((uintptr_t)1) << E; + uintptr_t IMask = ((uintptr_t)1) << I; + uintptr_t Mask = EMask - IMask; + setSmallBits(getSmallBits() & ~Mask); + } else + getPointer()->reset(I, E); + return *this; + } + SmallBitVector &flip() { if (isSmall()) setSmallBits(~getSmallBits()); diff --git a/include/llvm/Attributes.h b/include/llvm/Attributes.h index 03ee520440..1e995f9a85 100644 --- a/include/llvm/Attributes.h +++ b/include/llvm/Attributes.h @@ -22,13 +22,11 @@ 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: @@ -36,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 @@ -52,6 +50,7 @@ public: /// uwtable + nounwind = Needs an entry because the ABI says so. enum AttrVal { + // IR-Level Attributes None = 0, ///< No attributes have been set AddressSafety = 1, ///< Address safety checking is on. Alignment = 2, ///< Alignment of parameter (5 bits) @@ -89,10 +88,10 @@ public: }; private: AttributesImpl *Attrs; - Attributes(AttributesImpl *A); + Attributes(AttributesImpl *A) : Attrs(A) {} public: Attributes() : Attrs(0) {} - Attributes(const Attributes &A); + Attributes(const Attributes &A) : Attrs(A.Attrs) {} Attributes &operator=(const Attributes &A) { Attrs = A.Attrs; return *this; @@ -100,81 +99,8 @@ public: /// get - Return a uniquified Attributes object. This takes the uniquified /// value from the Builder and wraps it in the Attributes class. - class Builder; static Attributes get(LLVMContext &Context, ArrayRef<AttrVal> Vals); - static Attributes get(LLVMContext &Context, Builder &B); - - //===--------------------------------------------------------------------===// - /// Attributes::Builder - 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 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()) {} - Builder(const Builder &B) : Bits(B.Bits) {} - - 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); - - Builder &addAttributes(const Attributes &A); - Builder &removeAttributes(const Attributes &A); - - /// 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); - - /// @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; - } - }; + static Attributes get(LLVMContext &Context, AttrBuilder &B); /// @brief Return true if the attribute is present. bool hasAttribute(AttrVal Val) const; @@ -244,42 +170,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; |