aboutsummaryrefslogtreecommitdiff
path: root/lib/IR/Attributes.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/IR/Attributes.cpp')
-rw-r--r--lib/IR/Attributes.cpp112
1 files changed, 29 insertions, 83 deletions
diff --git a/lib/IR/Attributes.cpp b/lib/IR/Attributes.cpp
index 2b7359dab807..d690111ef210 100644
--- a/lib/IR/Attributes.cpp
+++ b/lib/IR/Attributes.cpp
@@ -984,20 +984,23 @@ AttributeList AttributeList::addAttributes(LLVMContext &C, unsigned Index,
}
AttributeList AttributeList::addAttributes(LLVMContext &C, unsigned Index,
- AttributeSet AS) const {
- if (!AS.hasAttributes())
+ const AttrBuilder &B) const {
+ if (!B.hasAttributes())
return *this;
+ if (!pImpl)
+ return AttributeList::get(C, {{Index, AttributeSet::get(C, B)}});
+
#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 = B.getAlignment();
assert((!OldAlign || !NewAlign || OldAlign == NewAlign) &&
"Attempt to change alignment!");
#endif
- SmallVector<std::pair<unsigned, AttributeSet>, 4> AttrSet;
+ SmallVector<IndexAttrPair, 4> AttrVec;
uint64_t NumAttrs = pImpl->getNumSlots();
unsigned I;
@@ -1005,31 +1008,25 @@ AttributeList AttributeList::addAttributes(LLVMContext &C, unsigned Index,
for (I = 0; I < NumAttrs; ++I) {
if (getSlotIndex(I) >= Index)
break;
- AttrSet.emplace_back(getSlotIndex(I), pImpl->getSlotNode(I));
+ AttrVec.emplace_back(getSlotIndex(I), pImpl->getSlotNode(I));
}
+ AttrBuilder NewAttrs;
if (I < NumAttrs && getSlotIndex(I) == Index) {
- // We need to merge two AttributeSets.
- AttributeSet Merged = AttributeSet::get(
- C, AttrBuilder(pImpl->getSlotNode(I)).merge(AttrBuilder(AS)));
- AttrSet.emplace_back(Index, Merged);
+ // We need to merge the attribute sets.
+ NewAttrs.merge(pImpl->getSlotNode(I));
++I;
- } else {
- // Otherwise, there were no attributes at this position in the original
- // list. Add the set as is.
- AttrSet.emplace_back(Index, AS);
}
+ NewAttrs.merge(B);
+
+ // Add the new or merged attribute set at this index.
+ AttrVec.emplace_back(Index, AttributeSet::get(C, NewAttrs));
// Add the remaining entries.
for (; I < NumAttrs; ++I)
- AttrSet.emplace_back(getSlotIndex(I), pImpl->getSlotNode(I));
-
- return get(C, AttrSet);
-}
+ AttrVec.emplace_back(getSlotIndex(I), pImpl->getSlotNode(I));
-AttributeList AttributeList::addAttributes(LLVMContext &C, unsigned Index,
- const AttrBuilder &B) const {
- return get(C, Index, AttributeSet::get(C, B));
+ return get(C, AttrVec);
}
AttributeList AttributeList::removeAttribute(LLVMContext &C, unsigned Index,
@@ -1046,46 +1043,7 @@ AttributeList AttributeList::removeAttribute(LLVMContext &C, unsigned Index,
AttributeList AttributeList::removeAttributes(LLVMContext &C, unsigned Index,
AttributeList Attrs) const {
- if (!pImpl)
- return AttributeList();
- if (!Attrs.pImpl) return *this;
-
- // 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(Index, Attribute::Alignment) &&
- "Attempt to change alignment!");
-
- // Add the attribute slots before the one we're trying to add.
- SmallVector<AttributeList, 4> AttrSet;
- uint64_t NumAttrs = pImpl->getNumSlots();
- AttributeList AL;
- uint64_t LastIndex = 0;
- for (unsigned I = 0, E = NumAttrs; I != E; ++I) {
- if (getSlotIndex(I) >= Index) {
- if (getSlotIndex(I) == Index) AL = getSlotAttributes(LastIndex++);
- break;
- }
- LastIndex = I + 1;
- AttrSet.push_back(getSlotAttributes(I));
- }
-
- // Now remove the attribute from the correct slot. There may already be an
- // AttributeList there.
- AttrBuilder B(AL, Index);
-
- for (unsigned I = 0, E = Attrs.pImpl->getNumSlots(); I != E; ++I)
- if (Attrs.getSlotIndex(I) == Index) {
- B.removeAttributes(Attrs.pImpl->getSlotAttributes(I), Index);
- break;
- }
-
- 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));
-
- return get(C, AttrSet);
+ return removeAttributes(C, Index, AttrBuilder(Attrs.getAttributes(Index)));
}
AttributeList AttributeList::removeAttributes(LLVMContext &C, unsigned Index,
@@ -1098,31 +1056,30 @@ AttributeList AttributeList::removeAttributes(LLVMContext &C, unsigned Index,
assert(!Attrs.hasAlignmentAttr() && "Attempt to change alignment!");
// Add the attribute slots before the one we're trying to add.
- SmallVector<AttributeList, 4> AttrSet;
+ SmallVector<IndexAttrPair, 4> AttrSets;
uint64_t NumAttrs = pImpl->getNumSlots();
- AttributeList AL;
+ AttrBuilder B;
uint64_t LastIndex = 0;
for (unsigned I = 0, E = NumAttrs; I != E; ++I) {
if (getSlotIndex(I) >= Index) {
- if (getSlotIndex(I) == Index) AL = getSlotAttributes(LastIndex++);
+ if (getSlotIndex(I) == Index)
+ B = AttrBuilder(pImpl->getSlotNode(LastIndex++));
break;
}
LastIndex = I + 1;
- AttrSet.push_back(getSlotAttributes(I));
+ AttrSets.push_back({getSlotIndex(I), pImpl->getSlotNode(I)});
}
- // Now remove the attribute from the correct slot. There may already be an
- // AttributeList there.
- AttrBuilder B(AL, Index);
+ // Remove the attributes from the existing set and add them.
B.remove(Attrs);
-
- AttrSet.push_back(AttributeList::get(C, Index, B));
+ if (B.hasAttributes())
+ AttrSets.push_back({Index, AttributeSet::get(C, B)});
// Add the remaining attribute slots.
for (unsigned I = LastIndex, E = NumAttrs; I < E; ++I)
- AttrSet.push_back(getSlotAttributes(I));
+ AttrSets.push_back({getSlotIndex(I), pImpl->getSlotNode(I)});
- return get(C, AttrSet);
+ return get(C, AttrSets);
}
AttributeList AttributeList::removeAttributes(LLVMContext &C,
@@ -1406,18 +1363,7 @@ AttrBuilder &AttrBuilder::removeAttribute(Attribute::AttrKind Val) {
}
AttrBuilder &AttrBuilder::removeAttributes(AttributeList A, uint64_t Index) {
- unsigned Slot = ~0U;
- for (unsigned I = 0, E = A.getNumSlots(); I != E; ++I)
- if (A.getSlotIndex(I) == Index) {
- Slot = I;
- break;
- }
-
- assert(Slot != ~0U && "Couldn't find index in AttributeList!");
-
- for (AttributeList::iterator I = A.begin(Slot), E = A.end(Slot); I != E;
- ++I) {
- Attribute Attr = *I;
+ for (Attribute Attr : A.getAttributes(Index)) {
if (Attr.isEnumAttribute() || Attr.isIntAttribute()) {
removeAttribute(Attr.getKindAsEnum());
} else {