From d509a6653a12d2ed4842782d145fa93d7461ebd8 Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Tue, 29 Jan 2013 00:34:06 +0000 Subject: [PATCH] Reorder some functions and add comments. No functionality change. llvm-svn: 173733 --- llvm/include/llvm/IR/Attributes.h | 101 +++--- llvm/lib/IR/AttributeImpl.h | 25 +- llvm/lib/IR/Attributes.cpp | 669 +++++++++++++++++++------------------- 3 files changed, 400 insertions(+), 395 deletions(-) diff --git a/llvm/include/llvm/IR/Attributes.h b/llvm/include/llvm/IR/Attributes.h index 15b664c..a95ede1 100644 --- a/llvm/include/llvm/IR/Attributes.h +++ b/llvm/include/llvm/IR/Attributes.h @@ -107,6 +107,10 @@ private: public: Attribute() : pImpl(0) {} + //===--------------------------------------------------------------------===// + // Attribute Construction + //===--------------------------------------------------------------------===// + /// \brief Return a uniquified Attribute object. static Attribute get(LLVMContext &Context, AttrKind Kind); static Attribute get(LLVMContext &Context, AttrBuilder &B); @@ -116,6 +120,10 @@ public: static Attribute getWithAlignment(LLVMContext &Context, uint64_t Align); static Attribute getWithStackAlignment(LLVMContext &Context, uint64_t Align); + //===--------------------------------------------------------------------===// + // Attribute Accessors + //===--------------------------------------------------------------------===// + /// \brief Return true if the attribute is present. bool hasAttribute(AttrKind Val) const; @@ -130,6 +138,10 @@ public: /// alignment value. unsigned getStackAlignment() const; + /// \brief The Attribute is converted to a string of equivalent mnemonic. This + /// is, presumably, for writing out the mnemonics for the assembly writer. + std::string getAsString() const; + /// \brief Equality and non-equality query methods. bool operator==(AttrKind K) const; bool operator!=(AttrKind K) const; @@ -140,38 +152,15 @@ public: /// \brief Less-than operator. Useful for sorting the attributes list. bool operator<(Attribute A) const; - /// \brief The Attribute is converted to a string of equivalent mnemonic. This - /// is, presumably, for writing out the mnemonics for the assembly writer. - std::string getAsString() const; - void Profile(FoldingSetNodeID &ID) const { ID.AddPointer(pImpl); } + // FIXME: Remove this. uint64_t Raw() const; }; //===----------------------------------------------------------------------===// -/// \class -/// \brief Provide DenseMapInfo for Attribute::AttrKinds. This is used by -/// AttrBuilder. -template<> struct DenseMapInfo { - static inline Attribute::AttrKind getEmptyKey() { - return Attribute::AttrKindEmptyKey; - } - static inline Attribute::AttrKind getTombstoneKey() { - return Attribute::AttrKindTombstoneKey; - } - static unsigned getHashValue(const Attribute::AttrKind &Val) { - return Val * 37U; - } - static bool isEqual(const Attribute::AttrKind &LHS, - const Attribute::AttrKind &RHS) { - return LHS == RHS; - } -}; - -//===----------------------------------------------------------------------===// // AttributeSet Smart Pointer //===----------------------------------------------------------------------===// @@ -223,7 +212,7 @@ public: } //===--------------------------------------------------------------------===// - // Attribute List Construction and Mutation + // AttributeSet Construction and Mutation //===--------------------------------------------------------------------===// /// \brief Return an AttributeSet with the specified parameters in it. @@ -267,7 +256,7 @@ public: AttributeSet Attrs) const; //===--------------------------------------------------------------------===// - // Attribute Set Accessors + // AttributeSet Accessors //===--------------------------------------------------------------------===// /// \brief The attributes for the specified index are returned. @@ -285,6 +274,10 @@ public: /// \brief Return true if attribute exists at the given index. bool hasAttributes(unsigned Index) const; + /// \brief Return true if the specified attribute is set for at least one + /// parameter or for the return value. + bool hasAttrSomewhere(Attribute::AttrKind Attr) const; + /// \brief Return the alignment for the specified function parameter. unsigned getParamAlignment(unsigned Idx) const; @@ -294,12 +287,6 @@ public: /// \brief Return the attributes at the index as a string. std::string getAsString(unsigned Index) const; - uint64_t Raw(unsigned Index) const; - - /// \brief Return true if the specified attribute is set for at least one - /// parameter or for the return value. - bool hasAttrSomewhere(Attribute::AttrKind Attr) const; - /// operator==/!= - Provide equality predicates. bool operator==(const AttributeSet &RHS) const { return pImpl == RHS.pImpl; @@ -309,18 +296,17 @@ public: } //===--------------------------------------------------------------------===// - // Attribute List Introspection + // AttributeSet Introspection //===--------------------------------------------------------------------===// + // FIXME: Remove this. + uint64_t Raw(unsigned Index) const; + /// \brief Return a raw pointer that uniquely identifies this attribute list. void *getRawPointer() const { return pImpl; } - // 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. - /// \brief Return true if there are no attributes. bool isEmpty() const { return pImpl == 0; @@ -342,6 +328,26 @@ public: //===----------------------------------------------------------------------===// /// \class +/// \brief Provide DenseMapInfo for Attribute::AttrKinds. This is used by +/// AttrBuilder. +template<> struct DenseMapInfo { + static inline Attribute::AttrKind getEmptyKey() { + return Attribute::AttrKindEmptyKey; + } + static inline Attribute::AttrKind getTombstoneKey() { + return Attribute::AttrKindTombstoneKey; + } + static unsigned getHashValue(const Attribute::AttrKind &Val) { + return Val * 37U; + } + static bool isEqual(const Attribute::AttrKind &LHS, + const Attribute::AttrKind &RHS) { + return LHS == RHS; + } +}; + +//===----------------------------------------------------------------------===// +/// \class /// \brief This class is used in conjunction with the Attribute::get method to /// create an Attribute 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 @@ -407,17 +413,11 @@ public: typedef DenseSet::iterator iterator; typedef DenseSet::const_iterator const_iterator; - iterator begin() { return Attrs.begin(); } - iterator end() { return Attrs.end(); } - + 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! - AttrBuilder &addRawValue(uint64_t Val); - /// \brief Remove attributes that are used on functions only. void removeFunctionOnlyAttrs() { removeAttribute(Attribute::NoReturn) @@ -443,12 +443,19 @@ public: .removeAttribute(Attribute::NoDuplicate); } - uint64_t Raw() const; - bool operator==(const AttrBuilder &B); bool operator!=(const AttrBuilder &B) { return !(*this == B); } + + // FIXME: Remove these. + + /// \brief Add the raw value to the internal representation. + /// + /// N.B. This should be used ONLY for decoding LLVM bitcode! + AttrBuilder &addRawValue(uint64_t Val); + + uint64_t Raw() const; }; namespace AttributeFuncs { diff --git a/llvm/lib/IR/AttributeImpl.h b/llvm/lib/IR/AttributeImpl.h index c00f094..34754e8 100644 --- a/llvm/lib/IR/AttributeImpl.h +++ b/llvm/lib/IR/AttributeImpl.h @@ -37,20 +37,19 @@ class AttributeImpl : public FoldingSetNode { void operator=(const AttributeImpl &) LLVM_DELETED_FUNCTION; AttributeImpl(const AttributeImpl &) LLVM_DELETED_FUNCTION; public: - explicit AttributeImpl(LLVMContext &C, uint64_t data); + AttributeImpl(LLVMContext &C, Constant *Data) + : Context(C), Data(Data) {} explicit AttributeImpl(LLVMContext &C, Attribute::AttrKind data); AttributeImpl(LLVMContext &C, Attribute::AttrKind data, ArrayRef values); AttributeImpl(LLVMContext &C, StringRef data); - LLVMContext &getContext() { return Context; } - - ArrayRef getValues() const { return Vals; } - bool hasAttribute(Attribute::AttrKind A) const; - bool hasAttributes() const; + LLVMContext &getContext() { return Context; } + ArrayRef getValues() const { return Vals; } + uint64_t getAlignment() const; uint64_t getStackAlignment() const; @@ -62,15 +61,19 @@ public: bool operator<(const AttributeImpl &AI) const; - uint64_t Raw() const; // FIXME: Remove. - - static uint64_t getAttrMask(Attribute::AttrKind Val); - void Profile(FoldingSetNodeID &ID) const { Profile(ID, Data, Vals); } static void Profile(FoldingSetNodeID &ID, Constant *Data, - ArrayRef Vals); + ArrayRef Vals) { + ID.AddPointer(Data); + for (unsigned I = 0, E = Vals.size(); I != E; ++I) + ID.AddPointer(Vals[I]); + } + + // FIXME: Remove these! + uint64_t Raw() const; + static uint64_t getAttrMask(Attribute::AttrKind Val); }; //===----------------------------------------------------------------------===// diff --git a/llvm/lib/IR/Attributes.cpp b/llvm/lib/IR/Attributes.cpp index ac394b7..f56eb7b 100644 --- a/llvm/lib/IR/Attributes.cpp +++ b/llvm/lib/IR/Attributes.cpp @@ -44,7 +44,8 @@ Attribute Attribute::get(LLVMContext &Context, AttrBuilder &B) { // Otherwise, build a key to look up the existing attributes. LLVMContextImpl *pImpl = Context.pImpl; FoldingSetNodeID ID; - ID.AddInteger(B.Raw()); + ConstantInt *CI = ConstantInt::get(Type::getInt64Ty(Context), B.Raw()); + ID.AddPointer(CI); void *InsertPoint; AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint); @@ -52,7 +53,7 @@ Attribute Attribute::get(LLVMContext &Context, AttrBuilder &B) { if (!PA) { // If we didn't find any existing attributes of the same shape then create a // new one and insert it. - PA = new AttributeImpl(Context, B.Raw()); + PA = new AttributeImpl(Context, CI); pImpl->AttrsSet.InsertNode(PA, InsertPoint); } @@ -94,24 +95,6 @@ unsigned Attribute::getStackAlignment() const { return pImpl->getStackAlignment(); } -bool Attribute::operator==(AttrKind K) const { - return pImpl && *pImpl == K; -} -bool Attribute::operator!=(AttrKind K) const { - return !(*this == K); -} - -bool Attribute::operator<(Attribute A) const { - if (!pImpl && !A.pImpl) return false; - if (!pImpl) return true; - if (!A.pImpl) return false; - return *pImpl < *A.pImpl; -} - -uint64_t Attribute::Raw() const { - return pImpl ? pImpl->Raw() : 0; -} - std::string Attribute::getAsString() const { std::string Result; if (hasAttribute(Attribute::ZExt)) @@ -186,184 +169,28 @@ std::string Attribute::getAsString() const { return Result; } -//===----------------------------------------------------------------------===// -// AttrBuilder Method Implementations -//===----------------------------------------------------------------------===// - -AttrBuilder::AttrBuilder(AttributeSet AS, unsigned Idx) - : Alignment(0), StackAlignment(0) { - AttributeSetImpl *pImpl = AS.pImpl; - if (!pImpl) return; - - AttrBuilder B; - - for (unsigned I = 0, E = pImpl->getNumAttributes(); I != E; ++I) { - if (pImpl->getSlotIndex(I) != Idx) continue; - - for (AttributeSetNode::const_iterator II = pImpl->begin(I), - IE = pImpl->end(I); II != IE; ++II) - B.addAttributes(*II); - - break; - } - - if (!B.hasAttributes()) return; - - uint64_t Mask = B.Raw(); - - for (Attribute::AttrKind I = Attribute::None; I != Attribute::EndAttrKinds; - I = Attribute::AttrKind(I + 1)) { - if (uint64_t A = (Mask & AttributeImpl::getAttrMask(I))) { - Attrs.insert(I); - - if (I == Attribute::Alignment) - Alignment = 1ULL << ((A >> 16) - 1); - else if (I == Attribute::StackAlignment) - StackAlignment = 1ULL << ((A >> 26)-1); - } - } -} - -void AttrBuilder::clear() { - Attrs.clear(); - Alignment = StackAlignment = 0; -} - -AttrBuilder &AttrBuilder::addAttribute(Attribute::AttrKind Val) { - Attrs.insert(Val); - return *this; -} - -AttrBuilder &AttrBuilder::removeAttribute(Attribute::AttrKind Val) { - Attrs.erase(Val); - if (Val == Attribute::Alignment) - Alignment = 0; - else if (Val == Attribute::StackAlignment) - StackAlignment = 0; - - return *this; -} - -AttrBuilder &AttrBuilder::addAttributes(Attribute Attr) { - uint64_t Mask = Attr.Raw(); - - for (Attribute::AttrKind I = Attribute::None; I != Attribute::EndAttrKinds; - I = Attribute::AttrKind(I + 1)) - if ((Mask & AttributeImpl::getAttrMask(I)) != 0) - Attrs.insert(I); - - if (Attr.getAlignment()) - Alignment = Attr.getAlignment(); - if (Attr.getStackAlignment()) - StackAlignment = Attr.getStackAlignment(); - return *this; -} - -AttrBuilder &AttrBuilder::removeAttributes(Attribute A) { - uint64_t Mask = A.Raw(); - - for (Attribute::AttrKind I = Attribute::None; I != Attribute::EndAttrKinds; - I = Attribute::AttrKind(I + 1)) { - if (Mask & AttributeImpl::getAttrMask(I)) { - Attrs.erase(I); - - if (I == Attribute::Alignment) - Alignment = 0; - else if (I == Attribute::StackAlignment) - StackAlignment = 0; - } - } - - return *this; -} - -AttrBuilder &AttrBuilder::addAlignmentAttr(unsigned Align) { - if (Align == 0) return *this; - - assert(isPowerOf2_32(Align) && "Alignment must be a power of two."); - assert(Align <= 0x40000000 && "Alignment too large."); - - Attrs.insert(Attribute::Alignment); - Alignment = Align; - return *this; -} - -AttrBuilder &AttrBuilder::addStackAlignmentAttr(unsigned Align) { - // Default alignment, allow the target to define how to align it. - if (Align == 0) return *this; - - assert(isPowerOf2_32(Align) && "Alignment must be a power of two."); - assert(Align <= 0x100 && "Alignment too large."); - - Attrs.insert(Attribute::StackAlignment); - StackAlignment = Align; - return *this; -} - -AttrBuilder &AttrBuilder::addRawValue(uint64_t Val) { - for (Attribute::AttrKind I = Attribute::None; I != Attribute::EndAttrKinds; - I = Attribute::AttrKind(I + 1)) { - if (uint64_t A = (Val & AttributeImpl::getAttrMask(I))) { - Attrs.insert(I); - - if (I == Attribute::Alignment) - Alignment = 1ULL << ((A >> 16) - 1); - else if (I == Attribute::StackAlignment) - StackAlignment = 1ULL << ((A >> 26)-1); - } - } - - return *this; -} - -bool AttrBuilder::contains(Attribute::AttrKind A) const { - return Attrs.count(A); -} - -bool AttrBuilder::hasAttributes() const { - return !Attrs.empty(); -} - -bool AttrBuilder::hasAttributes(const Attribute &A) const { - return Raw() & A.Raw(); +bool Attribute::operator==(AttrKind K) const { + return pImpl && *pImpl == K; } - -bool AttrBuilder::hasAlignmentAttr() const { - return Alignment != 0; +bool Attribute::operator!=(AttrKind K) const { + return !(*this == K); } -uint64_t AttrBuilder::Raw() const { - uint64_t Mask = 0; - - for (DenseSet::const_iterator I = Attrs.begin(), - E = Attrs.end(); I != E; ++I) { - Attribute::AttrKind Kind = *I; - - if (Kind == Attribute::Alignment) - Mask |= (Log2_32(Alignment) + 1) << 16; - else if (Kind == Attribute::StackAlignment) - Mask |= (Log2_32(StackAlignment) + 1) << 26; - else - Mask |= AttributeImpl::getAttrMask(Kind); - } - - return Mask; +bool Attribute::operator<(Attribute A) const { + if (!pImpl && !A.pImpl) return false; + if (!pImpl) return true; + if (!A.pImpl) return false; + return *pImpl < *A.pImpl; } -bool AttrBuilder::operator==(const AttrBuilder &B) { - SmallVector This(Attrs.begin(), Attrs.end()); - SmallVector That(B.Attrs.begin(), B.Attrs.end()); - return This == That; +uint64_t Attribute::Raw() const { + return pImpl ? pImpl->Raw() : 0; } //===----------------------------------------------------------------------===// // AttributeImpl Definition //===----------------------------------------------------------------------===// -AttributeImpl::AttributeImpl(LLVMContext &C, uint64_t data) - : Context(C) { - Data = ConstantInt::get(Type::getInt64Ty(C), data); -} AttributeImpl::AttributeImpl(LLVMContext &C, Attribute::AttrKind data) : Context(C) { Data = ConstantInt::get(Type::getInt64Ty(C), data); @@ -380,6 +207,24 @@ AttributeImpl::AttributeImpl(LLVMContext &C, StringRef data) Data = ConstantDataArray::getString(C, data); } +bool AttributeImpl::hasAttribute(Attribute::AttrKind A) const { + return (Raw() & getAttrMask(A)) != 0; +} + +bool AttributeImpl::hasAttributes() const { + return Raw() != 0; +} + +uint64_t AttributeImpl::getAlignment() const { + uint64_t Mask = Raw() & getAttrMask(Attribute::Alignment); + return 1ULL << ((Mask >> 16) - 1); +} + +uint64_t AttributeImpl::getStackAlignment() const { + uint64_t Mask = Raw() & getAttrMask(Attribute::StackAlignment); + return 1ULL << ((Mask >> 26) - 1); +} + bool AttributeImpl::operator==(Attribute::AttrKind Kind) const { if (ConstantInt *CI = dyn_cast(Data)) return CI->getZExtValue() == Kind; @@ -429,6 +274,7 @@ uint64_t AttributeImpl::Raw() const { } uint64_t AttributeImpl::getAttrMask(Attribute::AttrKind Val) { + // FIXME: Remove this. switch (Val) { case Attribute::EndAttrKinds: case Attribute::AttrKindEmptyKey: @@ -470,35 +316,6 @@ uint64_t AttributeImpl::getAttrMask(Attribute::AttrKind Val) { llvm_unreachable("Unsupported attribute type"); } -bool AttributeImpl::hasAttribute(Attribute::AttrKind A) const { - return (Raw() & getAttrMask(A)) != 0; -} - -bool AttributeImpl::hasAttributes() const { - return Raw() != 0; -} - -uint64_t AttributeImpl::getAlignment() const { - uint64_t Mask = Raw() & getAttrMask(Attribute::Alignment); - return 1ULL << ((Mask >> 16) - 1); -} - -uint64_t AttributeImpl::getStackAlignment() const { - uint64_t Mask = Raw() & getAttrMask(Attribute::StackAlignment); - return 1ULL << ((Mask >> 26) - 1); -} - -void AttributeImpl::Profile(FoldingSetNodeID &ID, Constant *Data, - ArrayRef Vals) { - ID.AddInteger(cast(Data)->getZExtValue()); -#if 0 - // FIXME: Not yet supported. - for (ArrayRef::iterator I = Vals.begin(), E = Vals.end(); - I != E; ++I) - ID.AddPointer(*I); -#endif -} - //===----------------------------------------------------------------------===// // AttributeSetNode Definition //===----------------------------------------------------------------------===// @@ -554,44 +371,15 @@ uint64_t AttributeSetImpl::Raw(uint64_t Index) const { } //===----------------------------------------------------------------------===// -// AttributeSet Method Implementations +// AttributeSet Construction and Mutation Methods //===----------------------------------------------------------------------===// -AttributeSet AttributeSet::getParamAttributes(unsigned Idx) const { - // FIXME: Remove. - return pImpl && hasAttributes(Idx) ? - AttributeSet::get(pImpl->getContext(), - ArrayRef >( - std::make_pair(Idx, getAttributes(Idx)))) : - AttributeSet(); -} - -AttributeSet AttributeSet::getRetAttributes() const { - // FIXME: Remove. - return pImpl && hasAttributes(ReturnIndex) ? - AttributeSet::get(pImpl->getContext(), - ArrayRef >( - std::make_pair(ReturnIndex, - getAttributes(ReturnIndex)))) : - AttributeSet(); -} - -AttributeSet AttributeSet::getFnAttributes() const { - // FIXME: Remove. - return pImpl && hasAttributes(FunctionIndex) ? - AttributeSet::get(pImpl->getContext(), - ArrayRef >( - std::make_pair(FunctionIndex, - getAttributes(FunctionIndex)))) : - AttributeSet(); -} - -AttributeSet AttributeSet::getImpl(LLVMContext &C, - ArrayRef > Attrs) { - LLVMContextImpl *pImpl = C.pImpl; - FoldingSetNodeID ID; - AttributeSetImpl::Profile(ID, Attrs); +AttributeSet AttributeSet::getImpl(LLVMContext &C, + ArrayRef > Attrs) { + LLVMContextImpl *pImpl = C.pImpl; + FoldingSetNodeID ID; + AttributeSetImpl::Profile(ID, Attrs); void *InsertPoint; AttributeSetImpl *PA = pImpl->AttrsLists.FindNodeOrInsertPos(ID, InsertPoint); @@ -668,6 +456,8 @@ AttributeSet AttributeSet::get(LLVMContext &C, unsigned Idx, } AttributeSet AttributeSet::get(LLVMContext &C, ArrayRef Attrs) { + if (Attrs.empty()) return AttributeSet(); + SmallVector, 8> AttrNodeVec; for (unsigned I = 0, E = Attrs.size(); I != E; ++I) { AttributeSet AS = Attrs[I]; @@ -675,85 +465,7 @@ AttributeSet AttributeSet::get(LLVMContext &C, ArrayRef Attrs) { AttrNodeVec.append(AS.pImpl->AttrNodes.begin(), AS.pImpl->AttrNodes.end()); } - return get(C, AttrNodeVec); -} - -/// \brief 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 AttributeSet::getNumSlots() const { - return pImpl ? pImpl->getNumAttributes() : 0; -} - -uint64_t AttributeSet::getSlotIndex(unsigned Slot) const { - assert(pImpl && Slot < pImpl->getNumAttributes() && - "Slot # out of range!"); - return pImpl->getSlotIndex(Slot); -} - -AttributeSet AttributeSet::getSlotAttributes(unsigned Slot) const { - assert(pImpl && Slot < pImpl->getNumAttributes() && - "Slot # out of range!"); - return pImpl->getSlotAttributes(Slot); -} - -bool AttributeSet::hasAttribute(unsigned Index, Attribute::AttrKind Kind) const{ - return getAttributes(Index).hasAttribute(Kind); -} - -bool AttributeSet::hasAttributes(unsigned Index) const { - return getAttributes(Index).hasAttributes(); -} - -std::string AttributeSet::getAsString(unsigned Index) const { - return getAttributes(Index).getAsString(); -} - -unsigned AttributeSet::getParamAlignment(unsigned Idx) const { - return getAttributes(Idx).getAlignment(); -} - -unsigned AttributeSet::getStackAlignment(unsigned Index) const { - return getAttributes(Index).getStackAlignment(); -} - -uint64_t AttributeSet::Raw(unsigned Index) const { - // FIXME: Remove this. - return pImpl ? pImpl->Raw(Index) : 0; -} - -/// \brief The attributes for the specified index are returned. -/// -/// FIXME: This shouldn't return 'Attribute'. -Attribute AttributeSet::getAttributes(unsigned Idx) const { - if (pImpl == 0) return Attribute(); - - // Loop through to find the attribute we want. - for (unsigned I = 0, E = pImpl->getNumAttributes(); I != E; ++I) { - if (pImpl->getSlotIndex(I) != Idx) continue; - - AttrBuilder B; - for (AttributeSetImpl::const_iterator II = pImpl->begin(I), - IE = pImpl->end(I); II != IE; ++II) - B.addAttributes(*II); - return Attribute::get(pImpl->getContext(), B); - } - - return Attribute(); -} - -/// hasAttrSomewhere - Return true if the specified attribute is set for at -/// least one parameter or for the return value. -bool AttributeSet::hasAttrSomewhere(Attribute::AttrKind Attr) const { - if (pImpl == 0) return false; - - for (unsigned I = 0, E = pImpl->getNumAttributes(); I != E; ++I) - for (AttributeSetImpl::const_iterator II = pImpl->begin(I), - IE = pImpl->end(I); II != IE; ++II) - if (II->hasAttribute(Attr)) - return true; - - return false; + return getImpl(C, AttrNodeVec); } AttributeSet AttributeSet::addAttribute(LLVMContext &C, unsigned Idx, @@ -862,8 +574,121 @@ AttributeSet AttributeSet::removeAttributes(LLVMContext &C, unsigned Idx, return get(C, AttrSet); } +//===----------------------------------------------------------------------===// +// AttributeSet Accessor Methods +//===----------------------------------------------------------------------===// + +AttributeSet AttributeSet::getParamAttributes(unsigned Idx) const { + return pImpl && hasAttributes(Idx) ? + AttributeSet::get(pImpl->getContext(), + ArrayRef >( + std::make_pair(Idx, getAttributes(Idx)))) : + AttributeSet(); +} + +AttributeSet AttributeSet::getRetAttributes() const { + return pImpl && hasAttributes(ReturnIndex) ? + AttributeSet::get(pImpl->getContext(), + ArrayRef >( + std::make_pair(ReturnIndex, + getAttributes(ReturnIndex)))) : + AttributeSet(); +} + +AttributeSet AttributeSet::getFnAttributes() const { + return pImpl && hasAttributes(FunctionIndex) ? + AttributeSet::get(pImpl->getContext(), + ArrayRef >( + std::make_pair(FunctionIndex, + getAttributes(FunctionIndex)))) : + AttributeSet(); +} + +bool AttributeSet::hasAttribute(unsigned Index, Attribute::AttrKind Kind) const{ + return getAttributes(Index).hasAttribute(Kind); +} + +bool AttributeSet::hasAttributes(unsigned Index) const { + return getAttributes(Index).hasAttributes(); +} + +/// \brief Return true if the specified attribute is set for at least one +/// parameter or for the return value. +bool AttributeSet::hasAttrSomewhere(Attribute::AttrKind Attr) const { + if (pImpl == 0) return false; + + for (unsigned I = 0, E = pImpl->getNumAttributes(); I != E; ++I) + for (AttributeSetImpl::const_iterator II = pImpl->begin(I), + IE = pImpl->end(I); II != IE; ++II) + if (II->hasAttribute(Attr)) + return true; + + return false; +} + +unsigned AttributeSet::getParamAlignment(unsigned Idx) const { + return getAttributes(Idx).getAlignment(); +} + +unsigned AttributeSet::getStackAlignment(unsigned Index) const { + return getAttributes(Index).getStackAlignment(); +} + +std::string AttributeSet::getAsString(unsigned Index) const { + return getAttributes(Index).getAsString(); +} + +/// \brief The attributes for the specified index are returned. +/// +/// FIXME: This shouldn't return 'Attribute'. +Attribute AttributeSet::getAttributes(unsigned Idx) const { + if (pImpl == 0) return Attribute(); + + // Loop through to find the attribute we want. + for (unsigned I = 0, E = pImpl->getNumAttributes(); I != E; ++I) { + if (pImpl->getSlotIndex(I) != Idx) continue; + + AttrBuilder B; + for (AttributeSetImpl::const_iterator II = pImpl->begin(I), + IE = pImpl->end(I); II != IE; ++II) + B.addAttributes(*II); + return Attribute::get(pImpl->getContext(), B); + } + + return Attribute(); +} + +//===----------------------------------------------------------------------===// +// AttributeSet Introspection Methods +//===----------------------------------------------------------------------===// + +/// \brief 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 AttributeSet::getNumSlots() const { + return pImpl ? pImpl->getNumAttributes() : 0; +} + +uint64_t AttributeSet::getSlotIndex(unsigned Slot) const { + assert(pImpl && Slot < pImpl->getNumAttributes() && + "Slot # out of range!"); + return pImpl->getSlotIndex(Slot); +} + +AttributeSet AttributeSet::getSlotAttributes(unsigned Slot) const { + assert(pImpl && Slot < pImpl->getNumAttributes() && + "Slot # out of range!"); + return pImpl->getSlotAttributes(Slot); +} + +uint64_t AttributeSet::Raw(unsigned Index) const { + // FIXME: Remove this. + return pImpl ? pImpl->Raw(Index) : 0; +} + void AttributeSet::dump() const { dbgs() << "PAL[\n"; + for (unsigned i = 0, e = getNumSlots(); i < e; ++i) { uint64_t Index = getSlotIndex(i); dbgs() << " { "; @@ -878,6 +703,176 @@ void AttributeSet::dump() const { } //===----------------------------------------------------------------------===// +// AttrBuilder Method Implementations +//===----------------------------------------------------------------------===// + +AttrBuilder::AttrBuilder(AttributeSet AS, unsigned Idx) + : Alignment(0), StackAlignment(0) { + AttributeSetImpl *pImpl = AS.pImpl; + if (!pImpl) return; + + AttrBuilder B; + + for (unsigned I = 0, E = pImpl->getNumAttributes(); I != E; ++I) { + if (pImpl->getSlotIndex(I) != Idx) continue; + + for (AttributeSetNode::const_iterator II = pImpl->begin(I), + IE = pImpl->end(I); II != IE; ++II) + B.addAttributes(*II); + + break; + } + + if (!B.hasAttributes()) return; + + uint64_t Mask = B.Raw(); + + for (Attribute::AttrKind I = Attribute::None; I != Attribute::EndAttrKinds; + I = Attribute::AttrKind(I + 1)) { + if (uint64_t A = (Mask & AttributeImpl::getAttrMask(I))) { + Attrs.insert(I); + + if (I == Attribute::Alignment) + Alignment = 1ULL << ((A >> 16) - 1); + else if (I == Attribute::StackAlignment) + StackAlignment = 1ULL << ((A >> 26)-1); + } + } +} + +void AttrBuilder::clear() { + Attrs.clear(); + Alignment = StackAlignment = 0; +} + +AttrBuilder &AttrBuilder::addAttribute(Attribute::AttrKind Val) { + Attrs.insert(Val); + return *this; +} + +AttrBuilder &AttrBuilder::removeAttribute(Attribute::AttrKind Val) { + Attrs.erase(Val); + if (Val == Attribute::Alignment) + Alignment = 0; + else if (Val == Attribute::StackAlignment) + StackAlignment = 0; + + return *this; +} + +AttrBuilder &AttrBuilder::addAttributes(Attribute Attr) { + uint64_t Mask = Attr.Raw(); + + for (Attribute::AttrKind I = Attribute::None; I != Attribute::EndAttrKinds; + I = Attribute::AttrKind(I + 1)) + if ((Mask & AttributeImpl::getAttrMask(I)) != 0) + Attrs.insert(I); + + if (Attr.getAlignment()) + Alignment = Attr.getAlignment(); + if (Attr.getStackAlignment()) + StackAlignment = Attr.getStackAlignment(); + return *this; +} + +AttrBuilder &AttrBuilder::removeAttributes(Attribute A) { + uint64_t Mask = A.Raw(); + + for (Attribute::AttrKind I = Attribute::None; I != Attribute::EndAttrKinds; + I = Attribute::AttrKind(I + 1)) { + if (Mask & AttributeImpl::getAttrMask(I)) { + Attrs.erase(I); + + if (I == Attribute::Alignment) + Alignment = 0; + else if (I == Attribute::StackAlignment) + StackAlignment = 0; + } + } + + return *this; +} + +AttrBuilder &AttrBuilder::addAlignmentAttr(unsigned Align) { + if (Align == 0) return *this; + + assert(isPowerOf2_32(Align) && "Alignment must be a power of two."); + assert(Align <= 0x40000000 && "Alignment too large."); + + Attrs.insert(Attribute::Alignment); + Alignment = Align; + return *this; +} + +AttrBuilder &AttrBuilder::addStackAlignmentAttr(unsigned Align) { + // Default alignment, allow the target to define how to align it. + if (Align == 0) return *this; + + assert(isPowerOf2_32(Align) && "Alignment must be a power of two."); + assert(Align <= 0x100 && "Alignment too large."); + + Attrs.insert(Attribute::StackAlignment); + StackAlignment = Align; + return *this; +} + +bool AttrBuilder::contains(Attribute::AttrKind A) const { + return Attrs.count(A); +} + +bool AttrBuilder::hasAttributes() const { + return !Attrs.empty(); +} + +bool AttrBuilder::hasAttributes(const Attribute &A) const { + return Raw() & A.Raw(); +} + +bool AttrBuilder::hasAlignmentAttr() const { + return Alignment != 0; +} + +bool AttrBuilder::operator==(const AttrBuilder &B) { + SmallVector This(Attrs.begin(), Attrs.end()); + SmallVector That(B.Attrs.begin(), B.Attrs.end()); + return This == That; +} + +AttrBuilder &AttrBuilder::addRawValue(uint64_t Val) { + for (Attribute::AttrKind I = Attribute::None; I != Attribute::EndAttrKinds; + I = Attribute::AttrKind(I + 1)) { + if (uint64_t A = (Val & AttributeImpl::getAttrMask(I))) { + Attrs.insert(I); + + if (I == Attribute::Alignment) + Alignment = 1ULL << ((A >> 16) - 1); + else if (I == Attribute::StackAlignment) + StackAlignment = 1ULL << ((A >> 26)-1); + } + } + + return *this; +} + +uint64_t AttrBuilder::Raw() const { + uint64_t Mask = 0; + + for (DenseSet::const_iterator I = Attrs.begin(), + E = Attrs.end(); I != E; ++I) { + Attribute::AttrKind Kind = *I; + + if (Kind == Attribute::Alignment) + Mask |= (Log2_32(Alignment) + 1) << 16; + else if (Kind == Attribute::StackAlignment) + Mask |= (Log2_32(StackAlignment) + 1) << 26; + else + Mask |= AttributeImpl::getAttrMask(Kind); + } + + return Mask; +} + +//===----------------------------------------------------------------------===// // AttributeFuncs Function Defintions //===----------------------------------------------------------------------===// @@ -900,9 +895,9 @@ Attribute AttributeFuncs::typeIncompatible(Type *Ty) { return Attribute::get(Ty->getContext(), Incompatible); } -/// 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. +/// \brief 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. uint64_t AttributeFuncs::encodeLLVMAttributesForBitcode(AttributeSet Attrs, unsigned Index) { // FIXME: It doesn't make sense to store the alignment information as an @@ -921,9 +916,9 @@ uint64_t AttributeFuncs::encodeLLVMAttributesForBitcode(AttributeSet Attrs, return EncodedAttrs; } -/// 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'. +/// \brief 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'. Attribute AttributeFuncs::decodeLLVMAttributesForBitcode(LLVMContext &C, uint64_t EncodedAttrs){ // The alignment is stored as a 16-bit raw value from bits 31--16. We shift -- 2.7.4