diff options
Diffstat (limited to 'llvm/lib/IR')
-rw-r--r-- | llvm/lib/IR/AsmWriter.cpp | 50 | ||||
-rw-r--r-- | llvm/lib/IR/AttributeImpl.h | 2 | ||||
-rw-r--r-- | llvm/lib/IR/AttributeSetNode.h | 107 | ||||
-rw-r--r-- | llvm/lib/IR/Attributes.cpp | 269 | ||||
-rw-r--r-- | llvm/lib/IR/Core.cpp | 2 |
5 files changed, 183 insertions, 247 deletions
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp index 3afa3986052..f8481039c66 100644 --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -21,6 +21,8 @@ #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringExtras.h" #include "llvm/IR/AssemblyAnnotationWriter.h" +#include "llvm/IR/AttributeSetNode.h" +#include "llvm/IR/Attributes.h" #include "llvm/IR/CFG.h" #include "llvm/IR/CallingConv.h" #include "llvm/IR/Constants.h" @@ -604,7 +606,7 @@ private: unsigned mdnNext; /// asMap - The slot map for attribute sets. - DenseMap<AttributeList, unsigned> asMap; + DenseMap<AttributeSetNode *, unsigned> asMap; unsigned asNext; public: /// Construct from a module. @@ -627,7 +629,7 @@ public: int getLocalSlot(const Value *V); int getGlobalSlot(const GlobalValue *V); int getMetadataSlot(const MDNode *N); - int getAttributeGroupSlot(AttributeList AS); + int getAttributeGroupSlot(AttributeSetNode *AS); /// If you'd like to deal with a function instead of just a module, use /// this method to get its data into the SlotTracker. @@ -650,8 +652,8 @@ public: unsigned mdn_size() const { return mdnMap.size(); } bool mdn_empty() const { return mdnMap.empty(); } - /// AttributeList map iterators. - typedef DenseMap<AttributeList, unsigned>::iterator as_iterator; + /// AttributeSetNode map iterators. + typedef DenseMap<AttributeSetNode *, unsigned>::iterator as_iterator; as_iterator as_begin() { return asMap.begin(); } as_iterator as_end() { return asMap.end(); } unsigned as_size() const { return asMap.size(); } @@ -671,8 +673,8 @@ private: /// CreateFunctionSlot - Insert the specified Value* into the slot table. void CreateFunctionSlot(const Value *V); - /// \brief Insert the specified AttributeList into the slot table. - void CreateAttributeSetSlot(AttributeList AS); + /// \brief Insert the specified AttributeSetNode into the slot table. + void CreateAttributeSetSlot(AttributeSetNode *AS); /// Add all of the module level global variables (and their initializers) /// and function declarations, but not the contents of those functions. @@ -831,8 +833,8 @@ void SlotTracker::processModule() { // Add all the function attributes to the table. // FIXME: Add attributes of other objects? - AttributeList FnAttrs = F.getAttributes().getFnAttributes(); - if (FnAttrs.hasAttributes(AttributeList::FunctionIndex)) + AttributeSetNode *FnAttrs = F.getAttributes().getFnAttributes(); + if (FnAttrs) CreateAttributeSetSlot(FnAttrs); } @@ -869,13 +871,13 @@ void SlotTracker::processFunction() { // target may not be linked into the optimizer. if (const CallInst *CI = dyn_cast<CallInst>(&I)) { // Add all the call attributes to the table. - AttributeList Attrs = CI->getAttributes().getFnAttributes(); - if (Attrs.hasAttributes(AttributeList::FunctionIndex)) + AttributeSetNode *Attrs = CI->getAttributes().getFnAttributes(); + if (Attrs) CreateAttributeSetSlot(Attrs); } else if (const InvokeInst *II = dyn_cast<InvokeInst>(&I)) { // Add all the call attributes to the table. - AttributeList Attrs = II->getAttributes().getFnAttributes(); - if (Attrs.hasAttributes(AttributeList::FunctionIndex)) + AttributeSetNode *Attrs = II->getAttributes().getFnAttributes(); + if (Attrs) CreateAttributeSetSlot(Attrs); } } @@ -961,11 +963,11 @@ int SlotTracker::getLocalSlot(const Value *V) { return FI == fMap.end() ? -1 : (int)FI->second; } -int SlotTracker::getAttributeGroupSlot(AttributeList AS) { +int SlotTracker::getAttributeGroupSlot(AttributeSetNode *AS) { // Check for uninitialized state and do lazy initialization. initialize(); - // Find the AttributeList in the module map. + // Find the AttributeSetNode in the module map. as_iterator AI = asMap.find(AS); return AI == asMap.end() ? -1 : (int)AI->second; } @@ -1015,9 +1017,8 @@ void SlotTracker::CreateMetadataSlot(const MDNode *N) { CreateMetadataSlot(Op); } -void SlotTracker::CreateAttributeSetSlot(AttributeList AS) { - assert(AS.hasAttributes(AttributeList::FunctionIndex) && - "Doesn't need a slot!"); +void SlotTracker::CreateAttributeSetSlot(AttributeSetNode *AS) { + assert(AS && "Doesn't need a slot!"); as_iterator I = asMap.find(AS); if (I != asMap.end()) @@ -2606,17 +2607,10 @@ void AssemblyWriter::printFunction(const Function *F) { const AttributeList &Attrs = F->getAttributes(); if (Attrs.hasAttributes(AttributeList::FunctionIndex)) { - AttributeList AS = Attrs.getFnAttributes(); + AttributeSetNode *AS = Attrs.getFnAttributes(); std::string AttrStr; - unsigned Idx = 0; - for (unsigned E = AS.getNumSlots(); Idx != E; ++Idx) - if (AS.getSlotIndex(Idx) == AttributeList::FunctionIndex) - break; - - for (AttributeList::iterator I = AS.begin(Idx), E = AS.end(Idx); I != E; - ++I) { - Attribute Attr = *I; + for (const Attribute &Attr : *AS) { if (!Attr.isStringAttribute()) { if (!AttrStr.empty()) AttrStr += ' '; AttrStr += Attr.getAsString(); @@ -3250,7 +3244,7 @@ void AssemblyWriter::printMDNodeBody(const MDNode *Node) { } void AssemblyWriter::writeAllAttributeGroups() { - std::vector<std::pair<AttributeList, unsigned>> asVec; + std::vector<std::pair<AttributeSetNode *, unsigned>> asVec; asVec.resize(Machine.as_size()); for (SlotTracker::as_iterator I = Machine.as_begin(), E = Machine.as_end(); @@ -3259,7 +3253,7 @@ void AssemblyWriter::writeAllAttributeGroups() { for (const auto &I : asVec) Out << "attributes #" << I.second << " = { " - << I.first.getAsString(AttributeList::FunctionIndex, true) << " }\n"; + << I.first->getAsString(true) << " }\n"; } void AssemblyWriter::printUseListOrder(const UseListOrder &Order) { diff --git a/llvm/lib/IR/AttributeImpl.h b/llvm/lib/IR/AttributeImpl.h index 01140b70bfc..77f1067c7ac 100644 --- a/llvm/lib/IR/AttributeImpl.h +++ b/llvm/lib/IR/AttributeImpl.h @@ -16,10 +16,10 @@ #ifndef LLVM_LIB_IR_ATTRIBUTEIMPL_H #define LLVM_LIB_IR_ATTRIBUTEIMPL_H -#include "AttributeSetNode.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/StringRef.h" +#include "llvm/IR/AttributeSetNode.h" #include "llvm/IR/Attributes.h" #include "llvm/Support/TrailingObjects.h" #include <algorithm> diff --git a/llvm/lib/IR/AttributeSetNode.h b/llvm/lib/IR/AttributeSetNode.h deleted file mode 100644 index 481cf47918c..00000000000 --- a/llvm/lib/IR/AttributeSetNode.h +++ /dev/null @@ -1,107 +0,0 @@ -//===-- AttributeSetNode.h - AttributeList Internal Node ---------*- C++ -//-*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -/// -/// \file -/// \brief This file defines the node class used internally by AttributeList. -/// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_IR_ATTRIBUTESETNODE_H -#define LLVM_IR_ATTRIBUTESETNODE_H - -#include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/FoldingSet.h" -#include "llvm/ADT/Optional.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/IR/Attributes.h" -#include "llvm/Support/TrailingObjects.h" -#include <algorithm> -#include <climits> -#include <cstdint> -#include <string> -#include <utility> - -namespace llvm { - -//===----------------------------------------------------------------------===// -/// \class -/// \brief This class represents a group of attributes that apply to one -/// element: function, return type, or parameter. -class AttributeSetNode final - : public FoldingSetNode, - private TrailingObjects<AttributeSetNode, Attribute> { - friend TrailingObjects; - - unsigned NumAttrs; ///< Number of attributes in this node. - /// Bitset with a bit for each available attribute Attribute::AttrKind. - uint64_t AvailableAttrs; - - AttributeSetNode(ArrayRef<Attribute> Attrs) - : NumAttrs(Attrs.size()), AvailableAttrs(0) { - static_assert(Attribute::EndAttrKinds <= sizeof(AvailableAttrs) * CHAR_BIT, - "Too many attributes for AvailableAttrs"); - // There's memory after the node where we can store the entries in. - std::copy(Attrs.begin(), Attrs.end(), getTrailingObjects<Attribute>()); - - for (Attribute I : *this) { - if (!I.isStringAttribute()) { - AvailableAttrs |= ((uint64_t)1) << I.getKindAsEnum(); - } - } - } - -public: - // AttributesSetNode is uniqued, these should not be available. - AttributeSetNode(const AttributeSetNode &) = delete; - AttributeSetNode &operator=(const AttributeSetNode &) = delete; - - void operator delete(void *p) { ::operator delete(p); } - - static AttributeSetNode *get(LLVMContext &C, ArrayRef<Attribute> Attrs); - - static AttributeSetNode *get(AttributeList AS, unsigned Index) { - return AS.getAttributes(Index); - } - - /// \brief Return the number of attributes this AttributeList contains. - unsigned getNumAttributes() const { return NumAttrs; } - - bool hasAttribute(Attribute::AttrKind Kind) const { - return AvailableAttrs & ((uint64_t)1) << Kind; - } - bool hasAttribute(StringRef Kind) const; - bool hasAttributes() const { return NumAttrs != 0; } - - Attribute getAttribute(Attribute::AttrKind Kind) const; - Attribute getAttribute(StringRef Kind) const; - - unsigned getAlignment() const; - unsigned getStackAlignment() const; - uint64_t getDereferenceableBytes() const; - uint64_t getDereferenceableOrNullBytes() const; - std::pair<unsigned, Optional<unsigned>> getAllocSizeArgs() const; - std::string getAsString(bool InAttrGrp) const; - - typedef const Attribute *iterator; - iterator begin() const { return getTrailingObjects<Attribute>(); } - iterator end() const { return begin() + NumAttrs; } - - void Profile(FoldingSetNodeID &ID) const { - Profile(ID, makeArrayRef(begin(), end())); - } - static void Profile(FoldingSetNodeID &ID, ArrayRef<Attribute> AttrList) { - for (const auto &Attr : AttrList) - Attr.Profile(ID); - } -}; - -} // end namespace llvm - -#endif // LLVM_IR_ATTRIBUTESETNODE_H diff --git a/llvm/lib/IR/Attributes.cpp b/llvm/lib/IR/Attributes.cpp index c2759849b60..0cdc48e2d64 100644 --- a/llvm/lib/IR/Attributes.cpp +++ b/llvm/lib/IR/Attributes.cpp @@ -14,7 +14,6 @@ //===----------------------------------------------------------------------===// #include "AttributeImpl.h" -#include "AttributeSetNode.h" #include "LLVMContextImpl.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/FoldingSet.h" @@ -24,6 +23,7 @@ #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,6 +527,48 @@ 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)) @@ -612,6 +654,19 @@ 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); @@ -680,50 +735,32 @@ 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(); - - // 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); + AttributeSetNode *ASN = AttributeSetNode::get(C, B); + std::pair<unsigned, AttributeSetNode *> Arr[1] = {{Index, ASN}}; + return getImpl(C, Arr); } AttributeList AttributeList::get(LLVMContext &C, unsigned Index, @@ -791,31 +828,31 @@ AttributeList AttributeList::addAttribute(LLVMContext &C, unsigned Index, AttributeList AttributeList::addAttribute(LLVMContext &C, ArrayRef<unsigned> Indices, Attribute A) const { - unsigned I = 0, E = pImpl ? pImpl->getNumSlots() : 0; - auto IdxI = Indices.begin(), IdxE = Indices.end(); - SmallVector<AttributeList, 4> AttrSet; + assert(std::is_sorted(Indices.begin(), Indices.end())); - 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)); + 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))); ++I; - ++IdxI; } + B.addAttribute(A); + AttrVec.emplace_back(Index, AttributeSetNode::get(C, B)); } - while (I != E) - AttrSet.emplace_back(getSlotAttributes(I++)); + // Add remaining attributes. + for (; I < E; ++I) + AttrVec.emplace_back(getSlotIndex(I), pImpl->getSlotNode(I)); - while (IdxI != IdxE) - AttrSet.emplace_back(AttributeList::get(C, std::make_pair(*IdxI++, A))); - - return get(C, AttrSet); + return get(C, AttrVec); } AttributeList AttributeList::addAttributes(LLVMContext &C, unsigned Index, @@ -823,51 +860,58 @@ 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 = Attrs.getParamAlignment(Index); + unsigned NewAlign = AS->getAlignment(); assert((!OldAlign || !NewAlign || OldAlign == NewAlign) && "Attempt to change alignment!"); #endif - // Add the attribute slots before the one we're trying to add. - SmallVector<AttributeList, 4> AttrSet; + SmallVector<std::pair<unsigned, AttributeSetNode *>, 4> AttrSet; uint64_t NumAttrs = pImpl->getNumSlots(); - 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++); + unsigned I; + + // Add all the attribute slots before the one we need to merge. + for (I = 0; I < NumAttrs; ++I) { + if (getSlotIndex(I) >= Index) break; - } - LastIndex = I + 1; - AttrSet.push_back(getSlotAttributes(I)); + AttrSet.emplace_back(getSlotIndex(I), pImpl->getSlotNode(I)); } - // Now add the attribute into the correct slot. There may already be an - // AttributeList there. - AttrBuilder B(AS, Index); - - 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; - } + 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); + } - AttrSet.push_back(AttributeList::get(C, Index, B)); - - // Add the remaining attribute slots. - for (unsigned I = LastIndex, E = NumAttrs; I < E; ++I) - AttrSet.push_back(getSlotAttributes(I)); + // Add the remaining entries. + for (; I < NumAttrs; ++I) + AttrSet.emplace_back(getSlotIndex(I), pImpl->getSlotNode(I)); return get(C, AttrSet); } +AttributeList AttributeList::addAttributes(LLVMContext &C, unsigned Index, + const AttrBuilder &B) const { + return get(C, Index, AttributeSetNode::get(C, B)); +} + AttributeList AttributeList::removeAttribute(LLVMContext &C, unsigned Index, Attribute::AttrKind Kind) const { if (!hasAttribute(Index, Kind)) return *this; @@ -961,6 +1005,20 @@ 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 { @@ -992,32 +1050,16 @@ AttributeList::addAllocSizeAttr(LLVMContext &C, unsigned Index, LLVMContext &AttributeList::getContext() const { return pImpl->getContext(); } -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::getParamAttributes(unsigned Index) const { + return getAttributes(Index); } -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::getRetAttributes() const { + return getAttributes(ReturnIndex); } -AttributeList AttributeList::getFnAttributes() const { - return pImpl && hasAttributes(FunctionIndex) - ? AttributeList::get( - pImpl->getContext(), - ArrayRef<std::pair<unsigned, AttributeSetNode *>>( - std::make_pair(FunctionIndex, - getAttributes(FunctionIndex)))) - : AttributeList(); +AttributeSetNode *AttributeList::getFnAttributes() const { + return getAttributes(FunctionIndex); } bool AttributeList::hasAttribute(unsigned Index, @@ -1181,6 +1223,13 @@ 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(); diff --git a/llvm/lib/IR/Core.cpp b/llvm/lib/IR/Core.cpp index c5b3d18764d..f1843593a3b 100644 --- a/llvm/lib/IR/Core.cpp +++ b/llvm/lib/IR/Core.cpp @@ -16,7 +16,7 @@ #include "llvm/ADT/StringSwitch.h" #include "llvm/Bitcode/BitcodeReader.h" #include "llvm/IR/Attributes.h" -#include "AttributeSetNode.h" +#include "llvm/IR/AttributeSetNode.h" #include "llvm/IR/CallSite.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DerivedTypes.h" |