File indexing completed on 2026-05-10 08:43:57
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #ifndef LLVM_IR_ATTRIBUTES_H
0016 #define LLVM_IR_ATTRIBUTES_H
0017
0018 #include "llvm-c/Types.h"
0019 #include "llvm/ADT/ArrayRef.h"
0020 #include "llvm/ADT/BitmaskEnum.h"
0021 #include "llvm/ADT/StringRef.h"
0022 #include "llvm/Config/llvm-config.h"
0023 #include "llvm/Support/Alignment.h"
0024 #include "llvm/Support/CodeGen.h"
0025 #include "llvm/Support/ModRef.h"
0026 #include "llvm/Support/PointerLikeTypeTraits.h"
0027 #include <cassert>
0028 #include <cstdint>
0029 #include <optional>
0030 #include <string>
0031 #include <utility>
0032
0033 namespace llvm {
0034
0035 class AttrBuilder;
0036 class AttributeMask;
0037 class AttributeImpl;
0038 class AttributeListImpl;
0039 class AttributeSetNode;
0040 class ConstantRange;
0041 class ConstantRangeList;
0042 class FoldingSetNodeID;
0043 class Function;
0044 class LLVMContext;
0045 class Type;
0046 class raw_ostream;
0047 enum FPClassTest : unsigned;
0048
0049 enum class AllocFnKind : uint64_t {
0050 Unknown = 0,
0051 Alloc = 1 << 0,
0052 Realloc = 1 << 1,
0053 Free = 1 << 2,
0054 Uninitialized = 1 << 3,
0055 Zeroed = 1 << 4,
0056 Aligned = 1 << 5,
0057
0058 LLVM_MARK_AS_BITMASK_ENUM( Aligned)
0059 };
0060
0061
0062
0063
0064
0065
0066
0067 class Attribute {
0068 public:
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086 enum AttrKind {
0087
0088 None,
0089 #define GET_ATTR_ENUM
0090 #include "llvm/IR/Attributes.inc"
0091 EndAttrKinds,
0092 EmptyKey,
0093 TombstoneKey,
0094 };
0095
0096 static const unsigned NumIntAttrKinds = LastIntAttr - FirstIntAttr + 1;
0097 static const unsigned NumTypeAttrKinds = LastTypeAttr - FirstTypeAttr + 1;
0098
0099 static bool isEnumAttrKind(AttrKind Kind) {
0100 return Kind >= FirstEnumAttr && Kind <= LastEnumAttr;
0101 }
0102 static bool isIntAttrKind(AttrKind Kind) {
0103 return Kind >= FirstIntAttr && Kind <= LastIntAttr;
0104 }
0105 static bool isTypeAttrKind(AttrKind Kind) {
0106 return Kind >= FirstTypeAttr && Kind <= LastTypeAttr;
0107 }
0108 static bool isConstantRangeAttrKind(AttrKind Kind) {
0109 return Kind >= FirstConstantRangeAttr && Kind <= LastConstantRangeAttr;
0110 }
0111 static bool isConstantRangeListAttrKind(AttrKind Kind) {
0112 return Kind >= FirstConstantRangeListAttr &&
0113 Kind <= LastConstantRangeListAttr;
0114 }
0115
0116 static bool canUseAsFnAttr(AttrKind Kind);
0117 static bool canUseAsParamAttr(AttrKind Kind);
0118 static bool canUseAsRetAttr(AttrKind Kind);
0119
0120 static bool intersectMustPreserve(AttrKind Kind);
0121 static bool intersectWithAnd(AttrKind Kind);
0122 static bool intersectWithMin(AttrKind Kind);
0123 static bool intersectWithCustom(AttrKind Kind);
0124
0125 private:
0126 AttributeImpl *pImpl = nullptr;
0127
0128 Attribute(AttributeImpl *A) : pImpl(A) {}
0129
0130 public:
0131 Attribute() = default;
0132
0133
0134
0135
0136
0137
0138 static Attribute get(LLVMContext &Context, AttrKind Kind, uint64_t Val = 0);
0139 static Attribute get(LLVMContext &Context, StringRef Kind,
0140 StringRef Val = StringRef());
0141 static Attribute get(LLVMContext &Context, AttrKind Kind, Type *Ty);
0142 static Attribute get(LLVMContext &Context, AttrKind Kind,
0143 const ConstantRange &CR);
0144 static Attribute get(LLVMContext &Context, AttrKind Kind,
0145 ArrayRef<ConstantRange> Val);
0146
0147
0148
0149 static Attribute getWithAlignment(LLVMContext &Context, Align Alignment);
0150 static Attribute getWithStackAlignment(LLVMContext &Context, Align Alignment);
0151 static Attribute getWithDereferenceableBytes(LLVMContext &Context,
0152 uint64_t Bytes);
0153 static Attribute getWithDereferenceableOrNullBytes(LLVMContext &Context,
0154 uint64_t Bytes);
0155 static Attribute getWithAllocSizeArgs(
0156 LLVMContext &Context, unsigned ElemSizeArg,
0157 const std::optional<unsigned> &NumElemsArg);
0158 static Attribute getWithVScaleRangeArgs(LLVMContext &Context,
0159 unsigned MinValue, unsigned MaxValue);
0160 static Attribute getWithByValType(LLVMContext &Context, Type *Ty);
0161 static Attribute getWithStructRetType(LLVMContext &Context, Type *Ty);
0162 static Attribute getWithByRefType(LLVMContext &Context, Type *Ty);
0163 static Attribute getWithPreallocatedType(LLVMContext &Context, Type *Ty);
0164 static Attribute getWithInAllocaType(LLVMContext &Context, Type *Ty);
0165 static Attribute getWithUWTableKind(LLVMContext &Context, UWTableKind Kind);
0166 static Attribute getWithMemoryEffects(LLVMContext &Context, MemoryEffects ME);
0167 static Attribute getWithNoFPClass(LLVMContext &Context, FPClassTest Mask);
0168
0169
0170
0171 Attribute getWithNewType(LLVMContext &Context, Type *ReplacementTy) {
0172 assert(isTypeAttribute() && "this requires a typed attribute");
0173 return get(Context, getKindAsEnum(), ReplacementTy);
0174 }
0175
0176 static Attribute::AttrKind getAttrKindFromName(StringRef AttrName);
0177
0178 static StringRef getNameFromAttrKind(Attribute::AttrKind AttrKind);
0179
0180
0181
0182 static bool isExistingAttribute(StringRef Name);
0183
0184
0185
0186
0187
0188
0189 bool isEnumAttribute() const;
0190
0191
0192 bool isIntAttribute() const;
0193
0194
0195
0196 bool isStringAttribute() const;
0197
0198
0199 bool isTypeAttribute() const;
0200
0201
0202 bool isConstantRangeAttribute() const;
0203
0204
0205 bool isConstantRangeListAttribute() const;
0206
0207
0208 bool isValid() const { return pImpl; }
0209
0210
0211 bool hasAttribute(AttrKind Val) const;
0212
0213
0214 bool hasAttribute(StringRef Val) const;
0215
0216
0217
0218 bool hasKindAsEnum() const { return !isStringAttribute(); }
0219
0220
0221
0222 Attribute::AttrKind getKindAsEnum() const;
0223
0224
0225
0226 uint64_t getValueAsInt() const;
0227
0228
0229
0230 bool getValueAsBool() const;
0231
0232
0233
0234 StringRef getKindAsString() const;
0235
0236
0237
0238 StringRef getValueAsString() const;
0239
0240
0241
0242 Type *getValueAsType() const;
0243
0244
0245
0246 const ConstantRange &getValueAsConstantRange() const;
0247
0248
0249
0250 ArrayRef<ConstantRange> getValueAsConstantRangeList() const;
0251
0252
0253
0254 MaybeAlign getAlignment() const;
0255
0256
0257
0258 MaybeAlign getStackAlignment() const;
0259
0260
0261
0262 uint64_t getDereferenceableBytes() const;
0263
0264
0265
0266 uint64_t getDereferenceableOrNullBytes() const;
0267
0268
0269 std::pair<unsigned, std::optional<unsigned>> getAllocSizeArgs() const;
0270
0271
0272 unsigned getVScaleRangeMin() const;
0273
0274
0275
0276 std::optional<unsigned> getVScaleRangeMax() const;
0277
0278
0279 UWTableKind getUWTableKind() const;
0280
0281
0282 AllocFnKind getAllocKind() const;
0283
0284
0285 MemoryEffects getMemoryEffects() const;
0286
0287
0288 CaptureInfo getCaptureInfo() const;
0289
0290
0291 FPClassTest getNoFPClass() const;
0292
0293
0294 const ConstantRange &getRange() const;
0295
0296
0297 ArrayRef<ConstantRange> getInitializes() const;
0298
0299
0300
0301 std::string getAsString(bool InAttrGrp = false) const;
0302
0303
0304 bool hasParentContext(LLVMContext &C) const;
0305
0306
0307 bool operator==(Attribute A) const { return pImpl == A.pImpl; }
0308 bool operator!=(Attribute A) const { return pImpl != A.pImpl; }
0309
0310
0311 int cmpKind(Attribute A) const;
0312
0313
0314 bool operator<(Attribute A) const;
0315
0316 void Profile(FoldingSetNodeID &ID) const;
0317
0318
0319 void *getRawPointer() const {
0320 return pImpl;
0321 }
0322
0323
0324 static Attribute fromRawPointer(void *RawPtr) {
0325 return Attribute(reinterpret_cast<AttributeImpl*>(RawPtr));
0326 }
0327 };
0328
0329
0330 inline LLVMAttributeRef wrap(Attribute Attr) {
0331 return reinterpret_cast<LLVMAttributeRef>(Attr.getRawPointer());
0332 }
0333
0334
0335 inline Attribute unwrap(LLVMAttributeRef Attr) {
0336 return Attribute::fromRawPointer(Attr);
0337 }
0338
0339
0340
0341
0342
0343
0344
0345 class AttributeSet {
0346 friend AttributeListImpl;
0347 template <typename Ty, typename Enable> friend struct DenseMapInfo;
0348
0349
0350
0351
0352
0353
0354 AttributeSetNode *SetNode = nullptr;
0355
0356 private:
0357 explicit AttributeSet(AttributeSetNode *ASN) : SetNode(ASN) {}
0358
0359 public:
0360
0361 AttributeSet() = default;
0362 AttributeSet(const AttributeSet &) = default;
0363 ~AttributeSet() = default;
0364
0365 static AttributeSet get(LLVMContext &C, const AttrBuilder &B);
0366 static AttributeSet get(LLVMContext &C, ArrayRef<Attribute> Attrs);
0367
0368 bool operator==(const AttributeSet &O) const { return SetNode == O.SetNode; }
0369 bool operator!=(const AttributeSet &O) const { return !(*this == O); }
0370
0371
0372
0373 [[nodiscard]] AttributeSet addAttribute(LLVMContext &C,
0374 Attribute::AttrKind Kind) const;
0375
0376
0377
0378 [[nodiscard]] AttributeSet addAttribute(LLVMContext &C, StringRef Kind,
0379 StringRef Value = StringRef()) const;
0380
0381
0382
0383 [[nodiscard]] AttributeSet addAttributes(LLVMContext &C,
0384 AttributeSet AS) const;
0385
0386
0387
0388 [[nodiscard]] AttributeSet removeAttribute(LLVMContext &C,
0389 Attribute::AttrKind Kind) const;
0390
0391
0392
0393 [[nodiscard]] AttributeSet removeAttribute(LLVMContext &C,
0394 StringRef Kind) const;
0395
0396
0397
0398 [[nodiscard]] AttributeSet
0399 removeAttributes(LLVMContext &C, const AttributeMask &AttrsToRemove) const;
0400
0401
0402
0403
0404 [[nodiscard]] std::optional<AttributeSet>
0405 intersectWith(LLVMContext &C, AttributeSet Other) const;
0406
0407
0408 unsigned getNumAttributes() const;
0409
0410
0411 bool hasAttributes() const { return SetNode != nullptr; }
0412
0413
0414 bool hasAttribute(Attribute::AttrKind Kind) const;
0415
0416
0417 bool hasAttribute(StringRef Kind) const;
0418
0419
0420 Attribute getAttribute(Attribute::AttrKind Kind) const;
0421
0422
0423 Attribute getAttribute(StringRef Kind) const;
0424
0425 MaybeAlign getAlignment() const;
0426 MaybeAlign getStackAlignment() const;
0427 uint64_t getDereferenceableBytes() const;
0428 uint64_t getDereferenceableOrNullBytes() const;
0429 Type *getByValType() const;
0430 Type *getStructRetType() const;
0431 Type *getByRefType() const;
0432 Type *getPreallocatedType() const;
0433 Type *getInAllocaType() const;
0434 Type *getElementType() const;
0435 std::optional<std::pair<unsigned, std::optional<unsigned>>> getAllocSizeArgs()
0436 const;
0437 unsigned getVScaleRangeMin() const;
0438 std::optional<unsigned> getVScaleRangeMax() const;
0439 UWTableKind getUWTableKind() const;
0440 AllocFnKind getAllocKind() const;
0441 MemoryEffects getMemoryEffects() const;
0442 CaptureInfo getCaptureInfo() const;
0443 FPClassTest getNoFPClass() const;
0444 std::string getAsString(bool InAttrGrp = false) const;
0445
0446
0447 bool hasParentContext(LLVMContext &C) const;
0448
0449 using iterator = const Attribute *;
0450
0451 iterator begin() const;
0452 iterator end() const;
0453 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
0454 void dump() const;
0455 #endif
0456 };
0457
0458
0459
0460
0461 template <> struct DenseMapInfo<AttributeSet, void> {
0462 static AttributeSet getEmptyKey() {
0463 auto Val = static_cast<uintptr_t>(-1);
0464 Val <<= PointerLikeTypeTraits<void *>::NumLowBitsAvailable;
0465 return AttributeSet(reinterpret_cast<AttributeSetNode *>(Val));
0466 }
0467
0468 static AttributeSet getTombstoneKey() {
0469 auto Val = static_cast<uintptr_t>(-2);
0470 Val <<= PointerLikeTypeTraits<void *>::NumLowBitsAvailable;
0471 return AttributeSet(reinterpret_cast<AttributeSetNode *>(Val));
0472 }
0473
0474 static unsigned getHashValue(AttributeSet AS) {
0475 return (unsigned((uintptr_t)AS.SetNode) >> 4) ^
0476 (unsigned((uintptr_t)AS.SetNode) >> 9);
0477 }
0478
0479 static bool isEqual(AttributeSet LHS, AttributeSet RHS) { return LHS == RHS; }
0480 };
0481
0482
0483
0484
0485
0486
0487
0488
0489
0490 class AttributeList {
0491 public:
0492 enum AttrIndex : unsigned {
0493 ReturnIndex = 0U,
0494 FunctionIndex = ~0U,
0495 FirstArgIndex = 1,
0496 };
0497
0498 private:
0499 friend class AttrBuilder;
0500 friend class AttributeListImpl;
0501 friend class AttributeSet;
0502 friend class AttributeSetNode;
0503 template <typename Ty, typename Enable> friend struct DenseMapInfo;
0504
0505
0506
0507 AttributeListImpl *pImpl = nullptr;
0508
0509 public:
0510
0511 static AttributeList get(LLVMContext &C,
0512 ArrayRef<std::pair<unsigned, Attribute>> Attrs);
0513 static AttributeList get(LLVMContext &C,
0514 ArrayRef<std::pair<unsigned, AttributeSet>> Attrs);
0515
0516
0517
0518 static AttributeList get(LLVMContext &C, AttributeSet FnAttrs,
0519 AttributeSet RetAttrs,
0520 ArrayRef<AttributeSet> ArgAttrs);
0521
0522 private:
0523 explicit AttributeList(AttributeListImpl *LI) : pImpl(LI) {}
0524
0525 static AttributeList getImpl(LLVMContext &C, ArrayRef<AttributeSet> AttrSets);
0526
0527 AttributeList setAttributesAtIndex(LLVMContext &C, unsigned Index,
0528 AttributeSet Attrs) const;
0529
0530 public:
0531 AttributeList() = default;
0532
0533
0534
0535
0536
0537
0538 static AttributeList get(LLVMContext &C, ArrayRef<AttributeList> Attrs);
0539 static AttributeList get(LLVMContext &C, unsigned Index,
0540 ArrayRef<Attribute::AttrKind> Kinds);
0541 static AttributeList get(LLVMContext &C, unsigned Index,
0542 ArrayRef<Attribute::AttrKind> Kinds,
0543 ArrayRef<uint64_t> Values);
0544 static AttributeList get(LLVMContext &C, unsigned Index,
0545 ArrayRef<StringRef> Kind);
0546 static AttributeList get(LLVMContext &C, unsigned Index,
0547 AttributeSet Attrs);
0548 static AttributeList get(LLVMContext &C, unsigned Index,
0549 const AttrBuilder &B);
0550
0551
0552
0553
0554 [[nodiscard]] AttributeList
0555 addAttributeAtIndex(LLVMContext &C, unsigned Index,
0556 Attribute::AttrKind Kind) const;
0557
0558
0559
0560 [[nodiscard]] AttributeList
0561 addAttributeAtIndex(LLVMContext &C, unsigned Index, StringRef Kind,
0562 StringRef Value = StringRef()) const;
0563
0564
0565
0566 [[nodiscard]] AttributeList
0567 addAttributeAtIndex(LLVMContext &C, unsigned Index, Attribute A) const;
0568
0569
0570
0571 [[nodiscard]] AttributeList addAttributesAtIndex(LLVMContext &C,
0572 unsigned Index,
0573 const AttrBuilder &B) const;
0574
0575
0576
0577 [[nodiscard]] AttributeList addFnAttribute(LLVMContext &C,
0578 Attribute::AttrKind Kind) const {
0579 return addAttributeAtIndex(C, FunctionIndex, Kind);
0580 }
0581
0582
0583
0584 [[nodiscard]] AttributeList addFnAttribute(LLVMContext &C,
0585 Attribute Attr) const {
0586 return addAttributeAtIndex(C, FunctionIndex, Attr);
0587 }
0588
0589
0590
0591 [[nodiscard]] AttributeList
0592 addFnAttribute(LLVMContext &C, StringRef Kind,
0593 StringRef Value = StringRef()) const {
0594 return addAttributeAtIndex(C, FunctionIndex, Kind, Value);
0595 }
0596
0597
0598
0599 [[nodiscard]] AttributeList addFnAttributes(LLVMContext &C,
0600 const AttrBuilder &B) const {
0601 return addAttributesAtIndex(C, FunctionIndex, B);
0602 }
0603
0604
0605
0606 [[nodiscard]] AttributeList addRetAttribute(LLVMContext &C,
0607 Attribute::AttrKind Kind) const {
0608 return addAttributeAtIndex(C, ReturnIndex, Kind);
0609 }
0610
0611
0612
0613 [[nodiscard]] AttributeList addRetAttribute(LLVMContext &C,
0614 Attribute Attr) const {
0615 return addAttributeAtIndex(C, ReturnIndex, Attr);
0616 }
0617
0618
0619
0620 [[nodiscard]] AttributeList addRetAttributes(LLVMContext &C,
0621 const AttrBuilder &B) const {
0622 return addAttributesAtIndex(C, ReturnIndex, B);
0623 }
0624
0625
0626
0627 [[nodiscard]] AttributeList
0628 addParamAttribute(LLVMContext &C, unsigned ArgNo,
0629 Attribute::AttrKind Kind) const {
0630 return addAttributeAtIndex(C, ArgNo + FirstArgIndex, Kind);
0631 }
0632
0633
0634
0635 [[nodiscard]] AttributeList
0636 addParamAttribute(LLVMContext &C, unsigned ArgNo, StringRef Kind,
0637 StringRef Value = StringRef()) const {
0638 return addAttributeAtIndex(C, ArgNo + FirstArgIndex, Kind, Value);
0639 }
0640
0641
0642
0643 [[nodiscard]] AttributeList addParamAttribute(LLVMContext &C,
0644 ArrayRef<unsigned> ArgNos,
0645 Attribute A) const;
0646
0647
0648
0649 [[nodiscard]] AttributeList addParamAttributes(LLVMContext &C, unsigned ArgNo,
0650 const AttrBuilder &B) const {
0651 return addAttributesAtIndex(C, ArgNo + FirstArgIndex, B);
0652 }
0653
0654
0655
0656 [[nodiscard]] AttributeList
0657 removeAttributeAtIndex(LLVMContext &C, unsigned Index,
0658 Attribute::AttrKind Kind) const;
0659
0660
0661
0662 [[nodiscard]] AttributeList
0663 removeAttributeAtIndex(LLVMContext &C, unsigned Index, StringRef Kind) const;
0664 [[nodiscard]] AttributeList removeAttribute(LLVMContext &C, unsigned Index,
0665 StringRef Kind) const {
0666 return removeAttributeAtIndex(C, Index, Kind);
0667 }
0668
0669
0670
0671 [[nodiscard]] AttributeList
0672 removeAttributesAtIndex(LLVMContext &C, unsigned Index,
0673 const AttributeMask &AttrsToRemove) const;
0674
0675
0676
0677 [[nodiscard]] AttributeList removeAttributesAtIndex(LLVMContext &C,
0678 unsigned Index) const;
0679
0680
0681
0682 [[nodiscard]] AttributeList
0683 removeFnAttribute(LLVMContext &C, Attribute::AttrKind Kind) const {
0684 return removeAttributeAtIndex(C, FunctionIndex, Kind);
0685 }
0686
0687
0688
0689 [[nodiscard]] AttributeList removeFnAttribute(LLVMContext &C,
0690 StringRef Kind) const {
0691 return removeAttributeAtIndex(C, FunctionIndex, Kind);
0692 }
0693
0694
0695
0696 [[nodiscard]] AttributeList
0697 removeFnAttributes(LLVMContext &C, const AttributeMask &AttrsToRemove) const {
0698 return removeAttributesAtIndex(C, FunctionIndex, AttrsToRemove);
0699 }
0700
0701
0702
0703 [[nodiscard]] AttributeList removeFnAttributes(LLVMContext &C) const {
0704 return removeAttributesAtIndex(C, FunctionIndex);
0705 }
0706
0707
0708
0709 [[nodiscard]] AttributeList
0710 removeRetAttribute(LLVMContext &C, Attribute::AttrKind Kind) const {
0711 return removeAttributeAtIndex(C, ReturnIndex, Kind);
0712 }
0713
0714
0715
0716 [[nodiscard]] AttributeList removeRetAttribute(LLVMContext &C,
0717 StringRef Kind) const {
0718 return removeAttributeAtIndex(C, ReturnIndex, Kind);
0719 }
0720
0721
0722
0723 [[nodiscard]] AttributeList
0724 removeRetAttributes(LLVMContext &C,
0725 const AttributeMask &AttrsToRemove) const {
0726 return removeAttributesAtIndex(C, ReturnIndex, AttrsToRemove);
0727 }
0728
0729
0730
0731 [[nodiscard]] AttributeList
0732 removeParamAttribute(LLVMContext &C, unsigned ArgNo,
0733 Attribute::AttrKind Kind) const {
0734 return removeAttributeAtIndex(C, ArgNo + FirstArgIndex, Kind);
0735 }
0736
0737
0738
0739 [[nodiscard]] AttributeList
0740 removeParamAttribute(LLVMContext &C, unsigned ArgNo, StringRef Kind) const {
0741 return removeAttributeAtIndex(C, ArgNo + FirstArgIndex, Kind);
0742 }
0743
0744
0745
0746 [[nodiscard]] AttributeList
0747 removeParamAttributes(LLVMContext &C, unsigned ArgNo,
0748 const AttributeMask &AttrsToRemove) const {
0749 return removeAttributesAtIndex(C, ArgNo + FirstArgIndex, AttrsToRemove);
0750 }
0751
0752
0753
0754 [[nodiscard]] AttributeList removeParamAttributes(LLVMContext &C,
0755 unsigned ArgNo) const {
0756 return removeAttributesAtIndex(C, ArgNo + FirstArgIndex);
0757 }
0758
0759
0760
0761 [[nodiscard]] AttributeList
0762 replaceAttributeTypeAtIndex(LLVMContext &C, unsigned ArgNo,
0763 Attribute::AttrKind Kind,
0764 Type *ReplacementTy) const {
0765 Attribute Attr = getAttributeAtIndex(ArgNo, Kind);
0766 auto Attrs = removeAttributeAtIndex(C, ArgNo, Kind);
0767 return Attrs.addAttributeAtIndex(C, ArgNo,
0768 Attr.getWithNewType(C, ReplacementTy));
0769 }
0770
0771
0772
0773 [[nodiscard]] AttributeList addDereferenceableRetAttr(LLVMContext &C,
0774 uint64_t Bytes) const;
0775
0776
0777
0778 [[nodiscard]] AttributeList addDereferenceableParamAttr(LLVMContext &C,
0779 unsigned ArgNo,
0780 uint64_t Bytes) const;
0781
0782
0783
0784
0785 [[nodiscard]] AttributeList
0786 addDereferenceableOrNullParamAttr(LLVMContext &C, unsigned ArgNo,
0787 uint64_t Bytes) const;
0788
0789
0790
0791 [[nodiscard]] AttributeList addRangeRetAttr(LLVMContext &C,
0792 const ConstantRange &CR) const;
0793
0794
0795
0796 [[nodiscard]] AttributeList
0797 addAllocSizeParamAttr(LLVMContext &C, unsigned ArgNo, unsigned ElemSizeArg,
0798 const std::optional<unsigned> &NumElemsArg) const;
0799
0800
0801
0802
0803 [[nodiscard]] std::optional<AttributeList>
0804 intersectWith(LLVMContext &C, AttributeList Other) const;
0805
0806
0807
0808
0809
0810
0811 AttributeSet getAttributes(unsigned Index) const;
0812
0813
0814
0815 AttributeSet getParamAttrs(unsigned ArgNo) const;
0816
0817
0818 AttributeSet getRetAttrs() const;
0819
0820
0821 AttributeSet getFnAttrs() const;
0822
0823
0824 bool hasAttributeAtIndex(unsigned Index, Attribute::AttrKind Kind) const;
0825
0826
0827 bool hasAttributeAtIndex(unsigned Index, StringRef Kind) const;
0828
0829
0830 bool hasAttributesAtIndex(unsigned Index) const;
0831
0832
0833 bool hasParamAttr(unsigned ArgNo, Attribute::AttrKind Kind) const {
0834 return hasAttributeAtIndex(ArgNo + FirstArgIndex, Kind);
0835 }
0836
0837
0838 bool hasParamAttr(unsigned ArgNo, StringRef Kind) const {
0839 return hasAttributeAtIndex(ArgNo + FirstArgIndex, Kind);
0840 }
0841
0842
0843 bool hasParamAttrs(unsigned ArgNo) const {
0844 return hasAttributesAtIndex(ArgNo + FirstArgIndex);
0845 }
0846
0847
0848 bool hasRetAttr(Attribute::AttrKind Kind) const {
0849 return hasAttributeAtIndex(ReturnIndex, Kind);
0850 }
0851
0852
0853 bool hasRetAttr(StringRef Kind) const {
0854 return hasAttributeAtIndex(ReturnIndex, Kind);
0855 }
0856
0857
0858 bool hasRetAttrs() const { return hasAttributesAtIndex(ReturnIndex); }
0859
0860
0861 bool hasFnAttr(Attribute::AttrKind Kind) const;
0862
0863
0864 bool hasFnAttr(StringRef Kind) const;
0865
0866
0867 bool hasFnAttrs() const { return hasAttributesAtIndex(FunctionIndex); }
0868
0869
0870
0871
0872 bool hasAttrSomewhere(Attribute::AttrKind Kind,
0873 unsigned *Index = nullptr) const;
0874
0875
0876 Attribute getAttributeAtIndex(unsigned Index, Attribute::AttrKind Kind) const;
0877
0878
0879 Attribute getAttributeAtIndex(unsigned Index, StringRef Kind) const;
0880
0881
0882 Attribute getParamAttr(unsigned ArgNo, Attribute::AttrKind Kind) const {
0883 return getAttributeAtIndex(ArgNo + FirstArgIndex, Kind);
0884 }
0885
0886
0887 Attribute getParamAttr(unsigned ArgNo, StringRef Kind) const {
0888 return getAttributeAtIndex(ArgNo + FirstArgIndex, Kind);
0889 }
0890
0891
0892 Attribute getFnAttr(Attribute::AttrKind Kind) const {
0893 return getAttributeAtIndex(FunctionIndex, Kind);
0894 }
0895
0896
0897 Attribute getFnAttr(StringRef Kind) const {
0898 return getAttributeAtIndex(FunctionIndex, Kind);
0899 }
0900
0901
0902 Attribute getRetAttr(Attribute::AttrKind Kind) const {
0903 return getAttributeAtIndex(ReturnIndex, Kind);
0904 }
0905
0906
0907 MaybeAlign getRetAlignment() const;
0908
0909
0910 MaybeAlign getParamAlignment(unsigned ArgNo) const;
0911
0912
0913 MaybeAlign getParamStackAlignment(unsigned ArgNo) const;
0914
0915
0916 Type *getParamByValType(unsigned ArgNo) const;
0917
0918
0919 Type *getParamStructRetType(unsigned ArgNo) const;
0920
0921
0922 Type *getParamByRefType(unsigned ArgNo) const;
0923
0924
0925 Type *getParamPreallocatedType(unsigned ArgNo) const;
0926
0927
0928 Type *getParamInAllocaType(unsigned ArgNo) const;
0929
0930
0931 Type *getParamElementType(unsigned ArgNo) const;
0932
0933
0934 MaybeAlign getFnStackAlignment() const;
0935
0936
0937 MaybeAlign getRetStackAlignment() const;
0938
0939
0940
0941 uint64_t getRetDereferenceableBytes() const;
0942
0943
0944 uint64_t getParamDereferenceableBytes(unsigned Index) const;
0945
0946
0947
0948 uint64_t getRetDereferenceableOrNullBytes() const;
0949
0950
0951
0952 uint64_t getParamDereferenceableOrNullBytes(unsigned ArgNo) const;
0953
0954
0955 std::optional<ConstantRange> getParamRange(unsigned ArgNo) const;
0956
0957
0958 FPClassTest getRetNoFPClass() const;
0959
0960
0961 FPClassTest getParamNoFPClass(unsigned ArgNo) const;
0962
0963
0964 UWTableKind getUWTableKind() const;
0965
0966 AllocFnKind getAllocKind() const;
0967
0968
0969 MemoryEffects getMemoryEffects() const;
0970
0971
0972 std::string getAsString(unsigned Index, bool InAttrGrp = false) const;
0973
0974
0975 bool hasParentContext(LLVMContext &C) const;
0976
0977
0978
0979
0980
0981 using iterator = const AttributeSet *;
0982
0983 iterator begin() const;
0984 iterator end() const;
0985
0986 unsigned getNumAttrSets() const;
0987
0988
0989
0990
0991 struct index_iterator {
0992 unsigned NumAttrSets;
0993 index_iterator(int NumAttrSets) : NumAttrSets(NumAttrSets) {}
0994 struct int_wrapper {
0995 int_wrapper(unsigned i) : i(i) {}
0996 unsigned i;
0997 unsigned operator*() { return i; }
0998 bool operator!=(const int_wrapper &Other) { return i != Other.i; }
0999 int_wrapper &operator++() {
1000
1001
1002 ++i;
1003 return *this;
1004 }
1005 };
1006
1007 int_wrapper begin() { return int_wrapper(AttributeList::FunctionIndex); }
1008
1009 int_wrapper end() { return int_wrapper(NumAttrSets - 1); }
1010 };
1011
1012
1013 index_iterator indexes() const { return index_iterator(getNumAttrSets()); }
1014
1015
1016 bool operator==(const AttributeList &RHS) const { return pImpl == RHS.pImpl; }
1017 bool operator!=(const AttributeList &RHS) const { return pImpl != RHS.pImpl; }
1018
1019
1020 void *getRawPointer() const {
1021 return pImpl;
1022 }
1023
1024
1025 bool isEmpty() const { return pImpl == nullptr; }
1026
1027 void print(raw_ostream &O) const;
1028
1029 void dump() const;
1030 };
1031
1032
1033
1034
1035 template <> struct DenseMapInfo<AttributeList, void> {
1036 static AttributeList getEmptyKey() {
1037 auto Val = static_cast<uintptr_t>(-1);
1038 Val <<= PointerLikeTypeTraits<void*>::NumLowBitsAvailable;
1039 return AttributeList(reinterpret_cast<AttributeListImpl *>(Val));
1040 }
1041
1042 static AttributeList getTombstoneKey() {
1043 auto Val = static_cast<uintptr_t>(-2);
1044 Val <<= PointerLikeTypeTraits<void*>::NumLowBitsAvailable;
1045 return AttributeList(reinterpret_cast<AttributeListImpl *>(Val));
1046 }
1047
1048 static unsigned getHashValue(AttributeList AS) {
1049 return (unsigned((uintptr_t)AS.pImpl) >> 4) ^
1050 (unsigned((uintptr_t)AS.pImpl) >> 9);
1051 }
1052
1053 static bool isEqual(AttributeList LHS, AttributeList RHS) {
1054 return LHS == RHS;
1055 }
1056 };
1057
1058
1059
1060
1061
1062
1063
1064 class AttrBuilder {
1065 LLVMContext &Ctx;
1066 SmallVector<Attribute, 8> Attrs;
1067
1068 public:
1069 AttrBuilder(LLVMContext &Ctx) : Ctx(Ctx) {}
1070 AttrBuilder(const AttrBuilder &) = delete;
1071 AttrBuilder(AttrBuilder &&) = default;
1072
1073 AttrBuilder(LLVMContext &Ctx, const Attribute &A) : Ctx(Ctx) {
1074 addAttribute(A);
1075 }
1076
1077 AttrBuilder(LLVMContext &Ctx, AttributeSet AS);
1078
1079 void clear();
1080
1081
1082 AttrBuilder &addAttribute(Attribute::AttrKind Val);
1083
1084
1085 AttrBuilder &addAttribute(Attribute A);
1086
1087
1088 AttrBuilder &addAttribute(StringRef A, StringRef V = StringRef());
1089
1090
1091 AttrBuilder &removeAttribute(Attribute::AttrKind Val);
1092
1093
1094 AttrBuilder &removeAttribute(StringRef A);
1095
1096
1097 AttrBuilder &removeAttribute(Attribute A) {
1098 if (A.isStringAttribute())
1099 return removeAttribute(A.getKindAsString());
1100 else
1101 return removeAttribute(A.getKindAsEnum());
1102 }
1103
1104
1105
1106 AttrBuilder &merge(const AttrBuilder &B);
1107
1108
1109 AttrBuilder &remove(const AttributeMask &AM);
1110
1111
1112
1113 bool overlaps(const AttributeMask &AM) const;
1114
1115
1116 bool contains(Attribute::AttrKind A) const;
1117
1118
1119
1120 bool contains(StringRef A) const;
1121
1122
1123 bool hasAttributes() const { return !Attrs.empty(); }
1124
1125
1126
1127 Attribute getAttribute(Attribute::AttrKind Kind) const;
1128
1129
1130
1131 Attribute getAttribute(StringRef Kind) const;
1132
1133
1134
1135 std::optional<ConstantRange> getRange() const;
1136
1137
1138
1139 std::optional<uint64_t> getRawIntAttr(Attribute::AttrKind Kind) const;
1140
1141
1142 MaybeAlign getAlignment() const {
1143 return MaybeAlign(getRawIntAttr(Attribute::Alignment).value_or(0));
1144 }
1145
1146
1147 MaybeAlign getStackAlignment() const {
1148 return MaybeAlign(getRawIntAttr(Attribute::StackAlignment).value_or(0));
1149 }
1150
1151
1152
1153 uint64_t getDereferenceableBytes() const {
1154 return getRawIntAttr(Attribute::Dereferenceable).value_or(0);
1155 }
1156
1157
1158
1159 uint64_t getDereferenceableOrNullBytes() const {
1160 return getRawIntAttr(Attribute::DereferenceableOrNull).value_or(0);
1161 }
1162
1163
1164 Type *getTypeAttr(Attribute::AttrKind Kind) const;
1165
1166
1167 Type *getByValType() const { return getTypeAttr(Attribute::ByVal); }
1168
1169
1170 Type *getStructRetType() const { return getTypeAttr(Attribute::StructRet); }
1171
1172
1173 Type *getByRefType() const { return getTypeAttr(Attribute::ByRef); }
1174
1175
1176 Type *getPreallocatedType() const {
1177 return getTypeAttr(Attribute::Preallocated);
1178 }
1179
1180
1181 Type *getInAllocaType() const { return getTypeAttr(Attribute::InAlloca); }
1182
1183
1184
1185 std::optional<std::pair<unsigned, std::optional<unsigned>>> getAllocSizeArgs()
1186 const;
1187
1188
1189 AttrBuilder &addRawIntAttr(Attribute::AttrKind Kind, uint64_t Value);
1190
1191
1192
1193 AttrBuilder &addAlignmentAttr(MaybeAlign Align);
1194
1195
1196
1197
1198
1199 inline AttrBuilder &addAlignmentAttr(unsigned Align) {
1200 return addAlignmentAttr(MaybeAlign(Align));
1201 }
1202
1203
1204
1205 AttrBuilder &addStackAlignmentAttr(MaybeAlign Align);
1206
1207
1208
1209
1210
1211 inline AttrBuilder &addStackAlignmentAttr(unsigned Align) {
1212 return addStackAlignmentAttr(MaybeAlign(Align));
1213 }
1214
1215
1216
1217 AttrBuilder &addDereferenceableAttr(uint64_t Bytes);
1218
1219
1220
1221 AttrBuilder &addDereferenceableOrNullAttr(uint64_t Bytes);
1222
1223
1224 AttrBuilder &addAllocSizeAttr(unsigned ElemSizeArg,
1225 const std::optional<unsigned> &NumElemsArg);
1226
1227
1228 AttrBuilder &addVScaleRangeAttr(unsigned MinValue,
1229 std::optional<unsigned> MaxValue);
1230
1231
1232 AttrBuilder &addTypeAttr(Attribute::AttrKind Kind, Type *Ty);
1233
1234
1235 AttrBuilder &addByValAttr(Type *Ty);
1236
1237
1238 AttrBuilder &addStructRetAttr(Type *Ty);
1239
1240
1241 AttrBuilder &addByRefAttr(Type *Ty);
1242
1243
1244 AttrBuilder &addPreallocatedAttr(Type *Ty);
1245
1246
1247 AttrBuilder &addInAllocaAttr(Type *Ty);
1248
1249
1250
1251 AttrBuilder &addAllocSizeAttrFromRawRepr(uint64_t RawAllocSizeRepr);
1252
1253
1254
1255 AttrBuilder &addVScaleRangeAttrFromRawRepr(uint64_t RawVScaleRangeRepr);
1256
1257
1258
1259 AttrBuilder &addUWTableAttr(UWTableKind Kind);
1260
1261
1262 AttrBuilder &addAllocKindAttr(AllocFnKind Kind);
1263
1264
1265 AttrBuilder &addMemoryAttr(MemoryEffects ME);
1266
1267
1268 AttrBuilder &addCapturesAttr(CaptureInfo CI);
1269
1270
1271 AttrBuilder &addNoFPClassAttr(FPClassTest NoFPClassMask);
1272
1273
1274 AttrBuilder &addConstantRangeAttr(Attribute::AttrKind Kind,
1275 const ConstantRange &CR);
1276
1277
1278 AttrBuilder &addRangeAttr(const ConstantRange &CR);
1279
1280
1281 AttrBuilder &addConstantRangeListAttr(Attribute::AttrKind Kind,
1282 ArrayRef<ConstantRange> Val);
1283
1284
1285 AttrBuilder &addInitializesAttr(const ConstantRangeList &CRL);
1286
1287 ArrayRef<Attribute> attrs() const { return Attrs; }
1288
1289 bool operator==(const AttrBuilder &B) const;
1290 bool operator!=(const AttrBuilder &B) const { return !(*this == B); }
1291 };
1292
1293 namespace AttributeFuncs {
1294
1295 enum AttributeSafetyKind : uint8_t {
1296 ASK_SAFE_TO_DROP = 1,
1297 ASK_UNSAFE_TO_DROP = 2,
1298 ASK_ALL = ASK_SAFE_TO_DROP | ASK_UNSAFE_TO_DROP,
1299 };
1300
1301
1302
1303 bool isNoFPClassCompatibleType(Type *Ty);
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314 AttributeMask typeIncompatible(Type *Ty, AttributeSet AS,
1315 AttributeSafetyKind ASK = ASK_ALL);
1316
1317
1318
1319
1320
1321
1322 AttributeMask getUBImplyingAttributes();
1323
1324
1325
1326 bool areInlineCompatible(const Function &Caller, const Function &Callee);
1327
1328
1329
1330
1331
1332
1333
1334
1335 bool areOutlineCompatible(const Function &A, const Function &B);
1336
1337
1338 void mergeAttributesForInlining(Function &Caller, const Function &Callee);
1339
1340
1341
1342
1343
1344 void mergeAttributesForOutlining(Function &Base, const Function &ToMerge);
1345
1346
1347 void updateMinLegalVectorWidthAttr(Function &Fn, uint64_t Width);
1348
1349 }
1350
1351 }
1352
1353 #endif