summaryrefslogtreecommitdiffstats
path: root/llvm/lib/IR
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/IR')
-rw-r--r--llvm/lib/IR/AsmWriter.cpp50
-rw-r--r--llvm/lib/IR/AttributeImpl.h2
-rw-r--r--llvm/lib/IR/AttributeSetNode.h107
-rw-r--r--llvm/lib/IR/Attributes.cpp269
-rw-r--r--llvm/lib/IR/Core.cpp2
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"
OpenPOWER on IntegriCloud