summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorserge-sans-paille <sguelton@redhat.com>2022-01-04 09:44:47 +0100
committerserge-sans-paille <sguelton@redhat.com>2022-01-04 15:37:46 +0100
commit9290ccc3c1a17a7874de020656db38183a20f6b0 (patch)
tree9c9a10a0fa164c01b7a109a9db5cb8a1014adaf2
parent2b1c38f737d490c09efc60e2c3e17b8568173097 (diff)
downloadllvm-9290ccc3c1a17a7874de020656db38183a20f6b0.tar.gz
Introduce the AttributeMask class
This class is solely used as a lightweight and clean way to build a set of attributes to be removed from an AttrBuilder. Previously AttrBuilder was used both for building and removing, which introduced odd situation like creation of Attribute with dummy value because the only relevant part was the attribute kind. Differential Revision: https://reviews.llvm.org/D116110
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp2
-rw-r--r--llvm/include/llvm/IR/Argument.h2
-rw-r--r--llvm/include/llvm/IR/Attributes.h98
-rw-r--r--llvm/include/llvm/IR/Function.h6
-rw-r--r--llvm/include/llvm/IR/InstrTypes.h6
-rw-r--r--llvm/lib/IR/Attributes.cpp72
-rw-r--r--llvm/lib/IR/Function.cpp12
-rw-r--r--llvm/lib/IR/Instruction.cpp3
-rw-r--r--llvm/lib/IR/Verifier.cpp2
-rw-r--r--llvm/lib/Target/AMDGPU/AMDGPURewriteOutArguments.cpp2
-rw-r--r--llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp3
-rw-r--r--llvm/lib/Transforms/IPO/FunctionAttrs.cpp2
-rw-r--r--llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp2
-rw-r--r--llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp4
-rw-r--r--llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp14
-rw-r--r--llvm/lib/Transforms/Scalar/SCCP.cpp2
-rw-r--r--llvm/unittests/IR/AttributesTest.cpp4
17 files changed, 153 insertions, 83 deletions
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 36b7ce87336c..bf74f4d3f698 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -2097,7 +2097,7 @@ void CodeGenModule::setNonAliasAttributes(GlobalDecl GD,
// We know that GetCPUAndFeaturesAttributes will always have the
// newest set, since it has the newest possible FunctionDecl, so the
// new ones should replace the old.
- llvm::AttrBuilder RemoveAttrs;
+ llvm::AttributeMask RemoveAttrs;
RemoveAttrs.addAttribute("target-cpu");
RemoveAttrs.addAttribute("target-features");
RemoveAttrs.addAttribute("tune-cpu");
diff --git a/llvm/include/llvm/IR/Argument.h b/llvm/include/llvm/IR/Argument.h
index 396ab6a9d01d..7cbfa2a7b6ce 100644
--- a/llvm/include/llvm/IR/Argument.h
+++ b/llvm/include/llvm/IR/Argument.h
@@ -162,7 +162,7 @@ public:
/// Remove attributes from an argument.
void removeAttr(Attribute::AttrKind Kind);
- void removeAttrs(const AttrBuilder &B);
+ void removeAttrs(const AttributeMask &AM);
/// Check if an argument has a given attribute.
bool hasAttribute(Attribute::AttrKind Kind) const;
diff --git a/llvm/include/llvm/IR/Attributes.h b/llvm/include/llvm/IR/Attributes.h
index f64f15bd38ba..0e75371037bf 100644
--- a/llvm/include/llvm/IR/Attributes.h
+++ b/llvm/include/llvm/IR/Attributes.h
@@ -28,12 +28,14 @@
#include <cassert>
#include <cstdint>
#include <map>
+#include <set>
#include <string>
#include <utility>
namespace llvm {
class AttrBuilder;
+class AttributeMask;
class AttributeImpl;
class AttributeListImpl;
class AttributeSetNode;
@@ -320,7 +322,7 @@ public:
/// Remove the specified attributes from this set. Returns a new set because
/// attribute sets are immutable.
LLVM_NODISCARD AttributeSet
- removeAttributes(LLVMContext &C, const AttrBuilder &AttrsToRemove) const;
+ removeAttributes(LLVMContext &C, const AttributeMask &AttrsToRemove) const;
/// Return the number of attributes in this set.
unsigned getNumAttributes() const;
@@ -580,7 +582,7 @@ public:
/// Remove the specified attributes at the specified index from this
/// attribute list. Returns a new list because attribute lists are immutable.
LLVM_NODISCARD AttributeList removeAttributesAtIndex(
- LLVMContext &C, unsigned Index, const AttrBuilder &AttrsToRemove) const;
+ LLVMContext &C, unsigned Index, const AttributeMask &AttrsToRemove) const;
/// Remove all attributes at the specified index from this
/// attribute list. Returns a new list because attribute lists are immutable.
@@ -604,7 +606,7 @@ public:
/// Remove the specified attribute at the function index from this
/// attribute list. Returns a new list because attribute lists are immutable.
LLVM_NODISCARD AttributeList
- removeFnAttributes(LLVMContext &C, const AttrBuilder &AttrsToRemove) const {
+ removeFnAttributes(LLVMContext &C, const AttributeMask &AttrsToRemove) const {
return removeAttributesAtIndex(C, FunctionIndex, AttrsToRemove);
}
@@ -630,8 +632,8 @@ public:
/// Remove the specified attribute at the return value index from this
/// attribute list. Returns a new list because attribute lists are immutable.
- LLVM_NODISCARD AttributeList
- removeRetAttributes(LLVMContext &C, const AttrBuilder &AttrsToRemove) const {
+ LLVM_NODISCARD AttributeList removeRetAttributes(
+ LLVMContext &C, const AttributeMask &AttrsToRemove) const {
return removeAttributesAtIndex(C, ReturnIndex, AttrsToRemove);
}
@@ -652,8 +654,9 @@ public:
/// Remove the specified attribute at the specified arg index from this
/// attribute list. Returns a new list because attribute lists are immutable.
- LLVM_NODISCARD AttributeList removeParamAttributes(
- LLVMContext &C, unsigned ArgNo, const AttrBuilder &AttrsToRemove) const {
+ LLVM_NODISCARD AttributeList
+ removeParamAttributes(LLVMContext &C, unsigned ArgNo,
+ const AttributeMask &AttrsToRemove) const {
return removeAttributesAtIndex(C, ArgNo + FirstArgIndex, AttrsToRemove);
}
@@ -929,6 +932,65 @@ template <> struct DenseMapInfo<AttributeList, void> {
//===----------------------------------------------------------------------===//
/// \class
+/// This class stores enough information to efficiently remove some attributes
+/// from an existing AttrBuilder, AttributeSet or AttributeList.
+class AttributeMask {
+ std::bitset<Attribute::EndAttrKinds> Attrs;
+ std::set<SmallString<32>, std::less<>> TargetDepAttrs;
+
+public:
+ AttributeMask() = default;
+ AttributeMask(const AttributeMask &) = delete;
+ AttributeMask(AttributeMask &&) = default;
+
+ AttributeMask(AttributeSet AS) {
+ for (Attribute A : AS)
+ addAttribute(A);
+ }
+
+ /// Add an attribute to the mask.
+ AttributeMask &addAttribute(Attribute::AttrKind Val) {
+ assert((unsigned)Val < Attribute::EndAttrKinds &&
+ "Attribute out of range!");
+ Attrs[Val] = true;
+ return *this;
+ }
+
+ /// Add the Attribute object to the builder.
+ AttributeMask &addAttribute(Attribute A) {
+ if (A.isStringAttribute())
+ addAttribute(A.getKindAsString());
+ else
+ addAttribute(A.getKindAsEnum());
+ return *this;
+ }
+
+ /// Add the target-dependent attribute to the builder.
+ AttributeMask &addAttribute(StringRef A) {
+ TargetDepAttrs.insert(A);
+ return *this;
+ }
+
+ /// Return true if the builder has the specified attribute.
+ bool contains(Attribute::AttrKind A) const {
+ assert((unsigned)A < Attribute::EndAttrKinds && "Attribute out of range!");
+ return Attrs[A];
+ }
+
+ /// Return true if the builder has the specified target-dependent
+ /// attribute.
+ bool contains(StringRef A) const { return TargetDepAttrs.count(A); }
+
+ using td_const_iterator = decltype(TargetDepAttrs)::const_iterator;
+ using td_const_range = iterator_range<td_const_iterator>;
+ td_const_range td_attrs() const {
+ return {TargetDepAttrs.begin(), TargetDepAttrs.end()};
+ }
+ auto const &attrs() const { return Attrs; }
+};
+
+//===----------------------------------------------------------------------===//
+/// \class
/// This class is used in conjunction with the Attribute::get method to
/// create an Attribute object. The object itself is uniquified. The Builder's
/// value, however, is not. So this can be used as a quick way to test for
@@ -975,21 +1037,29 @@ public:
/// Remove an attribute from the builder.
AttrBuilder &removeAttribute(Attribute::AttrKind Val);
+ /// Remove the target-dependent attribute from the builder.
+ AttrBuilder &removeAttribute(StringRef A);
+
+ /// Remove the target-dependent attribute from the builder.
+ AttrBuilder &removeAttribute(Attribute A) {
+ if (A.isStringAttribute())
+ return removeAttribute(A.getKindAsString());
+ else
+ return removeAttribute(A.getKindAsEnum());
+ }
+
/// Remove the attributes from the builder.
AttrBuilder &removeAttributes(AttributeList A, uint64_t WithoutIndex);
- /// Remove the target-dependent attribute to the builder.
- AttrBuilder &removeAttribute(StringRef A);
-
/// Add the attributes from the builder.
AttrBuilder &merge(const AttrBuilder &B);
/// Remove the attributes from the builder.
- AttrBuilder &remove(const AttrBuilder &B);
+ AttrBuilder &remove(const AttributeMask &AM);
/// Return true if the builder has any attribute that's in the
/// specified builder.
- bool overlaps(const AttrBuilder &B) const;
+ bool overlaps(const AttributeMask &AM) const;
/// Return true if the builder has the specified attribute.
bool contains(Attribute::AttrKind A) const {
@@ -1168,14 +1238,14 @@ public:
namespace AttributeFuncs {
/// Which attributes cannot be applied to a type.
-AttrBuilder typeIncompatible(Type *Ty);
+AttributeMask typeIncompatible(Type *Ty);
/// Get param/return attributes which imply immediate undefined behavior if an
/// invalid value is passed. For example, this includes noundef (where undef
/// implies UB), but not nonnull (where null implies poison). It also does not
/// include attributes like nocapture, which constrain the function
/// implementation rather than the passed value.
-AttrBuilder getUBImplyingAttributes();
+AttributeMask getUBImplyingAttributes();
/// \returns Return true if the two functions have compatible target-independent
/// attributes for inlining purposes.
diff --git a/llvm/include/llvm/IR/Function.h b/llvm/include/llvm/IR/Function.h
index 669418eacbb0..2c94897c61dc 100644
--- a/llvm/include/llvm/IR/Function.h
+++ b/llvm/include/llvm/IR/Function.h
@@ -364,7 +364,7 @@ public:
/// Remove function attribute from this function.
void removeFnAttr(StringRef Kind);
- void removeFnAttrs(const AttrBuilder &Attrs);
+ void removeFnAttrs(const AttributeMask &Attrs);
/// removes the attribute from the return value list of attributes.
void removeRetAttr(Attribute::AttrKind Kind);
@@ -373,7 +373,7 @@ public:
void removeRetAttr(StringRef Kind);
/// removes the attributes from the return value list of attributes.
- void removeRetAttrs(const AttrBuilder &Attrs);
+ void removeRetAttrs(const AttributeMask &Attrs);
/// removes the attribute from the list of attributes.
void removeParamAttr(unsigned ArgNo, Attribute::AttrKind Kind);
@@ -382,7 +382,7 @@ public:
void removeParamAttr(unsigned ArgNo, StringRef Kind);
/// removes the attribute from the list of attributes.
- void removeParamAttrs(unsigned ArgNo, const AttrBuilder &Attrs);
+ void removeParamAttrs(unsigned ArgNo, const AttributeMask &Attrs);
/// Return true if the function has the attribute.
bool hasFnAttribute(Attribute::AttrKind Kind) const;
diff --git a/llvm/include/llvm/IR/InstrTypes.h b/llvm/include/llvm/IR/InstrTypes.h
index 143a87f4997d..3eedb762d124 100644
--- a/llvm/include/llvm/IR/InstrTypes.h
+++ b/llvm/include/llvm/IR/InstrTypes.h
@@ -1544,7 +1544,7 @@ public:
}
/// Removes the attributes from the function
- void removeFnAttrs(const AttrBuilder &AttrsToRemove) {
+ void removeFnAttrs(const AttributeMask &AttrsToRemove) {
Attrs = Attrs.removeFnAttributes(getContext(), AttrsToRemove);
}
@@ -1559,7 +1559,7 @@ public:
}
/// Removes the attributes from the return value
- void removeRetAttrs(const AttrBuilder &AttrsToRemove) {
+ void removeRetAttrs(const AttributeMask &AttrsToRemove) {
Attrs = Attrs.removeRetAttributes(getContext(), AttrsToRemove);
}
@@ -1576,7 +1576,7 @@ public:
}
/// Removes the attributes from the given argument
- void removeParamAttrs(unsigned ArgNo, const AttrBuilder &AttrsToRemove) {
+ void removeParamAttrs(unsigned ArgNo, const AttributeMask &AttrsToRemove) {
Attrs = Attrs.removeParamAttributes(getContext(), ArgNo, AttrsToRemove);
}
diff --git a/llvm/lib/IR/Attributes.cpp b/llvm/lib/IR/Attributes.cpp
index 2c917e46dfde..c1b63c036ef0 100644
--- a/llvm/lib/IR/Attributes.cpp
+++ b/llvm/lib/IR/Attributes.cpp
@@ -651,7 +651,7 @@ AttributeSet AttributeSet::removeAttribute(LLVMContext &C,
}
AttributeSet AttributeSet::removeAttributes(LLVMContext &C,
- const AttrBuilder &Attrs) const {
+ const AttributeMask &Attrs) const {
AttrBuilder B(*this);
// If there is nothing to remove, directly return the original set.
if (!B.overlaps(Attrs))
@@ -1314,9 +1314,8 @@ AttributeList AttributeList::removeAttributeAtIndex(LLVMContext &C,
return getImpl(C, AttrSets);
}
-AttributeList
-AttributeList::removeAttributesAtIndex(LLVMContext &C, unsigned Index,
- const AttrBuilder &AttrsToRemove) const {
+AttributeList AttributeList::removeAttributesAtIndex(
+ LLVMContext &C, unsigned Index, const AttributeMask &AttrsToRemove) const {
AttributeSet Attrs = getAttributes(Index);
AttributeSet NewAttrs = Attrs.removeAttributes(C, AttrsToRemove);
// If nothing was removed, return the original list.
@@ -1604,6 +1603,11 @@ AttrBuilder &AttrBuilder::addAttribute(StringRef A, StringRef V) {
return *this;
}
+AttrBuilder &AttrBuilder::removeAttributes(AttributeList AL, uint64_t Index) {
+ remove(AttributeMask(AL.getAttributes(Index)));
+ return *this;
+}
+
AttrBuilder &AttrBuilder::removeAttribute(Attribute::AttrKind Val) {
assert((unsigned)Val < Attribute::EndAttrKinds && "Attribute out of range!");
Attrs[Val] = false;
@@ -1616,11 +1620,6 @@ AttrBuilder &AttrBuilder::removeAttribute(Attribute::AttrKind Val) {
return *this;
}
-AttrBuilder &AttrBuilder::removeAttributes(AttributeList A, uint64_t Index) {
- remove(A.getAttributes(Index));
- return *this;
-}
-
AttrBuilder &AttrBuilder::removeAttribute(StringRef A) {
TargetDepAttrs.erase(A);
return *this;
@@ -1760,34 +1759,33 @@ AttrBuilder &AttrBuilder::merge(const AttrBuilder &B) {
return *this;
}
-AttrBuilder &AttrBuilder::remove(const AttrBuilder &B) {
+AttrBuilder &AttrBuilder::remove(const AttributeMask &AM) {
// FIXME: What if both have an int/type attribute, but they don't match?!
for (unsigned Index = 0; Index < Attribute::NumIntAttrKinds; ++Index)
- if (B.IntAttrs[Index])
+ if (AM.contains((Attribute::AttrKind)Index))
IntAttrs[Index] = 0;
for (unsigned Index = 0; Index < Attribute::NumTypeAttrKinds; ++Index)
- if (B.TypeAttrs[Index])
+ if (AM.contains((Attribute::AttrKind)Index))
TypeAttrs[Index] = nullptr;
- Attrs &= ~B.Attrs;
+ Attrs &= ~AM.attrs();
- for (const auto &I : B.td_attrs())
- TargetDepAttrs.erase(I.first);
+ for (const auto &I : AM.td_attrs())
+ TargetDepAttrs.erase(I);
return *this;
}
-bool AttrBuilder::overlaps(const AttrBuilder &B) const {
+bool AttrBuilder::overlaps(const AttributeMask &AM) const {
// First check if any of the target independent attributes overlap.
- if ((Attrs & B.Attrs).any())
+ if ((Attrs & AM.attrs()).any())
return true;
// Then check if any target dependent ones do.
for (const auto &I : td_attrs())
- if (B.contains(I.first))
+ if (AM.contains(I.first))
return true;
-
return false;
}
@@ -1835,8 +1833,8 @@ bool AttrBuilder::operator==(const AttrBuilder &B) const {
//===----------------------------------------------------------------------===//
/// Which attributes cannot be applied to a type.
-AttrBuilder AttributeFuncs::typeIncompatible(Type *Ty) {
- AttrBuilder Incompatible;
+AttributeMask AttributeFuncs::typeIncompatible(Type *Ty) {
+ AttributeMask Incompatible;
if (!Ty->isIntegerTy())
// Attributes that only apply to integers.
@@ -1852,18 +1850,18 @@ AttrBuilder AttributeFuncs::typeIncompatible(Type *Ty) {
.addAttribute(Attribute::ReadNone)
.addAttribute(Attribute::ReadOnly)
.addAttribute(Attribute::SwiftError)
- .addDereferenceableAttr(1) // the int here is ignored
- .addDereferenceableOrNullAttr(1) // the int here is ignored
- .addPreallocatedAttr(Ty)
- .addInAllocaAttr(Ty)
- .addByValAttr(Ty)
- .addStructRetAttr(Ty)
- .addByRefAttr(Ty)
- .addTypeAttr(Attribute::ElementType, Ty);
+ .addAttribute(Attribute::Dereferenceable)
+ .addAttribute(Attribute::DereferenceableOrNull)
+ .addAttribute(Attribute::Preallocated)
+ .addAttribute(Attribute::InAlloca)
+ .addAttribute(Attribute::ByVal)
+ .addAttribute(Attribute::StructRet)
+ .addAttribute(Attribute::ByRef)
+ .addAttribute(Attribute::ElementType);
if (!Ty->isPtrOrPtrVectorTy())
// Attributes that only apply to pointers or vectors of pointers.
- Incompatible.addAlignmentAttr(1); // the int here is ignored
+ Incompatible.addAttribute(Attribute::Alignment);
// Some attributes can apply to all "values" but there are no `void` values.
if (Ty->isVoidTy())
@@ -1872,12 +1870,12 @@ AttrBuilder AttributeFuncs::typeIncompatible(Type *Ty) {
return Incompatible;
}
-AttrBuilder AttributeFuncs::getUBImplyingAttributes() {
- AttrBuilder B;
- B.addAttribute(Attribute::NoUndef);
- B.addDereferenceableAttr(1);
- B.addDereferenceableOrNullAttr(1);
- return B;
+AttributeMask AttributeFuncs::getUBImplyingAttributes() {
+ AttributeMask AM;
+ AM.addAttribute(Attribute::NoUndef);
+ AM.addAttribute(Attribute::Dereferenceable);
+ AM.addAttribute(Attribute::DereferenceableOrNull);
+ return AM;
}
template<typename AttrClass>
@@ -1916,7 +1914,7 @@ static void adjustCallerSSPLevel(Function &Caller, const Function &Callee) {
// If upgrading the SSP attribute, clear out the old SSP Attributes first.
// Having multiple SSP attributes doesn't actually hurt, but it adds useless
// clutter to the IR.
- AttrBuilder OldSSPAttr;
+ AttributeMask OldSSPAttr;
OldSSPAttr.addAttribute(Attribute::StackProtect)
.addAttribute(Attribute::StackProtectStrong)
.addAttribute(Attribute::StackProtectReq);
diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp
index f1a6402fb11b..93e15e43845c 100644
--- a/llvm/lib/IR/Function.cpp
+++ b/llvm/lib/IR/Function.cpp
@@ -300,9 +300,9 @@ void Argument::removeAttr(Attribute::AttrKind Kind) {
getParent()->removeParamAttr(getArgNo(), Kind);
}
-void Argument::removeAttrs(const AttrBuilder &B) {
+void Argument::removeAttrs(const AttributeMask &AM) {
AttributeList AL = getParent()->getAttributes();
- AL = AL.removeParamAttributes(Parent->getContext(), getArgNo(), B);
+ AL = AL.removeParamAttributes(Parent->getContext(), getArgNo(), AM);
getParent()->setAttributes(AL);
}
@@ -589,8 +589,8 @@ void Function::removeFnAttr(StringRef Kind) {
AttributeSets = AttributeSets.removeFnAttribute(getContext(), Kind);
}
-void Function::removeFnAttrs(const AttrBuilder &Attrs) {
- AttributeSets = AttributeSets.removeFnAttributes(getContext(), Attrs);
+void Function::removeFnAttrs(const AttributeMask &AM) {
+ AttributeSets = AttributeSets.removeFnAttributes(getContext(), AM);
}
void Function::removeRetAttr(Attribute::AttrKind Kind) {
@@ -601,7 +601,7 @@ void Function::removeRetAttr(StringRef Kind) {
AttributeSets = AttributeSets.removeRetAttribute(getContext(), Kind);
}
-void Function::removeRetAttrs(const AttrBuilder &Attrs) {
+void Function::removeRetAttrs(const AttributeMask &Attrs) {
AttributeSets = AttributeSets.removeRetAttributes(getContext(), Attrs);
}
@@ -613,7 +613,7 @@ void Function::removeParamAttr(unsigned ArgNo, StringRef Kind) {
AttributeSets = AttributeSets.removeParamAttribute(getContext(), ArgNo, Kind);
}
-void Function::removeParamAttrs(unsigned ArgNo, const AttrBuilder &Attrs) {
+void Function::removeParamAttrs(unsigned ArgNo, const AttributeMask &Attrs) {
AttributeSets =
AttributeSets.removeParamAttributes(getContext(), ArgNo, Attrs);
}
diff --git a/llvm/lib/IR/Instruction.cpp b/llvm/lib/IR/Instruction.cpp
index 4480ec799c35..770fd8aa918b 100644
--- a/llvm/lib/IR/Instruction.cpp
+++ b/llvm/lib/IR/Instruction.cpp
@@ -186,7 +186,8 @@ void Instruction::dropUndefImplyingAttrsAndUnknownMetadata(
AttributeList AL = CB->getAttributes();
if (AL.isEmpty())
return;
- AttrBuilder UBImplyingAttributes = AttributeFuncs::getUBImplyingAttributes();
+ AttributeMask UBImplyingAttributes =
+ AttributeFuncs::getUBImplyingAttributes();
for (unsigned ArgNo = 0; ArgNo < CB->arg_size(); ArgNo++)
CB->removeParamAttrs(ArgNo, UBImplyingAttributes);
CB->removeRetAttrs(UBImplyingAttributes);
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 9ce37db9ea6c..46da9cfbc6b5 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -1793,7 +1793,7 @@ void Verifier::verifyParameterAttrs(AttributeSet Attrs, Type *Ty,
"'noinline and alwaysinline' are incompatible!",
V);
- AttrBuilder IncompatibleAttrs = AttributeFuncs::typeIncompatible(Ty);
+ AttributeMask IncompatibleAttrs = AttributeFuncs::typeIncompatible(Ty);
for (Attribute Attr : Attrs) {
if (!Attr.isStringAttribute() &&
IncompatibleAttrs.contains(Attr.getKindAsEnum())) {
diff --git a/llvm/lib/Target/AMDGPU/AMDGPURewriteOutArguments.cpp b/llvm/lib/Target/AMDGPU/AMDGPURewriteOutArguments.cpp
index 45f7c2f369bd..3d578a9b891e 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPURewriteOutArguments.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPURewriteOutArguments.cpp
@@ -353,7 +353,7 @@ bool AMDGPURewriteOutArguments::runOnFunction(Function &F) {
// off any return attributes, e.g. zeroext doesn't make sense with a struct.
NewFunc->stealArgumentListFrom(F);
- AttrBuilder RetAttrs;
+ AttributeMask RetAttrs;
RetAttrs.addAttribute(Attribute::SExt);
RetAttrs.addAttribute(Attribute::ZExt);
RetAttrs.addAttribute(Attribute::NoAlias);
diff --git a/llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp b/llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp
index fb9ab7954e36..d71e69a538d7 100644
--- a/llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp
+++ b/llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp
@@ -287,7 +287,8 @@ bool DeadArgumentEliminationPass::RemoveDeadArgumentsFromCallers(Function &Fn) {
SmallVector<unsigned, 8> UnusedArgs;
bool Changed = false;
- AttrBuilder UBImplyingAttributes = AttributeFuncs::getUBImplyingAttributes();
+ AttributeMask UBImplyingAttributes =
+ AttributeFuncs::getUBImplyingAttributes();
for (Argument &Arg : Fn.args()) {
if (!Arg.hasSwiftErrorAttr() && Arg.use_empty() &&
!Arg.hasPassPointeeByValueCopyAttr()) {
diff --git a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
index 321d4a19a585..8fb0c2dc7613 100644
--- a/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
+++ b/llvm/lib/Transforms/IPO/FunctionAttrs.cpp
@@ -301,7 +301,7 @@ static void addReadAttrs(const SCCNodeSet &SCCNodes, AARGetterT &&AARGetter,
Changed.insert(F);
// Clear out any existing attributes.
- AttrBuilder AttrsToRemove;
+ AttributeMask AttrsToRemove;
AttrsToRemove.addAttribute(Attribute::ReadOnly);
AttrsToRemove.addAttribute(Attribute::ReadNone);
AttrsToRemove.addAttribute(Attribute::WriteOnly);
diff --git a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
index 9f26b37bbc79..1e5688828d30 100644
--- a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
@@ -454,7 +454,7 @@ class DataFlowSanitizer {
MDNode *OriginStoreWeights;
DFSanABIList ABIList;
DenseMap<Value *, Function *> UnwrappedFnMap;
- AttrBuilder ReadOnlyNoneAttrs;
+ AttributeMask ReadOnlyNoneAttrs;
/// Memory map parameters used in calculation mapping application addresses
/// to shadow addresses and origin addresses.
diff --git a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
index 446e601cd4d7..0ae425117fc0 100644
--- a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
@@ -3664,7 +3664,7 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
// will become a non-readonly function after it is instrumented by us. To
// prevent this code from being optimized out, mark that function
// non-readonly in advance.
- AttrBuilder B;
+ AttributeMask B;
B.addAttribute(Attribute::ReadOnly)
.addAttribute(Attribute::ReadNone)
.addAttribute(Attribute::WriteOnly)
@@ -5359,7 +5359,7 @@ bool MemorySanitizer::sanitizeFunction(Function &F, TargetLibraryInfo &TLI) {
MemorySanitizerVisitor Visitor(F, *this, TLI);
// Clear out readonly/readnone attributes.
- AttrBuilder B;
+ AttributeMask B;
B.addAttribute(Attribute::ReadOnly)
.addAttribute(Attribute::ReadNone)
.addAttribute(Attribute::WriteOnly)
diff --git a/llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp b/llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp
index e12eca0ed287..5f4e8f1dad0a 100644
--- a/llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp
+++ b/llvm/lib/Transforms/Scalar/RewriteStatepointsForGC.cpp
@@ -1373,7 +1373,7 @@ static AttributeList legalizeCallAttributes(LLVMContext &Ctx,
for (Attribute A : AL.getFnAttrs()) {
if (isStatepointDirectiveAttr(A))
- FnAttrs.remove(A);
+ FnAttrs.removeAttribute(A);
}
// Just skip parameter and return attributes for now
@@ -2643,10 +2643,10 @@ static bool insertParsePoints(Function &F, DominatorTree &DT,
// List of all parameter and return attributes which must be stripped when
// lowering from the abstract machine model. Note that we list attributes
// here which aren't valid as return attributes, that is okay.
-static AttrBuilder getParamAndReturnAttributesToRemove() {
- AttrBuilder R;
- R.addDereferenceableAttr(1);
- R.addDereferenceableOrNullAttr(1);
+static AttributeMask getParamAndReturnAttributesToRemove() {
+ AttributeMask R;
+ R.addAttribute(Attribute::Dereferenceable);
+ R.addAttribute(Attribute::DereferenceableOrNull);
R.addAttribute(Attribute::ReadNone);
R.addAttribute(Attribute::ReadOnly);
R.addAttribute(Attribute::WriteOnly);
@@ -2668,7 +2668,7 @@ static void stripNonValidAttributesFromPrototype(Function &F) {
return;
}
- AttrBuilder R = getParamAndReturnAttributesToRemove();
+ AttributeMask R = getParamAndReturnAttributesToRemove();
for (Argument &A : F.args())
if (isa<PointerType>(A.getType()))
F.removeParamAttrs(A.getArgNo(), R);
@@ -2742,7 +2742,7 @@ static void stripNonValidDataFromBody(Function &F) {
stripInvalidMetadataFromInstruction(I);
- AttrBuilder R = getParamAndReturnAttributesToRemove();
+ AttributeMask R = getParamAndReturnAttributesToRemove();
if (auto *Call = dyn_cast<CallBase>(&I)) {
for (int i = 0, e = Call->arg_size(); i != e; i++)
if (isa<PointerType>(Call->getArgOperand(i)->getType()))
diff --git a/llvm/lib/Transforms/Scalar/SCCP.cpp b/llvm/lib/Transforms/Scalar/SCCP.cpp
index ff2f8a25f379..c34da51e6dc1 100644
--- a/llvm/lib/Transforms/Scalar/SCCP.cpp
+++ b/llvm/lib/Transforms/Scalar/SCCP.cpp
@@ -486,7 +486,7 @@ bool llvm::runIPSCCP(
// inaccessiblemem_or_argmemonly attributes do not hold any longer. Remove
// them from both the function and callsites.
if (ReplacedPointerArg) {
- AttrBuilder AttributesToRemove;
+ AttributeMask AttributesToRemove;
AttributesToRemove.addAttribute(Attribute::ArgMemOnly);
AttributesToRemove.addAttribute(Attribute::InaccessibleMemOrArgMemOnly);
F.removeFnAttrs(AttributesToRemove);
diff --git a/llvm/unittests/IR/AttributesTest.cpp b/llvm/unittests/IR/AttributesTest.cpp
index 188d4e342e85..9bc5e474a272 100644
--- a/llvm/unittests/IR/AttributesTest.cpp
+++ b/llvm/unittests/IR/AttributesTest.cpp
@@ -81,12 +81,12 @@ TEST(Attributes, RemoveAlign) {
AttrBuilder B_align_readonly;
B_align_readonly.addAttribute(AlignAttr);
B_align_readonly.addAttribute(Attribute::ReadOnly);
- AttrBuilder B_align;
+ AttributeMask B_align;
B_align.addAttribute(AlignAttr);
AttrBuilder B_stackalign_optnone;
B_stackalign_optnone.addAttribute(StackAlignAttr);
B_stackalign_optnone.addAttribute(Attribute::OptimizeNone);
- AttrBuilder B_stackalign;
+ AttributeMask B_stackalign;
B_stackalign.addAttribute(StackAlignAttr);
AttributeSet AS = AttributeSet::get(C, B_align_readonly);