28
28
#include < cassert>
29
29
#include < cstdint>
30
30
#include < map>
31
+ #include < set>
31
32
#include < string>
32
33
#include < utility>
33
34
34
35
namespace llvm {
35
36
36
37
class AttrBuilder ;
38
+ class AttributeMask ;
37
39
class AttributeImpl ;
38
40
class AttributeListImpl ;
39
41
class AttributeSetNode ;
@@ -320,7 +322,7 @@ class AttributeSet {
320
322
// / Remove the specified attributes from this set. Returns a new set because
321
323
// / attribute sets are immutable.
322
324
LLVM_NODISCARD AttributeSet
323
- removeAttributes (LLVMContext &C, const AttrBuilder &AttrsToRemove) const ;
325
+ removeAttributes (LLVMContext &C, const AttributeMask &AttrsToRemove) const ;
324
326
325
327
// / Return the number of attributes in this set.
326
328
unsigned getNumAttributes () const ;
@@ -580,7 +582,7 @@ class AttributeList {
580
582
// / Remove the specified attributes at the specified index from this
581
583
// / attribute list. Returns a new list because attribute lists are immutable.
582
584
LLVM_NODISCARD AttributeList removeAttributesAtIndex (
583
- LLVMContext &C, unsigned Index, const AttrBuilder &AttrsToRemove) const ;
585
+ LLVMContext &C, unsigned Index, const AttributeMask &AttrsToRemove) const ;
584
586
585
587
// / Remove all attributes at the specified index from this
586
588
// / attribute list. Returns a new list because attribute lists are immutable.
@@ -604,7 +606,7 @@ class AttributeList {
604
606
// / Remove the specified attribute at the function index from this
605
607
// / attribute list. Returns a new list because attribute lists are immutable.
606
608
LLVM_NODISCARD AttributeList
607
- removeFnAttributes (LLVMContext &C, const AttrBuilder &AttrsToRemove) const {
609
+ removeFnAttributes (LLVMContext &C, const AttributeMask &AttrsToRemove) const {
608
610
return removeAttributesAtIndex (C, FunctionIndex, AttrsToRemove);
609
611
}
610
612
@@ -630,8 +632,8 @@ class AttributeList {
630
632
631
633
// / Remove the specified attribute at the return value index from this
632
634
// / 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 {
635
637
return removeAttributesAtIndex (C, ReturnIndex, AttrsToRemove);
636
638
}
637
639
@@ -652,8 +654,9 @@ class AttributeList {
652
654
653
655
// / Remove the specified attribute at the specified arg index from this
654
656
// / 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 {
657
660
return removeAttributesAtIndex (C, ArgNo + FirstArgIndex, AttrsToRemove);
658
661
}
659
662
@@ -927,6 +930,65 @@ template <> struct DenseMapInfo<AttributeList, void> {
927
930
}
928
931
};
929
932
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
+
930
992
// ===----------------------------------------------------------------------===//
931
993
// / \class
932
994
// / This class is used in conjunction with the Attribute::get method to
@@ -975,21 +1037,29 @@ class AttrBuilder {
975
1037
// / Remove an attribute from the builder.
976
1038
AttrBuilder &removeAttribute (Attribute::AttrKind Val);
977
1039
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
+
978
1051
// / Remove the attributes from the builder.
979
1052
AttrBuilder &removeAttributes (AttributeList A, uint64_t WithoutIndex);
980
1053
981
- // / Remove the target-dependent attribute to the builder.
982
- AttrBuilder &removeAttribute (StringRef A);
983
-
984
1054
// / Add the attributes from the builder.
985
1055
AttrBuilder &merge (const AttrBuilder &B);
986
1056
987
1057
// / Remove the attributes from the builder.
988
- AttrBuilder &remove (const AttrBuilder &B );
1058
+ AttrBuilder &remove (const AttributeMask &AM );
989
1059
990
1060
// / Return true if the builder has any attribute that's in the
991
1061
// / specified builder.
992
- bool overlaps (const AttrBuilder &B ) const ;
1062
+ bool overlaps (const AttributeMask &AM ) const ;
993
1063
994
1064
// / Return true if the builder has the specified attribute.
995
1065
bool contains (Attribute::AttrKind A) const {
@@ -1168,14 +1238,14 @@ class AttrBuilder {
1168
1238
namespace AttributeFuncs {
1169
1239
1170
1240
// / Which attributes cannot be applied to a type.
1171
- AttrBuilder typeIncompatible (Type *Ty);
1241
+ AttributeMask typeIncompatible (Type *Ty);
1172
1242
1173
1243
// / Get param/return attributes which imply immediate undefined behavior if an
1174
1244
// / invalid value is passed. For example, this includes noundef (where undef
1175
1245
// / implies UB), but not nonnull (where null implies poison). It also does not
1176
1246
// / include attributes like nocapture, which constrain the function
1177
1247
// / implementation rather than the passed value.
1178
- AttrBuilder getUBImplyingAttributes ();
1248
+ AttributeMask getUBImplyingAttributes ();
1179
1249
1180
1250
// / \returns Return true if the two functions have compatible target-independent
1181
1251
// / attributes for inlining purposes.
0 commit comments