From c22f4aa886443507f8406d30d118fdeeac6a8c6c 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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@173733 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/IR/Attributes.h | 101 +-- lib/IR/AttributeImpl.h | 25 +- lib/IR/Attributes.cpp | 1133 +++++++++++++++++----------------- 3 files changed, 632 insertions(+), 627 deletions(-) diff --git a/include/llvm/IR/Attributes.h b/include/llvm/IR/Attributes.h index 15b664cd3f9..a95ede17604 100644 --- a/include/llvm/IR/Attributes.h +++ b/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,37 +152,14 @@ 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; @@ -340,6 +326,26 @@ public: void dump() 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; + } +}; + //===----------------------------------------------------------------------===// /// \class /// \brief This class is used in conjunction with the Attribute::get method to @@ -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/lib/IR/AttributeImpl.h b/lib/IR/AttributeImpl.h index c00f0943146..34754e8e543 100644 --- a/lib/IR/AttributeImpl.h +++ b/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/lib/IR/Attributes.cpp b/lib/IR/Attributes.cpp index ac394b77e7e..f56eb7be9ce 100644 --- a/lib/IR/Attributes.cpp +++ b/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,6 +169,539 @@ std::string Attribute::getAsString() const { return Result; } +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; +} + +//===----------------------------------------------------------------------===// +// AttributeImpl Definition +//===----------------------------------------------------------------------===// + +AttributeImpl::AttributeImpl(LLVMContext &C, Attribute::AttrKind data) + : Context(C) { + Data = ConstantInt::get(Type::getInt64Ty(C), data); +} +AttributeImpl::AttributeImpl(LLVMContext &C, Attribute::AttrKind data, + ArrayRef 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) + : Context(C) { + 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; + return false; +} +bool AttributeImpl::operator!=(Attribute::AttrKind Kind) const { + return !(*this == Kind); +} + +bool AttributeImpl::operator==(StringRef Kind) const { + if (ConstantDataArray *CDA = dyn_cast(Data)) + if (CDA->isString()) + return CDA->getAsString() == Kind; + return false; +} + +bool AttributeImpl::operator!=(StringRef Kind) const { + return !(*this == Kind); +} + +bool AttributeImpl::operator<(const AttributeImpl &AI) const { + if (!Data && !AI.Data) return false; + if (!Data && AI.Data) return true; + if (Data && !AI.Data) return false; + + ConstantInt *ThisCI = dyn_cast(Data); + ConstantInt *ThatCI = dyn_cast(AI.Data); + + ConstantDataArray *ThisCDA = dyn_cast(Data); + ConstantDataArray *ThatCDA = dyn_cast(AI.Data); + + if (ThisCI && ThatCI) + return ThisCI->getZExtValue() < ThatCI->getZExtValue(); + + if (ThisCI && ThatCDA) + return true; + + if (ThisCDA && ThatCI) + return false; + + return ThisCDA->getAsString() < ThatCDA->getAsString(); +} + +uint64_t AttributeImpl::Raw() const { + // FIXME: Remove this. + return cast(Data)->getZExtValue(); +} + +uint64_t AttributeImpl::getAttrMask(Attribute::AttrKind Val) { + // FIXME: Remove this. + switch (Val) { + case Attribute::EndAttrKinds: + case Attribute::AttrKindEmptyKey: + case Attribute::AttrKindTombstoneKey: + llvm_unreachable("Synthetic enumerators which should never get here"); + + case Attribute::None: return 0; + case Attribute::ZExt: return 1 << 0; + case Attribute::SExt: return 1 << 1; + case Attribute::NoReturn: return 1 << 2; + case Attribute::InReg: return 1 << 3; + case Attribute::StructRet: return 1 << 4; + case Attribute::NoUnwind: return 1 << 5; + case Attribute::NoAlias: return 1 << 6; + case Attribute::ByVal: return 1 << 7; + case Attribute::Nest: return 1 << 8; + case Attribute::ReadNone: return 1 << 9; + case Attribute::ReadOnly: return 1 << 10; + case Attribute::NoInline: return 1 << 11; + case Attribute::AlwaysInline: return 1 << 12; + case Attribute::OptimizeForSize: return 1 << 13; + case Attribute::StackProtect: return 1 << 14; + case Attribute::StackProtectReq: return 1 << 15; + case Attribute::Alignment: return 31 << 16; + case Attribute::NoCapture: return 1 << 21; + case Attribute::NoRedZone: return 1 << 22; + case Attribute::NoImplicitFloat: return 1 << 23; + case Attribute::Naked: return 1 << 24; + case Attribute::InlineHint: return 1 << 25; + case Attribute::StackAlignment: return 7 << 26; + case Attribute::ReturnsTwice: return 1 << 29; + case Attribute::UWTable: return 1 << 30; + case Attribute::NonLazyBind: return 1U << 31; + case Attribute::AddressSafety: return 1ULL << 32; + case Attribute::MinSize: return 1ULL << 33; + case Attribute::NoDuplicate: return 1ULL << 34; + case Attribute::StackProtectStrong: return 1ULL << 35; + } + llvm_unreachable("Unsupported attribute type"); +} + +//===----------------------------------------------------------------------===// +// AttributeSetNode Definition +//===----------------------------------------------------------------------===// + +AttributeSetNode *AttributeSetNode::get(LLVMContext &C, + ArrayRef Attrs) { + if (Attrs.empty()) + return 0; + + // Otherwise, build a key to look up the existing attributes. + LLVMContextImpl *pImpl = C.pImpl; + FoldingSetNodeID ID; + + SmallVector SortedAttrs(Attrs.begin(), Attrs.end()); + std::sort(SortedAttrs.begin(), SortedAttrs.end()); + + for (SmallVectorImpl::iterator I = SortedAttrs.begin(), + E = SortedAttrs.end(); I != E; ++I) + I->Profile(ID); + + void *InsertPoint; + AttributeSetNode *PA = + pImpl->AttrsSetNodes.FindNodeOrInsertPos(ID, InsertPoint); + + // If we didn't find any existing attributes of the same shape then create a + // new one and insert it. + if (!PA) { + PA = new AttributeSetNode(SortedAttrs); + pImpl->AttrsSetNodes.InsertNode(PA, InsertPoint); + } + + // Return the AttributesListNode that we found or created. + return PA; +} + +//===----------------------------------------------------------------------===// +// AttributeSetImpl Definition +//===----------------------------------------------------------------------===// + +uint64_t AttributeSetImpl::Raw(uint64_t Index) const { + for (unsigned I = 0, E = getNumAttributes(); I != E; ++I) { + if (getSlotIndex(I) != Index) continue; + const AttributeSetNode *ASN = AttrNodes[I].second; + AttrBuilder B; + + for (AttributeSetNode::const_iterator II = ASN->begin(), + IE = ASN->end(); II != IE; ++II) + B.addAttributes(*II); + return B.Raw(); + } + + return 0; +} + +//===----------------------------------------------------------------------===// +// AttributeSet Construction and Mutation Methods +//===----------------------------------------------------------------------===// + +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); + + // If we didn't find any existing attributes of the same shape then + // create a new one and insert it. + if (!PA) { + PA = new AttributeSetImpl(C, Attrs); + pImpl->AttrsLists.InsertNode(PA, InsertPoint); + } + + // Return the AttributesList that we found or created. + return AttributeSet(PA); +} + +AttributeSet AttributeSet::get(LLVMContext &C, + ArrayRef > Attrs){ + // If there are no attributes then return a null AttributesList pointer. + if (Attrs.empty()) + return AttributeSet(); + +#ifndef NDEBUG + for (unsigned i = 0, e = Attrs.size(); i != e; ++i) { + assert((!i || Attrs[i-1].first <= Attrs[i].first) && + "Misordered Attributes list!"); + assert(Attrs[i].second.hasAttributes() && + "Pointless attribute!"); + } +#endif + + // Create a vector if (unsigned, AttributeSetNode*) pairs from the attributes + // list. + SmallVector, 8> AttrPairVec; + for (ArrayRef >::iterator I = Attrs.begin(), + E = Attrs.end(); I != E; ) { + unsigned Index = I->first; + SmallVector AttrVec; + while (I->first == Index && I != E) { + AttrVec.push_back(I->second); + ++I; + } + + AttrPairVec.push_back(std::make_pair(Index, + AttributeSetNode::get(C, AttrVec))); + } + + return getImpl(C, AttrPairVec); +} + +AttributeSet AttributeSet::get(LLVMContext &C, + ArrayRef > Attrs) { + // If there are no attributes then return a null AttributesList pointer. + if (Attrs.empty()) + return AttributeSet(); + + return getImpl(C, Attrs); +} + +AttributeSet AttributeSet::get(LLVMContext &C, unsigned Idx, AttrBuilder &B) { + if (!B.hasAttributes()) + return AttributeSet(); + return get(C, ArrayRef >( + std::make_pair(Idx, Attribute::get(C, B)))); +} + +AttributeSet AttributeSet::get(LLVMContext &C, unsigned Idx, + ArrayRef Kind) { + SmallVector, 8> Attrs; + for (ArrayRef::iterator I = Kind.begin(), + E = Kind.end(); I != E; ++I) + Attrs.push_back(std::make_pair(Idx, Attribute::get(C, *I))); + return get(C, Attrs); +} + +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]; + if (!AS.pImpl) continue; + AttrNodeVec.append(AS.pImpl->AttrNodes.begin(), AS.pImpl->AttrNodes.end()); + } + + return getImpl(C, AttrNodeVec); +} + +AttributeSet AttributeSet::addAttribute(LLVMContext &C, unsigned Idx, + Attribute::AttrKind Attr) const { + return addAttributes(C, Idx, AttributeSet::get(C, Idx, Attr)); +} + +AttributeSet AttributeSet::addAttributes(LLVMContext &C, unsigned Idx, + AttributeSet Attrs) const { + if (!pImpl) return Attrs; + if (!Attrs.pImpl) return *this; + +#ifndef NDEBUG + // FIXME it is not obvious how this should work for alignment. For now, say + // we can't change a known alignment. + unsigned OldAlign = getParamAlignment(Idx); + unsigned NewAlign = Attrs.getParamAlignment(Idx); + assert((!OldAlign || !NewAlign || OldAlign == NewAlign) && + "Attempt to change alignment!"); +#endif + + // Add the attribute slots before the one we're trying to add. + SmallVector AttrSet; + uint64_t NumAttrs = pImpl->getNumAttributes(); + AttributeSet AS; + uint64_t LastIndex = 0; + for (unsigned I = 0, E = NumAttrs; I != E; ++I) { + if (getSlotIndex(I) >= Idx) { + if (getSlotIndex(I) == Idx) AS = getSlotAttributes(LastIndex++); + break; + } + LastIndex = I + 1; + AttrSet.push_back(getSlotAttributes(I)); + } + + // Now add the attribute into the correct slot. There may already be an + // AttributeSet there. + AttrBuilder B(AS, Idx); + + for (unsigned I = 0, E = Attrs.pImpl->getNumAttributes(); I != E; ++I) + if (Attrs.getSlotIndex(I) == Idx) { + for (AttributeSetImpl::const_iterator II = Attrs.pImpl->begin(I), + IE = Attrs.pImpl->end(I); II != IE; ++II) + B.addAttributes(*II); + break; + } + + AttrSet.push_back(AttributeSet::get(C, Idx, B)); + + // Add the remaining attribute slots. + for (unsigned I = LastIndex, E = NumAttrs; I < E; ++I) + AttrSet.push_back(getSlotAttributes(I)); + + return get(C, AttrSet); +} + +AttributeSet AttributeSet::removeAttribute(LLVMContext &C, unsigned Idx, + Attribute::AttrKind Attr) const { + return removeAttributes(C, Idx, AttributeSet::get(C, Idx, Attr)); +} + +AttributeSet AttributeSet::removeAttributes(LLVMContext &C, unsigned Idx, + AttributeSet Attrs) const { + if (!pImpl) return AttributeSet(); + if (!Attrs.pImpl) return *this; + +#ifndef NDEBUG + // FIXME it is not obvious how this should work for alignment. + // For now, say we can't pass in alignment, which no current use does. + assert(!Attrs.hasAttribute(Idx, Attribute::Alignment) && + "Attempt to change alignment!"); +#endif + + // Add the attribute slots before the one we're trying to add. + SmallVector AttrSet; + uint64_t NumAttrs = pImpl->getNumAttributes(); + AttributeSet AS; + uint64_t LastIndex = 0; + for (unsigned I = 0, E = NumAttrs; I != E; ++I) { + if (getSlotIndex(I) >= Idx) { + if (getSlotIndex(I) == Idx) AS = getSlotAttributes(LastIndex++); + break; + } + LastIndex = I + 1; + AttrSet.push_back(getSlotAttributes(I)); + } + + // Now add the attribute into the correct slot. There may already be an + // AttributeSet there. + AttrBuilder B(AS, Idx); + + for (unsigned I = 0, E = Attrs.pImpl->getNumAttributes(); I != E; ++I) + if (Attrs.getSlotIndex(I) == Idx) { + for (AttributeSetImpl::const_iterator II = Attrs.pImpl->begin(I), + IE = Attrs.pImpl->end(I); II != IE; ++II) + B.removeAttributes(*II); + break; + } + + AttrSet.push_back(AttributeSet::get(C, Idx, B)); + + // Add the remaining attribute slots. + for (unsigned I = LastIndex, E = NumAttrs; I < E; ++I) + AttrSet.push_back(getSlotAttributes(I)); + + 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() << " { "; + if (Index == ~0U) + dbgs() << "~0U"; + else + dbgs() << Index; + dbgs() << " => " << getAsString(Index) << " }\n"; + } + + dbgs() << "]\n"; +} + //===----------------------------------------------------------------------===// // AttrBuilder Method Implementations //===----------------------------------------------------------------------===// @@ -300,22 +816,6 @@ AttrBuilder &AttrBuilder::addStackAlignmentAttr(unsigned 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); } @@ -332,6 +832,28 @@ 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; @@ -350,533 +872,6 @@ uint64_t AttrBuilder::Raw() const { return Mask; } -bool AttrBuilder::operator==(const AttrBuilder &B) { - SmallVector This(Attrs.begin(), Attrs.end()); - SmallVector That(B.Attrs.begin(), B.Attrs.end()); - return This == That; -} - -//===----------------------------------------------------------------------===// -// 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); -} -AttributeImpl::AttributeImpl(LLVMContext &C, Attribute::AttrKind data, - ArrayRef 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) - : Context(C) { - Data = ConstantDataArray::getString(C, data); -} - -bool AttributeImpl::operator==(Attribute::AttrKind Kind) const { - if (ConstantInt *CI = dyn_cast(Data)) - return CI->getZExtValue() == Kind; - return false; -} -bool AttributeImpl::operator!=(Attribute::AttrKind Kind) const { - return !(*this == Kind); -} - -bool AttributeImpl::operator==(StringRef Kind) const { - if (ConstantDataArray *CDA = dyn_cast(Data)) - if (CDA->isString()) - return CDA->getAsString() == Kind; - return false; -} - -bool AttributeImpl::operator!=(StringRef Kind) const { - return !(*this == Kind); -} - -bool AttributeImpl::operator<(const AttributeImpl &AI) const { - if (!Data && !AI.Data) return false; - if (!Data && AI.Data) return true; - if (Data && !AI.Data) return false; - - ConstantInt *ThisCI = dyn_cast(Data); - ConstantInt *ThatCI = dyn_cast(AI.Data); - - ConstantDataArray *ThisCDA = dyn_cast(Data); - ConstantDataArray *ThatCDA = dyn_cast(AI.Data); - - if (ThisCI && ThatCI) - return ThisCI->getZExtValue() < ThatCI->getZExtValue(); - - if (ThisCI && ThatCDA) - return true; - - if (ThisCDA && ThatCI) - return false; - - return ThisCDA->getAsString() < ThatCDA->getAsString(); -} - -uint64_t AttributeImpl::Raw() const { - // FIXME: Remove this. - return cast(Data)->getZExtValue(); -} - -uint64_t AttributeImpl::getAttrMask(Attribute::AttrKind Val) { - switch (Val) { - case Attribute::EndAttrKinds: - case Attribute::AttrKindEmptyKey: - case Attribute::AttrKindTombstoneKey: - llvm_unreachable("Synthetic enumerators which should never get here"); - - case Attribute::None: return 0; - case Attribute::ZExt: return 1 << 0; - case Attribute::SExt: return 1 << 1; - case Attribute::NoReturn: return 1 << 2; - case Attribute::InReg: return 1 << 3; - case Attribute::StructRet: return 1 << 4; - case Attribute::NoUnwind: return 1 << 5; - case Attribute::NoAlias: return 1 << 6; - case Attribute::ByVal: return 1 << 7; - case Attribute::Nest: return 1 << 8; - case Attribute::ReadNone: return 1 << 9; - case Attribute::ReadOnly: return 1 << 10; - case Attribute::NoInline: return 1 << 11; - case Attribute::AlwaysInline: return 1 << 12; - case Attribute::OptimizeForSize: return 1 << 13; - case Attribute::StackProtect: return 1 << 14; - case Attribute::StackProtectReq: return 1 << 15; - case Attribute::Alignment: return 31 << 16; - case Attribute::NoCapture: return 1 << 21; - case Attribute::NoRedZone: return 1 << 22; - case Attribute::NoImplicitFloat: return 1 << 23; - case Attribute::Naked: return 1 << 24; - case Attribute::InlineHint: return 1 << 25; - case Attribute::StackAlignment: return 7 << 26; - case Attribute::ReturnsTwice: return 1 << 29; - case Attribute::UWTable: return 1 << 30; - case Attribute::NonLazyBind: return 1U << 31; - case Attribute::AddressSafety: return 1ULL << 32; - case Attribute::MinSize: return 1ULL << 33; - case Attribute::NoDuplicate: return 1ULL << 34; - case Attribute::StackProtectStrong: return 1ULL << 35; - } - 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 -//===----------------------------------------------------------------------===// - -AttributeSetNode *AttributeSetNode::get(LLVMContext &C, - ArrayRef Attrs) { - if (Attrs.empty()) - return 0; - - // Otherwise, build a key to look up the existing attributes. - LLVMContextImpl *pImpl = C.pImpl; - FoldingSetNodeID ID; - - SmallVector SortedAttrs(Attrs.begin(), Attrs.end()); - std::sort(SortedAttrs.begin(), SortedAttrs.end()); - - for (SmallVectorImpl::iterator I = SortedAttrs.begin(), - E = SortedAttrs.end(); I != E; ++I) - I->Profile(ID); - - void *InsertPoint; - AttributeSetNode *PA = - pImpl->AttrsSetNodes.FindNodeOrInsertPos(ID, InsertPoint); - - // If we didn't find any existing attributes of the same shape then create a - // new one and insert it. - if (!PA) { - PA = new AttributeSetNode(SortedAttrs); - pImpl->AttrsSetNodes.InsertNode(PA, InsertPoint); - } - - // Return the AttributesListNode that we found or created. - return PA; -} - -//===----------------------------------------------------------------------===// -// AttributeSetImpl Definition -//===----------------------------------------------------------------------===// - -uint64_t AttributeSetImpl::Raw(uint64_t Index) const { - for (unsigned I = 0, E = getNumAttributes(); I != E; ++I) { - if (getSlotIndex(I) != Index) continue; - const AttributeSetNode *ASN = AttrNodes[I].second; - AttrBuilder B; - - for (AttributeSetNode::const_iterator II = ASN->begin(), - IE = ASN->end(); II != IE; ++II) - B.addAttributes(*II); - return B.Raw(); - } - - return 0; -} - -//===----------------------------------------------------------------------===// -// AttributeSet Method Implementations -//===----------------------------------------------------------------------===// - -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); - - void *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. - if (!PA) { - PA = new AttributeSetImpl(C, Attrs); - pImpl->AttrsLists.InsertNode(PA, InsertPoint); - } - - // Return the AttributesList that we found or created. - return AttributeSet(PA); -} - -AttributeSet AttributeSet::get(LLVMContext &C, - ArrayRef > Attrs){ - // If there are no attributes then return a null AttributesList pointer. - if (Attrs.empty()) - return AttributeSet(); - -#ifndef NDEBUG - for (unsigned i = 0, e = Attrs.size(); i != e; ++i) { - assert((!i || Attrs[i-1].first <= Attrs[i].first) && - "Misordered Attributes list!"); - assert(Attrs[i].second.hasAttributes() && - "Pointless attribute!"); - } -#endif - - // Create a vector if (unsigned, AttributeSetNode*) pairs from the attributes - // list. - SmallVector, 8> AttrPairVec; - for (ArrayRef >::iterator I = Attrs.begin(), - E = Attrs.end(); I != E; ) { - unsigned Index = I->first; - SmallVector AttrVec; - while (I->first == Index && I != E) { - AttrVec.push_back(I->second); - ++I; - } - - AttrPairVec.push_back(std::make_pair(Index, - AttributeSetNode::get(C, AttrVec))); - } - - return getImpl(C, AttrPairVec); -} - -AttributeSet AttributeSet::get(LLVMContext &C, - ArrayRef > Attrs) { - // If there are no attributes then return a null AttributesList pointer. - if (Attrs.empty()) - return AttributeSet(); - - return getImpl(C, Attrs); -} - -AttributeSet AttributeSet::get(LLVMContext &C, unsigned Idx, AttrBuilder &B) { - if (!B.hasAttributes()) - return AttributeSet(); - return get(C, ArrayRef >( - std::make_pair(Idx, Attribute::get(C, B)))); -} - -AttributeSet AttributeSet::get(LLVMContext &C, unsigned Idx, - ArrayRef Kind) { - SmallVector, 8> Attrs; - for (ArrayRef::iterator I = Kind.begin(), - E = Kind.end(); I != E; ++I) - Attrs.push_back(std::make_pair(Idx, Attribute::get(C, *I))); - return get(C, Attrs); -} - -AttributeSet AttributeSet::get(LLVMContext &C, ArrayRef Attrs) { - SmallVector, 8> AttrNodeVec; - for (unsigned I = 0, E = Attrs.size(); I != E; ++I) { - AttributeSet AS = Attrs[I]; - if (!AS.pImpl) continue; - 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; -} - -AttributeSet AttributeSet::addAttribute(LLVMContext &C, unsigned Idx, - Attribute::AttrKind Attr) const { - return addAttributes(C, Idx, AttributeSet::get(C, Idx, Attr)); -} - -AttributeSet AttributeSet::addAttributes(LLVMContext &C, unsigned Idx, - AttributeSet Attrs) const { - if (!pImpl) return Attrs; - if (!Attrs.pImpl) return *this; - -#ifndef NDEBUG - // FIXME it is not obvious how this should work for alignment. For now, say - // we can't change a known alignment. - unsigned OldAlign = getParamAlignment(Idx); - unsigned NewAlign = Attrs.getParamAlignment(Idx); - assert((!OldAlign || !NewAlign || OldAlign == NewAlign) && - "Attempt to change alignment!"); -#endif - - // Add the attribute slots before the one we're trying to add. - SmallVector AttrSet; - uint64_t NumAttrs = pImpl->getNumAttributes(); - AttributeSet AS; - uint64_t LastIndex = 0; - for (unsigned I = 0, E = NumAttrs; I != E; ++I) { - if (getSlotIndex(I) >= Idx) { - if (getSlotIndex(I) == Idx) AS = getSlotAttributes(LastIndex++); - break; - } - LastIndex = I + 1; - AttrSet.push_back(getSlotAttributes(I)); - } - - // Now add the attribute into the correct slot. There may already be an - // AttributeSet there. - AttrBuilder B(AS, Idx); - - for (unsigned I = 0, E = Attrs.pImpl->getNumAttributes(); I != E; ++I) - if (Attrs.getSlotIndex(I) == Idx) { - for (AttributeSetImpl::const_iterator II = Attrs.pImpl->begin(I), - IE = Attrs.pImpl->end(I); II != IE; ++II) - B.addAttributes(*II); - break; - } - - AttrSet.push_back(AttributeSet::get(C, Idx, B)); - - // Add the remaining attribute slots. - for (unsigned I = LastIndex, E = NumAttrs; I < E; ++I) - AttrSet.push_back(getSlotAttributes(I)); - - return get(C, AttrSet); -} - -AttributeSet AttributeSet::removeAttribute(LLVMContext &C, unsigned Idx, - Attribute::AttrKind Attr) const { - return removeAttributes(C, Idx, AttributeSet::get(C, Idx, Attr)); -} - -AttributeSet AttributeSet::removeAttributes(LLVMContext &C, unsigned Idx, - AttributeSet Attrs) const { - if (!pImpl) return AttributeSet(); - if (!Attrs.pImpl) return *this; - -#ifndef NDEBUG - // FIXME it is not obvious how this should work for alignment. - // For now, say we can't pass in alignment, which no current use does. - assert(!Attrs.hasAttribute(Idx, Attribute::Alignment) && - "Attempt to change alignment!"); -#endif - - // Add the attribute slots before the one we're trying to add. - SmallVector AttrSet; - uint64_t NumAttrs = pImpl->getNumAttributes(); - AttributeSet AS; - uint64_t LastIndex = 0; - for (unsigned I = 0, E = NumAttrs; I != E; ++I) { - if (getSlotIndex(I) >= Idx) { - if (getSlotIndex(I) == Idx) AS = getSlotAttributes(LastIndex++); - break; - } - LastIndex = I + 1; - AttrSet.push_back(getSlotAttributes(I)); - } - - // Now add the attribute into the correct slot. There may already be an - // AttributeSet there. - AttrBuilder B(AS, Idx); - - for (unsigned I = 0, E = Attrs.pImpl->getNumAttributes(); I != E; ++I) - if (Attrs.getSlotIndex(I) == Idx) { - for (AttributeSetImpl::const_iterator II = Attrs.pImpl->begin(I), - IE = Attrs.pImpl->end(I); II != IE; ++II) - B.removeAttributes(*II); - break; - } - - AttrSet.push_back(AttributeSet::get(C, Idx, B)); - - // Add the remaining attribute slots. - for (unsigned I = LastIndex, E = NumAttrs; I < E; ++I) - AttrSet.push_back(getSlotAttributes(I)); - - return get(C, AttrSet); -} - -void AttributeSet::dump() const { - dbgs() << "PAL[\n"; - for (unsigned i = 0, e = getNumSlots(); i < e; ++i) { - uint64_t Index = getSlotIndex(i); - dbgs() << " { "; - if (Index == ~0U) - dbgs() << "~0U"; - else - dbgs() << Index; - dbgs() << " => " << getAsString(Index) << " }\n"; - } - - dbgs() << "]\n"; -} - //===----------------------------------------------------------------------===// // 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