File indexing completed on 2026-05-10 08:44:32
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef LLVM_SUPPORT_MODREF_H
0015 #define LLVM_SUPPORT_MODREF_H
0016
0017 #include "llvm/ADT/BitmaskEnum.h"
0018 #include "llvm/ADT/Sequence.h"
0019 #include "llvm/Support/raw_ostream.h"
0020
0021 namespace llvm {
0022
0023
0024
0025
0026
0027 enum class ModRefInfo : uint8_t {
0028
0029 NoModRef = 0,
0030
0031 Ref = 1,
0032
0033 Mod = 2,
0034
0035 ModRef = Ref | Mod,
0036 LLVM_MARK_AS_BITMASK_ENUM(ModRef),
0037 };
0038
0039 [[nodiscard]] inline bool isNoModRef(const ModRefInfo MRI) {
0040 return MRI == ModRefInfo::NoModRef;
0041 }
0042 [[nodiscard]] inline bool isModOrRefSet(const ModRefInfo MRI) {
0043 return MRI != ModRefInfo::NoModRef;
0044 }
0045 [[nodiscard]] inline bool isModAndRefSet(const ModRefInfo MRI) {
0046 return MRI == ModRefInfo::ModRef;
0047 }
0048 [[nodiscard]] inline bool isModSet(const ModRefInfo MRI) {
0049 return static_cast<int>(MRI) & static_cast<int>(ModRefInfo::Mod);
0050 }
0051 [[nodiscard]] inline bool isRefSet(const ModRefInfo MRI) {
0052 return static_cast<int>(MRI) & static_cast<int>(ModRefInfo::Ref);
0053 }
0054
0055
0056 raw_ostream &operator<<(raw_ostream &OS, ModRefInfo MR);
0057
0058
0059 enum class IRMemLocation {
0060
0061 ArgMem = 0,
0062
0063 InaccessibleMem = 1,
0064
0065 Other = 2,
0066
0067
0068 First = ArgMem,
0069 Last = Other,
0070 };
0071
0072 template <typename LocationEnum> class MemoryEffectsBase {
0073 public:
0074 using Location = LocationEnum;
0075
0076 private:
0077 uint32_t Data = 0;
0078
0079 static constexpr uint32_t BitsPerLoc = 2;
0080 static constexpr uint32_t LocMask = (1 << BitsPerLoc) - 1;
0081
0082 static uint32_t getLocationPos(Location Loc) {
0083 return (uint32_t)Loc * BitsPerLoc;
0084 }
0085
0086 MemoryEffectsBase(uint32_t Data) : Data(Data) {}
0087
0088 void setModRef(Location Loc, ModRefInfo MR) {
0089 Data &= ~(LocMask << getLocationPos(Loc));
0090 Data |= static_cast<uint32_t>(MR) << getLocationPos(Loc);
0091 }
0092
0093 public:
0094
0095 static auto locations() {
0096 return enum_seq_inclusive(Location::First, Location::Last,
0097 force_iteration_on_noniterable_enum);
0098 }
0099
0100
0101
0102 MemoryEffectsBase(Location Loc, ModRefInfo MR) { setModRef(Loc, MR); }
0103
0104
0105
0106 explicit MemoryEffectsBase(ModRefInfo MR) {
0107 for (Location Loc : locations())
0108 setModRef(Loc, MR);
0109 }
0110
0111
0112 static MemoryEffectsBase unknown() {
0113 return MemoryEffectsBase(ModRefInfo::ModRef);
0114 }
0115
0116
0117 static MemoryEffectsBase none() {
0118 return MemoryEffectsBase(ModRefInfo::NoModRef);
0119 }
0120
0121
0122 static MemoryEffectsBase readOnly() {
0123 return MemoryEffectsBase(ModRefInfo::Ref);
0124 }
0125
0126
0127 static MemoryEffectsBase writeOnly() {
0128 return MemoryEffectsBase(ModRefInfo::Mod);
0129 }
0130
0131
0132 static MemoryEffectsBase argMemOnly(ModRefInfo MR = ModRefInfo::ModRef) {
0133 return MemoryEffectsBase(Location::ArgMem, MR);
0134 }
0135
0136
0137 static MemoryEffectsBase
0138 inaccessibleMemOnly(ModRefInfo MR = ModRefInfo::ModRef) {
0139 return MemoryEffectsBase(Location::InaccessibleMem, MR);
0140 }
0141
0142
0143
0144 static MemoryEffectsBase
0145 inaccessibleOrArgMemOnly(ModRefInfo MR = ModRefInfo::ModRef) {
0146 MemoryEffectsBase FRMB = none();
0147 FRMB.setModRef(Location::ArgMem, MR);
0148 FRMB.setModRef(Location::InaccessibleMem, MR);
0149 return FRMB;
0150 }
0151
0152
0153
0154 static MemoryEffectsBase createFromIntValue(uint32_t Data) {
0155 return MemoryEffectsBase(Data);
0156 }
0157
0158
0159
0160 uint32_t toIntValue() const {
0161 return Data;
0162 }
0163
0164
0165 ModRefInfo getModRef(Location Loc) const {
0166 return ModRefInfo((Data >> getLocationPos(Loc)) & LocMask);
0167 }
0168
0169
0170 MemoryEffectsBase getWithModRef(Location Loc, ModRefInfo MR) const {
0171 MemoryEffectsBase ME = *this;
0172 ME.setModRef(Loc, MR);
0173 return ME;
0174 }
0175
0176
0177 MemoryEffectsBase getWithoutLoc(Location Loc) const {
0178 MemoryEffectsBase ME = *this;
0179 ME.setModRef(Loc, ModRefInfo::NoModRef);
0180 return ME;
0181 }
0182
0183
0184 ModRefInfo getModRef() const {
0185 ModRefInfo MR = ModRefInfo::NoModRef;
0186 for (Location Loc : locations())
0187 MR |= getModRef(Loc);
0188 return MR;
0189 }
0190
0191
0192 bool doesNotAccessMemory() const { return Data == 0; }
0193
0194
0195 bool onlyReadsMemory() const { return !isModSet(getModRef()); }
0196
0197
0198 bool onlyWritesMemory() const { return !isRefSet(getModRef()); }
0199
0200
0201 bool onlyAccessesArgPointees() const {
0202 return getWithoutLoc(Location::ArgMem).doesNotAccessMemory();
0203 }
0204
0205
0206 bool doesAccessArgPointees() const {
0207 return isModOrRefSet(getModRef(Location::ArgMem));
0208 }
0209
0210
0211 bool onlyAccessesInaccessibleMem() const {
0212 return getWithoutLoc(Location::InaccessibleMem).doesNotAccessMemory();
0213 }
0214
0215
0216
0217 bool onlyAccessesInaccessibleOrArgMem() const {
0218 return getWithoutLoc(Location::InaccessibleMem)
0219 .getWithoutLoc(Location::ArgMem)
0220 .doesNotAccessMemory();
0221 }
0222
0223
0224 MemoryEffectsBase operator&(MemoryEffectsBase Other) const {
0225 return MemoryEffectsBase(Data & Other.Data);
0226 }
0227
0228
0229 MemoryEffectsBase &operator&=(MemoryEffectsBase Other) {
0230 Data &= Other.Data;
0231 return *this;
0232 }
0233
0234
0235 MemoryEffectsBase operator|(MemoryEffectsBase Other) const {
0236 return MemoryEffectsBase(Data | Other.Data);
0237 }
0238
0239
0240 MemoryEffectsBase &operator|=(MemoryEffectsBase Other) {
0241 Data |= Other.Data;
0242 return *this;
0243 }
0244
0245
0246 MemoryEffectsBase operator-(MemoryEffectsBase Other) const {
0247 return MemoryEffectsBase(Data & ~Other.Data);
0248 }
0249
0250
0251 MemoryEffectsBase &operator-=(MemoryEffectsBase Other) {
0252 Data &= ~Other.Data;
0253 return *this;
0254 }
0255
0256
0257 bool operator==(MemoryEffectsBase Other) const { return Data == Other.Data; }
0258
0259
0260 bool operator!=(MemoryEffectsBase Other) const { return !operator==(Other); }
0261 };
0262
0263
0264
0265
0266
0267
0268 using MemoryEffects = MemoryEffectsBase<IRMemLocation>;
0269
0270
0271 raw_ostream &operator<<(raw_ostream &OS, MemoryEffects RMRB);
0272
0273
0274 using FunctionModRefBehavior = MemoryEffects;
0275
0276
0277 enum class CaptureComponents : uint8_t {
0278 None = 0,
0279 AddressIsNull = (1 << 0),
0280 Address = (1 << 1) | AddressIsNull,
0281 ReadProvenance = (1 << 2),
0282 Provenance = (1 << 3) | ReadProvenance,
0283 All = Address | Provenance,
0284 LLVM_MARK_AS_BITMASK_ENUM(Provenance),
0285 };
0286
0287 inline bool capturesNothing(CaptureComponents CC) {
0288 return CC == CaptureComponents::None;
0289 }
0290
0291 inline bool capturesAnything(CaptureComponents CC) {
0292 return CC != CaptureComponents::None;
0293 }
0294
0295 inline bool capturesAddressIsNullOnly(CaptureComponents CC) {
0296 return (CC & CaptureComponents::Address) == CaptureComponents::AddressIsNull;
0297 }
0298
0299 inline bool capturesAddress(CaptureComponents CC) {
0300 return (CC & CaptureComponents::Address) != CaptureComponents::None;
0301 }
0302
0303 inline bool capturesReadProvenanceOnly(CaptureComponents CC) {
0304 return (CC & CaptureComponents::Provenance) ==
0305 CaptureComponents::ReadProvenance;
0306 }
0307
0308 inline bool capturesFullProvenance(CaptureComponents CC) {
0309 return (CC & CaptureComponents::Provenance) == CaptureComponents::Provenance;
0310 }
0311
0312 raw_ostream &operator<<(raw_ostream &OS, CaptureComponents CC);
0313
0314
0315
0316
0317
0318 class CaptureInfo {
0319 CaptureComponents OtherComponents;
0320 CaptureComponents RetComponents;
0321
0322 public:
0323 CaptureInfo(CaptureComponents OtherComponents,
0324 CaptureComponents RetComponents)
0325 : OtherComponents(OtherComponents), RetComponents(RetComponents) {}
0326
0327 CaptureInfo(CaptureComponents Components)
0328 : OtherComponents(Components), RetComponents(Components) {}
0329
0330
0331 static CaptureInfo all() { return CaptureInfo(CaptureComponents::All); }
0332
0333
0334 CaptureComponents getRetComponents() const { return RetComponents; }
0335
0336
0337
0338 CaptureComponents getOtherComponents() const { return OtherComponents; }
0339
0340
0341
0342 operator CaptureComponents() const { return OtherComponents | RetComponents; }
0343
0344 bool operator==(CaptureInfo Other) const {
0345 return OtherComponents == Other.OtherComponents &&
0346 RetComponents == Other.RetComponents;
0347 }
0348
0349 bool operator!=(CaptureInfo Other) const { return !(*this == Other); }
0350
0351
0352 CaptureInfo operator|(CaptureInfo Other) const {
0353 return CaptureInfo(OtherComponents | Other.OtherComponents,
0354 RetComponents | Other.RetComponents);
0355 }
0356
0357
0358 CaptureInfo operator&(CaptureInfo Other) const {
0359 return CaptureInfo(OtherComponents & Other.OtherComponents,
0360 RetComponents & Other.RetComponents);
0361 }
0362
0363 static CaptureInfo createFromIntValue(uint32_t Data) {
0364 return CaptureInfo(CaptureComponents(Data >> 4),
0365 CaptureComponents(Data & 0xf));
0366 }
0367
0368
0369
0370 uint32_t toIntValue() const {
0371 return (uint32_t(OtherComponents) << 4) | uint32_t(RetComponents);
0372 }
0373 };
0374
0375 raw_ostream &operator<<(raw_ostream &OS, CaptureInfo Info);
0376
0377 }
0378
0379 #endif