2828#include < cassert>
2929#include < cstdint>
3030#include < map>
31+ #include < set>
3132#include < string>
3233#include < utility>
3334
3435namespace llvm {
3536
3637class AttrBuilder ;
38+ class AttributeMask ;
3739class AttributeImpl ;
3840class AttributeListImpl ;
3941class AttributeSetNode ;
@@ -320,7 +322,7 @@ class AttributeSet {
320322 // / Remove the specified attributes from this set. Returns a new set because
321323 // / attribute sets are immutable.
322324 LLVM_NODISCARD AttributeSet
323- removeAttributes (LLVMContext &C, const AttrBuilder &AttrsToRemove) const ;
325+ removeAttributes (LLVMContext &C, const AttributeMask &AttrsToRemove) const ;
324326
325327 // / Return the number of attributes in this set.
326328 unsigned getNumAttributes () const ;
@@ -580,7 +582,7 @@ class AttributeList {
580582 // / Remove the specified attributes at the specified index from this
581583 // / attribute list. Returns a new list because attribute lists are immutable.
582584 LLVM_NODISCARD AttributeList removeAttributesAtIndex (
583- LLVMContext &C, unsigned Index, const AttrBuilder &AttrsToRemove) const ;
585+ LLVMContext &C, unsigned Index, const AttributeMask &AttrsToRemove) const ;
584586
585587 // / Remove all attributes at the specified index from this
586588 // / attribute list. Returns a new list because attribute lists are immutable.
@@ -604,7 +606,7 @@ class AttributeList {
604606 // / Remove the specified attribute at the function index from this
605607 // / attribute list. Returns a new list because attribute lists are immutable.
606608 LLVM_NODISCARD AttributeList
607- removeFnAttributes (LLVMContext &C, const AttrBuilder &AttrsToRemove) const {
609+ removeFnAttributes (LLVMContext &C, const AttributeMask &AttrsToRemove) const {
608610 return removeAttributesAtIndex (C, FunctionIndex, AttrsToRemove);
609611 }
610612
@@ -630,8 +632,8 @@ class AttributeList {
630632
631633 // / Remove the specified attribute at the return value index from this
632634 // / attribute list. Returns a new list because attribute lists are immutable.
633- LLVM_NODISCARD AttributeList
634- removeRetAttributes ( LLVMContext &C, const AttrBuilder &AttrsToRemove) const {
635+ LLVM_NODISCARD AttributeList removeRetAttributes (
636+ LLVMContext &C, const AttributeMask &AttrsToRemove) const {
635637 return removeAttributesAtIndex (C, ReturnIndex, AttrsToRemove);
636638 }
637639
@@ -652,8 +654,9 @@ class AttributeList {
652654
653655 // / Remove the specified attribute at the specified arg index from this
654656 // / attribute list. Returns a new list because attribute lists are immutable.
655- LLVM_NODISCARD AttributeList removeParamAttributes (
656- LLVMContext &C, unsigned ArgNo, const AttrBuilder &AttrsToRemove) const {
657+ LLVM_NODISCARD AttributeList
658+ removeParamAttributes (LLVMContext &C, unsigned ArgNo,
659+ const AttributeMask &AttrsToRemove) const {
657660 return removeAttributesAtIndex (C, ArgNo + FirstArgIndex, AttrsToRemove);
658661 }
659662
@@ -927,6 +930,65 @@ template <> struct DenseMapInfo<AttributeList, void> {
927930 }
928931};
929932
933+ // ===----------------------------------------------------------------------===//
934+ // / \class
935+ // / This class stores enough information to efficiently remove some attributes
936+ // / from an existing AttrBuilder, AttributeSet or AttributeList.
937+ class AttributeMask {
938+ std::bitset<Attribute::EndAttrKinds> Attrs;
939+ std::set<SmallString<32 >, std::less<>> TargetDepAttrs;
940+
941+ public:
942+ AttributeMask () = default ;
943+ AttributeMask (const AttributeMask &) = delete ;
944+ AttributeMask (AttributeMask &&) = default ;
945+
946+ AttributeMask (AttributeSet AS) {
947+ for (Attribute A : AS)
948+ addAttribute (A);
949+ }
950+
951+ // / Add an attribute to the mask.
952+ AttributeMask &addAttribute (Attribute::AttrKind Val) {
953+ assert ((unsigned )Val < Attribute::EndAttrKinds &&
954+ " Attribute out of range!" );
955+ Attrs[Val] = true ;
956+ return *this ;
957+ }
958+
959+ // / Add the Attribute object to the builder.
960+ AttributeMask &addAttribute (Attribute A) {
961+ if (A.isStringAttribute ())
962+ addAttribute (A.getKindAsString ());
963+ else
964+ addAttribute (A.getKindAsEnum ());
965+ return *this ;
966+ }
967+
968+ // / Add the target-dependent attribute to the builder.
969+ AttributeMask &addAttribute (StringRef A) {
970+ TargetDepAttrs.insert (A);
971+ return *this ;
972+ }
973+
974+ // / Return true if the builder has the specified attribute.
975+ bool contains (Attribute::AttrKind A) const {
976+ assert ((unsigned )A < Attribute::EndAttrKinds && " Attribute out of range!" );
977+ return Attrs[A];
978+ }
979+
980+ // / Return true if the builder has the specified target-dependent
981+ // / attribute.
982+ bool contains (StringRef A) const { return TargetDepAttrs.count (A); }
983+
984+ using td_const_iterator = decltype (TargetDepAttrs)::const_iterator;
985+ using td_const_range = iterator_range<td_const_iterator>;
986+ td_const_range td_attrs () const {
987+ return {TargetDepAttrs.begin (), TargetDepAttrs.end ()};
988+ }
989+ auto const &attrs () const { return Attrs; }
990+ };
991+
930992// ===----------------------------------------------------------------------===//
931993// / \class
932994// / This class is used in conjunction with the Attribute::get method to
@@ -975,21 +1037,29 @@ class AttrBuilder {
9751037 // / Remove an attribute from the builder.
9761038 AttrBuilder &removeAttribute (Attribute::AttrKind Val);
9771039
1040+ // / Remove the target-dependent attribute from the builder.
1041+ AttrBuilder &removeAttribute (StringRef A);
1042+
1043+ // / Remove the target-dependent attribute from the builder.
1044+ AttrBuilder &removeAttribute (Attribute A) {
1045+ if (A.isStringAttribute ())
1046+ return removeAttribute (A.getKindAsString ());
1047+ else
1048+ return removeAttribute (A.getKindAsEnum ());
1049+ }
1050+
9781051 // / Remove the attributes from the builder.
9791052 AttrBuilder &removeAttributes (AttributeList A, uint64_t WithoutIndex);
9801053
981- // / Remove the target-dependent attribute to the builder.
982- AttrBuilder &removeAttribute (StringRef A);
983-
9841054 // / Add the attributes from the builder.
9851055 AttrBuilder &merge (const AttrBuilder &B);
9861056
9871057 // / Remove the attributes from the builder.
988- AttrBuilder &remove (const AttrBuilder &B );
1058+ AttrBuilder &remove (const AttributeMask &AM );
9891059
9901060 // / Return true if the builder has any attribute that's in the
9911061 // / specified builder.
992- bool overlaps (const AttrBuilder &B ) const ;
1062+ bool overlaps (const AttributeMask &AM ) const ;
9931063
9941064 // / Return true if the builder has the specified attribute.
9951065 bool contains (Attribute::AttrKind A) const {
@@ -1168,14 +1238,14 @@ class AttrBuilder {
11681238namespace AttributeFuncs {
11691239
11701240// / Which attributes cannot be applied to a type.
1171- AttrBuilder typeIncompatible (Type *Ty);
1241+ AttributeMask typeIncompatible (Type *Ty);
11721242
11731243// / Get param/return attributes which imply immediate undefined behavior if an
11741244// / invalid value is passed. For example, this includes noundef (where undef
11751245// / implies UB), but not nonnull (where null implies poison). It also does not
11761246// / include attributes like nocapture, which constrain the function
11771247// / implementation rather than the passed value.
1178- AttrBuilder getUBImplyingAttributes ();
1248+ AttributeMask getUBImplyingAttributes ();
11791249
11801250// / \returns Return true if the two functions have compatible target-independent
11811251// / attributes for inlining purposes.
0 commit comments