diff --git a/include/llvm/IR/Attributes.h b/include/llvm/IR/Attributes.h index e5a1ad294b5..28ec9db62e7 100644 --- a/include/llvm/IR/Attributes.h +++ b/include/llvm/IR/Attributes.h @@ -116,10 +116,16 @@ public: /// value. unsigned getAlignment() const; + /// \brief Set the alignment field of an attribute. + void setAlignment(unsigned Align); + /// \brief Returns the stack alignment field of an attribute as a byte /// alignment value. unsigned getStackAlignment() const; + /// \brief Set the stack alignment field of an attribute. + void setStackAlignment(unsigned Align); + /// \brief Equality and non-equality query methods. bool operator==(AttrKind K) const; bool operator!=(AttrKind K) const; @@ -233,6 +239,15 @@ public: /// the form used internally in Attribute. AttrBuilder &addStackAlignmentAttr(unsigned Align); + typedef DenseSet<Attribute::AttrKind>::iterator iterator; + typedef DenseSet<Attribute::AttrKind>::const_iterator const_iterator; + + iterator begin() { return Attrs.begin(); } + iterator end() { return Attrs.end(); } + + const_iterator begin() const { return Attrs.begin(); } + const_iterator end() const { return Attrs.end(); } + /// \brief Add the raw value to the internal representation. /// /// N.B. This should be used ONLY for decoding LLVM bitcode! @@ -329,6 +344,7 @@ public: /// \brief Return an AttributeSet with the specified parameters in it. static AttributeSet get(LLVMContext &C, ArrayRef<AttributeWithIndex> Attrs); + static AttributeSet get(LLVMContext &C, unsigned Idx, AttrBuilder &B); /// \brief Add the specified attribute at the specified index to this /// attribute list. Since attribute lists are immutable, this returns the new diff --git a/lib/IR/AttributeImpl.h b/lib/IR/AttributeImpl.h index 42b4fe36b22..a2a5218d806 100644 --- a/lib/IR/AttributeImpl.h +++ b/lib/IR/AttributeImpl.h @@ -29,6 +29,7 @@ class LLVMContext; /// \brief This class represents a single, uniqued attribute. That attribute /// could be a single enum, a tuple, or a string. class AttributeImpl : public FoldingSetNode { + LLVMContext &Context; Constant *Data; SmallVector<Constant*, 0> Vals; public: @@ -47,7 +48,10 @@ public: bool hasAttributes() const; uint64_t getAlignment() const; + void setAlignment(unsigned Align); + uint64_t getStackAlignment() const; + void setStackAlignment(unsigned Align); bool operator==(Attribute::AttrKind Kind) const; bool operator!=(Attribute::AttrKind Kind) const; diff --git a/lib/IR/Attributes.cpp b/lib/IR/Attributes.cpp index 068b5042948..84f90ade8b2 100644 --- a/lib/IR/Attributes.cpp +++ b/lib/IR/Attributes.cpp @@ -76,6 +76,12 @@ unsigned Attribute::getAlignment() const { return 1U << ((pImpl->getAlignment() >> 16) - 1); } +void Attribute::setAlignment(unsigned Align) { + assert(hasAttribute(Attribute::Alignment) && + "Trying to set the alignment on a non-alignment attribute!"); + pImpl->setAlignment(Align); +} + /// This returns the stack alignment field of an attribute as a byte alignment /// value. unsigned Attribute::getStackAlignment() const { @@ -84,6 +90,12 @@ unsigned Attribute::getStackAlignment() const { return 1U << ((pImpl->getStackAlignment() >> 26) - 1); } +void Attribute::setStackAlignment(unsigned Align) { + assert(hasAttribute(Attribute::StackAlignment) && + "Trying to set the stack alignment on a non-alignment attribute!"); + pImpl->setStackAlignment(Align); +} + bool Attribute::operator==(AttrKind K) const { return pImpl && *pImpl == K; } @@ -367,19 +379,23 @@ bool AttrBuilder::operator==(const AttrBuilder &B) { // AttributeImpl Definition //===----------------------------------------------------------------------===// -AttributeImpl::AttributeImpl(LLVMContext &C, uint64_t data) { +AttributeImpl::AttributeImpl(LLVMContext &C, uint64_t data) + : Context(C) { Data = ConstantInt::get(Type::getInt64Ty(C), data); } -AttributeImpl::AttributeImpl(LLVMContext &C, Attribute::AttrKind data) { +AttributeImpl::AttributeImpl(LLVMContext &C, Attribute::AttrKind data) + : Context(C) { Data = ConstantInt::get(Type::getInt64Ty(C), data); } AttributeImpl::AttributeImpl(LLVMContext &C, Attribute::AttrKind data, - ArrayRef<Constant*> values) { + ArrayRef<Constant*> values) + : Context(C) { Data = ConstantInt::get(Type::getInt64Ty(C), data); Vals.reserve(values.size()); Vals.append(values.begin(), values.end()); } -AttributeImpl::AttributeImpl(LLVMContext &C, StringRef data) { +AttributeImpl::AttributeImpl(LLVMContext &C, StringRef data) + : Context(C) { Data = ConstantDataArray::getString(C, data); } @@ -456,10 +472,18 @@ uint64_t AttributeImpl::getAlignment() const { return getBitMask() & getAttrMask(Attribute::Alignment); } +void AttributeImpl::setAlignment(unsigned Align) { + Vals.push_back(ConstantInt::get(Type::getInt64Ty(Context), Align)); +} + uint64_t AttributeImpl::getStackAlignment() const { return getBitMask() & getAttrMask(Attribute::StackAlignment); } +void AttributeImpl::setStackAlignment(unsigned Align) { + Vals.push_back(ConstantInt::get(Type::getInt64Ty(Context), Align)); +} + //===----------------------------------------------------------------------===// // AttributeSetImpl Definition //===----------------------------------------------------------------------===// @@ -485,8 +509,7 @@ AttributeSet AttributeSet::get(LLVMContext &C, AttributeSetImpl::Profile(ID, Attrs); void *InsertPoint; - AttributeSetImpl *PA = pImpl->AttrsLists.FindNodeOrInsertPos(ID, - InsertPoint); + AttributeSetImpl *PA = pImpl->AttrsLists.FindNodeOrInsertPos(ID, InsertPoint); // If we didn't find any existing attributes of the same shape then // create a new one and insert it. @@ -499,6 +522,23 @@ AttributeSet AttributeSet::get(LLVMContext &C, return AttributeSet(PA); } +AttributeSet AttributeSet::get(LLVMContext &C, unsigned Idx, AttrBuilder &B) { + SmallVector<AttributeWithIndex, 8> Attrs; + for (AttrBuilder::iterator I = B.begin(), E = B.end(); I != E; ++I) { + Attribute::AttrKind Kind = *I; + Attribute A = Attribute::get(C, Kind); + + if (Kind == Attribute::Alignment) + A.setAlignment(B.getAlignment()); + else if (Kind == Attribute::StackAlignment) + A.setStackAlignment(B.getStackAlignment()); + + Attrs.push_back(AttributeWithIndex::get(Idx, A)); + } + + return get(C, Attrs); +} + //===----------------------------------------------------------------------===// // AttributeSet Method Implementations //===----------------------------------------------------------------------===//