diff options
Diffstat (limited to 'llvm/lib/IR/Attributes.cpp')
-rw-r--r-- | llvm/lib/IR/Attributes.cpp | 269 |
1 files changed, 110 insertions, 159 deletions
diff --git a/llvm/lib/IR/Attributes.cpp b/llvm/lib/IR/Attributes.cpp index 0cdc48e2d64..c2759849b60 100644 --- a/llvm/lib/IR/Attributes.cpp +++ b/llvm/lib/IR/Attributes.cpp @@ -14,6 +14,7 @@ //===----------------------------------------------------------------------===// #include "AttributeImpl.h" +#include "AttributeSetNode.h" #include "LLVMContextImpl.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/FoldingSet.h" @@ -23,7 +24,6 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Twine.h" -#include "llvm/IR/AttributeSetNode.h" #include "llvm/IR/Attributes.h" #include "llvm/IR/Function.h" #include "llvm/IR/LLVMContext.h" @@ -527,48 +527,6 @@ AttributeSetNode *AttributeSetNode::get(LLVMContext &C, return PA; } -AttributeSetNode *AttributeSetNode::get(LLVMContext &C, const AttrBuilder &B) { - // Add target-independent attributes. - SmallVector<Attribute, 8> Attrs; - for (Attribute::AttrKind Kind = Attribute::None; - Kind != Attribute::EndAttrKinds; Kind = Attribute::AttrKind(Kind + 1)) { - if (!B.contains(Kind)) - continue; - - Attribute Attr; - switch (Kind) { - case Attribute::Alignment: - Attr = Attribute::getWithAlignment(C, B.getAlignment()); - break; - case Attribute::StackAlignment: - Attr = Attribute::getWithStackAlignment(C, B.getStackAlignment()); - break; - case Attribute::Dereferenceable: - Attr = Attribute::getWithDereferenceableBytes( - C, B.getDereferenceableBytes()); - break; - case Attribute::DereferenceableOrNull: - Attr = Attribute::getWithDereferenceableOrNullBytes( - C, B.getDereferenceableOrNullBytes()); - break; - case Attribute::AllocSize: { - auto A = B.getAllocSizeArgs(); - Attr = Attribute::getWithAllocSizeArgs(C, A.first, A.second); - break; - } - default: - Attr = Attribute::get(C, Kind); - } - Attrs.push_back(Attr); - } - - // Add target-dependent (string) attributes. - for (const auto &TDA : B.td_attrs()) - Attrs.emplace_back(Attribute::get(C, TDA.first, TDA.second)); - - return get(C, Attrs); -} - bool AttributeSetNode::hasAttribute(StringRef Kind) const { for (Attribute I : *this) if (I.hasAttribute(Kind)) @@ -654,19 +612,6 @@ LLVM_DUMP_METHOD void AttributeListImpl::dump() const { AttributeList AttributeList::getImpl( LLVMContext &C, ArrayRef<std::pair<unsigned, AttributeSetNode *>> Attrs) { - assert(!Attrs.empty() && "creating pointless AttributeList"); -#ifndef NDEBUG - unsigned LastIndex = 0; - bool IsFirst = true; - for (const auto &AttrPair : Attrs) { - assert((IsFirst || LastIndex < AttrPair.first) && - "unsorted or duplicate AttributeList indices"); - assert(AttrPair.second && "pointless AttributeList slot"); - LastIndex = AttrPair.first; - IsFirst = false; - } -#endif - LLVMContextImpl *pImpl = C.pImpl; FoldingSetNodeID ID; AttributeListImpl::Profile(ID, Attrs); @@ -735,32 +680,50 @@ AttributeList::get(LLVMContext &C, return getImpl(C, Attrs); } -AttributeList AttributeList::get(LLVMContext &C, ArrayRef<AttributeSetNode*> Attrs) { - assert(Attrs.size() >= 2 && - "should always have function and return attr slots"); - SmallVector<std::pair<unsigned, AttributeSetNode *>, 8> AttrPairs; - size_t Index = 0; - for (AttributeSetNode *AS : Attrs) { - if (AS) { - // If this is the last AttributeSetNode, it's for the function. - if (Index == Attrs.size() - 1) - Index = AttributeList::FunctionIndex; - AttrPairs.emplace_back(Index, AS); - } - ++Index; - } - if (AttrPairs.empty()) - return AttributeList(); - return getImpl(C, AttrPairs); -} - AttributeList AttributeList::get(LLVMContext &C, unsigned Index, const AttrBuilder &B) { if (!B.hasAttributes()) return AttributeList(); - AttributeSetNode *ASN = AttributeSetNode::get(C, B); - std::pair<unsigned, AttributeSetNode *> Arr[1] = {{Index, ASN}}; - return getImpl(C, Arr); + + // Add target-independent attributes. + SmallVector<std::pair<unsigned, Attribute>, 8> Attrs; + for (Attribute::AttrKind Kind = Attribute::None; + Kind != Attribute::EndAttrKinds; Kind = Attribute::AttrKind(Kind + 1)) { + if (!B.contains(Kind)) + continue; + + Attribute Attr; + switch (Kind) { + case Attribute::Alignment: + Attr = Attribute::getWithAlignment(C, B.getAlignment()); + break; + case Attribute::StackAlignment: + Attr = Attribute::getWithStackAlignment(C, B.getStackAlignment()); + break; + case Attribute::Dereferenceable: + Attr = Attribute::getWithDereferenceableBytes( + C, B.getDereferenceableBytes()); + break; + case Attribute::DereferenceableOrNull: + Attr = Attribute::getWithDereferenceableOrNullBytes( + C, B.getDereferenceableOrNullBytes()); + break; + case Attribute::AllocSize: { + auto A = B.getAllocSizeArgs(); + Attr = Attribute::getWithAllocSizeArgs(C, A.first, A.second); + break; + } + default: + Attr = Attribute::get(C, Kind); + } + Attrs.emplace_back(Index, Attr); + } + + // Add target-dependent (string) attributes. + for (const auto &TDA : B.td_attrs()) + Attrs.emplace_back(Index, Attribute::get(C, TDA.first, TDA.second)); + + return get(C, Attrs); } AttributeList AttributeList::get(LLVMContext &C, unsigned Index, @@ -828,31 +791,31 @@ AttributeList AttributeList::addAttribute(LLVMContext &C, unsigned Index, AttributeList AttributeList::addAttribute(LLVMContext &C, ArrayRef<unsigned> Indices, Attribute A) const { - assert(std::is_sorted(Indices.begin(), Indices.end())); - unsigned I = 0, E = pImpl ? pImpl->getNumSlots() : 0; - SmallVector<IndexAttrPair, 4> AttrVec; - for (unsigned Index : Indices) { - // Add all attribute slots before the current index. - for (; I < E && getSlotIndex(I) < Index; ++I) - AttrVec.emplace_back(getSlotIndex(I), pImpl->getSlotNode(I)); - - // Add the attribute at this index. If we already have attributes at this - // index, merge them into a new set. - AttrBuilder B; - if (I < E && getSlotIndex(I) == Index) { - B.merge(AttrBuilder(pImpl->getSlotNode(I))); + auto IdxI = Indices.begin(), IdxE = Indices.end(); + SmallVector<AttributeList, 4> AttrSet; + + while (I != E && IdxI != IdxE) { + if (getSlotIndex(I) < *IdxI) + AttrSet.emplace_back(getSlotAttributes(I++)); + else if (getSlotIndex(I) > *IdxI) + AttrSet.emplace_back(AttributeList::get(C, std::make_pair(*IdxI++, A))); + else { + AttrBuilder B(getSlotAttributes(I), *IdxI); + B.addAttribute(A); + AttrSet.emplace_back(AttributeList::get(C, *IdxI, B)); ++I; + ++IdxI; } - B.addAttribute(A); - AttrVec.emplace_back(Index, AttributeSetNode::get(C, B)); } - // Add remaining attributes. - for (; I < E; ++I) - AttrVec.emplace_back(getSlotIndex(I), pImpl->getSlotNode(I)); + while (I != E) + AttrSet.emplace_back(getSlotAttributes(I++)); - return get(C, AttrVec); + while (IdxI != IdxE) + AttrSet.emplace_back(AttributeList::get(C, std::make_pair(*IdxI++, A))); + + return get(C, AttrSet); } AttributeList AttributeList::addAttributes(LLVMContext &C, unsigned Index, @@ -860,56 +823,49 @@ AttributeList AttributeList::addAttributes(LLVMContext &C, unsigned Index, if (!pImpl) return Attrs; if (!Attrs.pImpl) return *this; - return addAttributes(C, Index, Attrs.getAttributes(Index)); -} - -AttributeList AttributeList::addAttributes(LLVMContext &C, unsigned Index, - AttributeSetNode *AS) const { - if (!AS) - 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(Index); - unsigned NewAlign = AS->getAlignment(); + unsigned NewAlign = Attrs.getParamAlignment(Index); assert((!OldAlign || !NewAlign || OldAlign == NewAlign) && "Attempt to change alignment!"); #endif - SmallVector<std::pair<unsigned, AttributeSetNode *>, 4> AttrSet; + // Add the attribute slots before the one we're trying to add. + SmallVector<AttributeList, 4> AttrSet; uint64_t NumAttrs = pImpl->getNumSlots(); - unsigned I; - - // Add all the attribute slots before the one we need to merge. - for (I = 0; I < NumAttrs; ++I) { - if (getSlotIndex(I) >= Index) + AttributeList AS; + uint64_t LastIndex = 0; + for (unsigned I = 0, E = NumAttrs; I != E; ++I) { + if (getSlotIndex(I) >= Index) { + if (getSlotIndex(I) == Index) AS = getSlotAttributes(LastIndex++); break; - AttrSet.emplace_back(getSlotIndex(I), pImpl->getSlotNode(I)); + } + LastIndex = I + 1; + AttrSet.push_back(getSlotAttributes(I)); } - if (I < NumAttrs && getSlotIndex(I) == Index) { - // We need to merge two AttributeSetNodes. - AttributeSetNode *Merged = AttributeSetNode::get( - C, AttrBuilder(pImpl->getSlotNode(I)).merge(AttrBuilder(AS))); - AttrSet.emplace_back(Index, Merged); - ++I; - } else { - // Otherwise, there were no attributes at this position in the original - // list. Add the set as is. - AttrSet.emplace_back(Index, AS); - } + // Now add the attribute into the correct slot. There may already be an + // AttributeList there. + AttrBuilder B(AS, Index); - // Add the remaining entries. - for (; I < NumAttrs; ++I) - AttrSet.emplace_back(getSlotIndex(I), pImpl->getSlotNode(I)); + for (unsigned I = 0, E = Attrs.pImpl->getNumSlots(); I != E; ++I) + if (Attrs.getSlotIndex(I) == Index) { + for (AttributeListImpl::iterator II = Attrs.pImpl->begin(I), + IE = Attrs.pImpl->end(I); + II != IE; ++II) + B.addAttribute(*II); + break; + } - return get(C, AttrSet); -} + AttrSet.push_back(AttributeList::get(C, Index, B)); -AttributeList AttributeList::addAttributes(LLVMContext &C, unsigned Index, - const AttrBuilder &B) const { - return get(C, Index, AttributeSetNode::get(C, B)); + // Add the remaining attribute slots. + for (unsigned I = LastIndex, E = NumAttrs; I < E; ++I) + AttrSet.push_back(getSlotAttributes(I)); + + return get(C, AttrSet); } AttributeList AttributeList::removeAttribute(LLVMContext &C, unsigned Index, @@ -1005,20 +961,6 @@ AttributeList AttributeList::removeAttributes(LLVMContext &C, unsigned Index, return get(C, AttrSet); } -AttributeList AttributeList::removeAttributes(LLVMContext &C, - unsigned WithoutIndex) const { - if (!pImpl) - return AttributeList(); - - SmallVector<std::pair<unsigned, AttributeSetNode *>, 4> AttrSet; - for (unsigned I = 0, E = pImpl->getNumSlots(); I != E; ++I) { - unsigned Index = getSlotIndex(I); - if (Index != WithoutIndex) - AttrSet.push_back({Index, pImpl->getSlotNode(I)}); - } - return get(C, AttrSet); -} - AttributeList AttributeList::addDereferenceableAttr(LLVMContext &C, unsigned Index, uint64_t Bytes) const { @@ -1050,16 +992,32 @@ AttributeList::addAllocSizeAttr(LLVMContext &C, unsigned Index, LLVMContext &AttributeList::getContext() const { return pImpl->getContext(); } -AttributeSetNode *AttributeList::getParamAttributes(unsigned Index) const { - return getAttributes(Index); +AttributeList AttributeList::getParamAttributes(unsigned Index) const { + return pImpl && hasAttributes(Index) + ? AttributeList::get( + pImpl->getContext(), + ArrayRef<std::pair<unsigned, AttributeSetNode *>>( + std::make_pair(Index, getAttributes(Index)))) + : AttributeList(); } -AttributeSetNode *AttributeList::getRetAttributes() const { - return getAttributes(ReturnIndex); +AttributeList AttributeList::getRetAttributes() const { + return pImpl && hasAttributes(ReturnIndex) + ? AttributeList::get( + pImpl->getContext(), + ArrayRef<std::pair<unsigned, AttributeSetNode *>>( + std::make_pair(ReturnIndex, getAttributes(ReturnIndex)))) + : AttributeList(); } -AttributeSetNode *AttributeList::getFnAttributes() const { - return getAttributes(FunctionIndex); +AttributeList AttributeList::getFnAttributes() const { + return pImpl && hasAttributes(FunctionIndex) + ? AttributeList::get( + pImpl->getContext(), + ArrayRef<std::pair<unsigned, AttributeSetNode *>>( + std::make_pair(FunctionIndex, + getAttributes(FunctionIndex)))) + : AttributeList(); } bool AttributeList::hasAttribute(unsigned Index, @@ -1223,13 +1181,6 @@ AttrBuilder::AttrBuilder(AttributeList AS, unsigned Index) { } } -AttrBuilder::AttrBuilder(AttributeSetNode *AS) { - if (AS) { - for (const Attribute &A : *AS) - addAttribute(A); - } -} - void AttrBuilder::clear() { Attrs.reset(); TargetDepAttrs.clear(); |