File indexing completed on 2026-05-10 08:44:10
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef LLVM_IR_VALUEHANDLE_H
0014 #define LLVM_IR_VALUEHANDLE_H
0015
0016 #include "llvm/ADT/DenseMapInfo.h"
0017 #include "llvm/ADT/PointerIntPair.h"
0018 #include "llvm/IR/Value.h"
0019 #include "llvm/Support/Casting.h"
0020 #include <cassert>
0021
0022 namespace llvm {
0023
0024
0025
0026
0027
0028
0029 class ValueHandleBase {
0030 friend class Value;
0031
0032 protected:
0033
0034
0035
0036
0037 enum HandleBaseKind { Assert, Callback, Weak, WeakTracking };
0038
0039 ValueHandleBase(const ValueHandleBase &RHS)
0040 : ValueHandleBase(RHS.PrevPair.getInt(), RHS) {}
0041
0042 ValueHandleBase(HandleBaseKind Kind, const ValueHandleBase &RHS)
0043 : PrevPair(nullptr, Kind), Val(RHS.getValPtr()) {
0044 if (isValid(getValPtr()))
0045 AddToExistingUseList(RHS.getPrevPtr());
0046 }
0047
0048 private:
0049 PointerIntPair<ValueHandleBase**, 2, HandleBaseKind> PrevPair;
0050 ValueHandleBase *Next = nullptr;
0051 Value *Val = nullptr;
0052
0053 void setValPtr(Value *V) { Val = V; }
0054
0055 public:
0056 explicit ValueHandleBase(HandleBaseKind Kind)
0057 : PrevPair(nullptr, Kind) {}
0058 ValueHandleBase(HandleBaseKind Kind, Value *V)
0059 : PrevPair(nullptr, Kind), Val(V) {
0060 if (isValid(getValPtr()))
0061 AddToUseList();
0062 }
0063
0064 ~ValueHandleBase() {
0065 if (isValid(getValPtr()))
0066 RemoveFromUseList();
0067 }
0068
0069 Value *operator=(Value *RHS) {
0070 if (getValPtr() == RHS)
0071 return RHS;
0072 if (isValid(getValPtr()))
0073 RemoveFromUseList();
0074 setValPtr(RHS);
0075 if (isValid(getValPtr()))
0076 AddToUseList();
0077 return RHS;
0078 }
0079
0080 Value *operator=(const ValueHandleBase &RHS) {
0081 if (getValPtr() == RHS.getValPtr())
0082 return RHS.getValPtr();
0083 if (isValid(getValPtr()))
0084 RemoveFromUseList();
0085 setValPtr(RHS.getValPtr());
0086 if (isValid(getValPtr()))
0087 AddToExistingUseList(RHS.getPrevPtr());
0088 return getValPtr();
0089 }
0090
0091 Value *operator->() const { return getValPtr(); }
0092 Value &operator*() const {
0093 Value *V = getValPtr();
0094 assert(V && "Dereferencing deleted ValueHandle");
0095 return *V;
0096 }
0097
0098 protected:
0099 Value *getValPtr() const { return Val; }
0100
0101 static bool isValid(Value *V) {
0102 return V &&
0103 V != DenseMapInfo<Value *>::getEmptyKey() &&
0104 V != DenseMapInfo<Value *>::getTombstoneKey();
0105 }
0106
0107
0108 void RemoveFromUseList();
0109
0110
0111
0112
0113
0114 void clearValPtr() { setValPtr(nullptr); }
0115
0116 public:
0117
0118 static void ValueIsDeleted(Value *V);
0119 static void ValueIsRAUWd(Value *Old, Value *New);
0120
0121 private:
0122
0123 ValueHandleBase **getPrevPtr() const { return PrevPair.getPointer(); }
0124 HandleBaseKind getKind() const { return PrevPair.getInt(); }
0125 void setPrevPtr(ValueHandleBase **Ptr) { PrevPair.setPointer(Ptr); }
0126
0127
0128
0129
0130
0131 void AddToExistingUseList(ValueHandleBase **List);
0132
0133
0134 void AddToExistingUseListAfter(ValueHandleBase *Node);
0135
0136
0137 void AddToUseList();
0138 };
0139
0140
0141
0142
0143
0144 class WeakVH : public ValueHandleBase {
0145 public:
0146 WeakVH() : ValueHandleBase(Weak) {}
0147 WeakVH(Value *P) : ValueHandleBase(Weak, P) {}
0148 WeakVH(const WeakVH &RHS)
0149 : ValueHandleBase(Weak, RHS) {}
0150
0151 WeakVH &operator=(const WeakVH &RHS) = default;
0152
0153 Value *operator=(Value *RHS) {
0154 return ValueHandleBase::operator=(RHS);
0155 }
0156 Value *operator=(const ValueHandleBase &RHS) {
0157 return ValueHandleBase::operator=(RHS);
0158 }
0159
0160 operator Value*() const {
0161 return getValPtr();
0162 }
0163 };
0164
0165
0166
0167 template <> struct simplify_type<WeakVH> {
0168 using SimpleType = Value *;
0169
0170 static SimpleType getSimplifiedValue(WeakVH &WVH) { return WVH; }
0171 };
0172 template <> struct simplify_type<const WeakVH> {
0173 using SimpleType = Value *;
0174
0175 static SimpleType getSimplifiedValue(const WeakVH &WVH) { return WVH; }
0176 };
0177
0178
0179 template <> struct DenseMapInfo<WeakVH> {
0180 static inline WeakVH getEmptyKey() {
0181 return WeakVH(DenseMapInfo<Value *>::getEmptyKey());
0182 }
0183
0184 static inline WeakVH getTombstoneKey() {
0185 return WeakVH(DenseMapInfo<Value *>::getTombstoneKey());
0186 }
0187
0188 static unsigned getHashValue(const WeakVH &Val) {
0189 return DenseMapInfo<Value *>::getHashValue(Val);
0190 }
0191
0192 static bool isEqual(const WeakVH &LHS, const WeakVH &RHS) {
0193 return DenseMapInfo<Value *>::isEqual(LHS, RHS);
0194 }
0195 };
0196
0197
0198
0199
0200
0201
0202
0203
0204 class WeakTrackingVH : public ValueHandleBase {
0205 public:
0206 WeakTrackingVH() : ValueHandleBase(WeakTracking) {}
0207 WeakTrackingVH(Value *P) : ValueHandleBase(WeakTracking, P) {}
0208 WeakTrackingVH(const WeakTrackingVH &RHS)
0209 : ValueHandleBase(WeakTracking, RHS) {}
0210
0211 WeakTrackingVH &operator=(const WeakTrackingVH &RHS) = default;
0212
0213 Value *operator=(Value *RHS) {
0214 return ValueHandleBase::operator=(RHS);
0215 }
0216 Value *operator=(const ValueHandleBase &RHS) {
0217 return ValueHandleBase::operator=(RHS);
0218 }
0219
0220 operator Value*() const {
0221 return getValPtr();
0222 }
0223
0224 bool pointsToAliveValue() const {
0225 return ValueHandleBase::isValid(getValPtr());
0226 }
0227 };
0228
0229
0230
0231 template <> struct simplify_type<WeakTrackingVH> {
0232 using SimpleType = Value *;
0233
0234 static SimpleType getSimplifiedValue(WeakTrackingVH &WVH) { return WVH; }
0235 };
0236 template <> struct simplify_type<const WeakTrackingVH> {
0237 using SimpleType = Value *;
0238
0239 static SimpleType getSimplifiedValue(const WeakTrackingVH &WVH) {
0240 return WVH;
0241 }
0242 };
0243
0244
0245
0246
0247
0248
0249
0250
0251
0252
0253
0254
0255
0256
0257
0258
0259 template <typename ValueTy>
0260 class AssertingVH
0261 #if LLVM_ENABLE_ABI_BREAKING_CHECKS
0262 : public ValueHandleBase
0263 #endif
0264 {
0265 friend struct DenseMapInfo<AssertingVH<ValueTy>>;
0266
0267 #if LLVM_ENABLE_ABI_BREAKING_CHECKS
0268 Value *getRawValPtr() const { return ValueHandleBase::getValPtr(); }
0269 void setRawValPtr(Value *P) { ValueHandleBase::operator=(P); }
0270 #else
0271 Value *ThePtr;
0272 Value *getRawValPtr() const { return ThePtr; }
0273 void setRawValPtr(Value *P) { ThePtr = P; }
0274 #endif
0275
0276 static Value *GetAsValue(Value *V) { return V; }
0277 static Value *GetAsValue(const Value *V) { return const_cast<Value*>(V); }
0278
0279 ValueTy *getValPtr() const { return static_cast<ValueTy *>(getRawValPtr()); }
0280 void setValPtr(ValueTy *P) { setRawValPtr(GetAsValue(P)); }
0281
0282 public:
0283 #if LLVM_ENABLE_ABI_BREAKING_CHECKS
0284 AssertingVH() : ValueHandleBase(Assert) {}
0285 AssertingVH(ValueTy *P) : ValueHandleBase(Assert, GetAsValue(P)) {}
0286 AssertingVH(const AssertingVH &RHS) : ValueHandleBase(Assert, RHS) {}
0287 #else
0288 AssertingVH() : ThePtr(nullptr) {}
0289 AssertingVH(ValueTy *P) : ThePtr(GetAsValue(P)) {}
0290 AssertingVH(const AssertingVH &) = default;
0291 #endif
0292
0293 operator ValueTy*() const {
0294 return getValPtr();
0295 }
0296
0297 ValueTy *operator=(ValueTy *RHS) {
0298 setValPtr(RHS);
0299 return getValPtr();
0300 }
0301 ValueTy *operator=(const AssertingVH<ValueTy> &RHS) {
0302 setValPtr(RHS.getValPtr());
0303 return getValPtr();
0304 }
0305
0306 ValueTy *operator->() const { return getValPtr(); }
0307 ValueTy &operator*() const { return *getValPtr(); }
0308 };
0309
0310
0311
0312 template<typename T>
0313 struct DenseMapInfo<AssertingVH<T>> : DenseMapInfo<T *> {};
0314
0315
0316
0317
0318
0319
0320
0321
0322
0323
0324
0325
0326
0327
0328
0329
0330
0331 template <typename ValueTy> class TrackingVH {
0332 WeakTrackingVH InnerHandle;
0333
0334 public:
0335 ValueTy *getValPtr() const {
0336 assert(InnerHandle.pointsToAliveValue() &&
0337 "TrackingVH must be non-null and valid on dereference!");
0338
0339
0340
0341
0342
0343 assert(isa<ValueTy>(InnerHandle) &&
0344 "Tracked Value was replaced by one with an invalid type!");
0345 return cast<ValueTy>(InnerHandle);
0346 }
0347
0348 void setValPtr(ValueTy *P) {
0349
0350
0351 InnerHandle = GetAsValue(P);
0352 }
0353
0354
0355
0356 static Value *GetAsValue(Value *V) { return V; }
0357 static Value *GetAsValue(const Value *V) { return const_cast<Value*>(V); }
0358
0359 public:
0360 TrackingVH() = default;
0361 TrackingVH(ValueTy *P) { setValPtr(P); }
0362
0363 operator ValueTy*() const {
0364 return getValPtr();
0365 }
0366
0367 ValueTy *operator=(ValueTy *RHS) {
0368 setValPtr(RHS);
0369 return getValPtr();
0370 }
0371
0372 ValueTy *operator->() const { return getValPtr(); }
0373 ValueTy &operator*() const { return *getValPtr(); }
0374 };
0375
0376
0377
0378
0379
0380
0381
0382
0383 class CallbackVH : public ValueHandleBase {
0384 virtual void anchor();
0385 protected:
0386 ~CallbackVH() = default;
0387 CallbackVH(const CallbackVH &) = default;
0388 CallbackVH &operator=(const CallbackVH &) = default;
0389
0390 void setValPtr(Value *P) {
0391 ValueHandleBase::operator=(P);
0392 }
0393
0394 public:
0395 CallbackVH() : ValueHandleBase(Callback) {}
0396 CallbackVH(Value *P) : ValueHandleBase(Callback, P) {}
0397 CallbackVH(const Value *P) : CallbackVH(const_cast<Value *>(P)) {}
0398
0399 operator Value*() const {
0400 return getValPtr();
0401 }
0402
0403
0404
0405
0406
0407
0408
0409
0410
0411
0412
0413
0414 virtual void deleted() { setValPtr(nullptr); }
0415
0416
0417
0418
0419
0420
0421
0422
0423 virtual void allUsesReplacedWith(Value *) {}
0424 };
0425
0426
0427
0428
0429
0430
0431
0432
0433
0434
0435
0436
0437
0438
0439
0440
0441
0442
0443
0444 template <typename ValueTy>
0445 class PoisoningVH final
0446 #if LLVM_ENABLE_ABI_BREAKING_CHECKS
0447 : public CallbackVH
0448 #endif
0449 {
0450 friend struct DenseMapInfo<PoisoningVH<ValueTy>>;
0451
0452
0453 static Value *GetAsValue(Value *V) { return V; }
0454 static Value *GetAsValue(const Value *V) { return const_cast<Value *>(V); }
0455
0456 #if LLVM_ENABLE_ABI_BREAKING_CHECKS
0457
0458
0459
0460
0461
0462
0463 bool Poisoned = false;
0464
0465 Value *getRawValPtr() const { return ValueHandleBase::getValPtr(); }
0466 void setRawValPtr(Value *P) { ValueHandleBase::operator=(P); }
0467
0468
0469 void deleted() override {
0470 assert(!Poisoned && "Tried to delete an already poisoned handle!");
0471 Poisoned = true;
0472 RemoveFromUseList();
0473 }
0474
0475
0476 void allUsesReplacedWith(Value *) override {
0477 assert(!Poisoned && "Tried to RAUW an already poisoned handle!");
0478 Poisoned = true;
0479 RemoveFromUseList();
0480 }
0481 #else
0482 Value *ThePtr = nullptr;
0483
0484 Value *getRawValPtr() const { return ThePtr; }
0485 void setRawValPtr(Value *P) { ThePtr = P; }
0486 #endif
0487
0488 ValueTy *getValPtr() const {
0489 #if LLVM_ENABLE_ABI_BREAKING_CHECKS
0490 assert(!Poisoned && "Accessed a poisoned value handle!");
0491 #endif
0492 return static_cast<ValueTy *>(getRawValPtr());
0493 }
0494 void setValPtr(ValueTy *P) { setRawValPtr(GetAsValue(P)); }
0495
0496 public:
0497 PoisoningVH() = default;
0498 #if LLVM_ENABLE_ABI_BREAKING_CHECKS
0499 PoisoningVH(ValueTy *P) : CallbackVH(GetAsValue(P)) {}
0500 PoisoningVH(const PoisoningVH &RHS)
0501 : CallbackVH(RHS), Poisoned(RHS.Poisoned) {}
0502
0503 ~PoisoningVH() {
0504 if (Poisoned)
0505 clearValPtr();
0506 }
0507
0508 PoisoningVH &operator=(const PoisoningVH &RHS) {
0509 if (Poisoned)
0510 clearValPtr();
0511 CallbackVH::operator=(RHS);
0512 Poisoned = RHS.Poisoned;
0513 return *this;
0514 }
0515 #else
0516 PoisoningVH(ValueTy *P) : ThePtr(GetAsValue(P)) {}
0517 #endif
0518
0519 operator ValueTy *() const { return getValPtr(); }
0520
0521 ValueTy *operator->() const { return getValPtr(); }
0522 ValueTy &operator*() const { return *getValPtr(); }
0523 };
0524
0525
0526 template <typename T> struct DenseMapInfo<PoisoningVH<T>> {
0527 static inline PoisoningVH<T> getEmptyKey() {
0528 PoisoningVH<T> Res;
0529 Res.setRawValPtr(DenseMapInfo<Value *>::getEmptyKey());
0530 return Res;
0531 }
0532
0533 static inline PoisoningVH<T> getTombstoneKey() {
0534 PoisoningVH<T> Res;
0535 Res.setRawValPtr(DenseMapInfo<Value *>::getTombstoneKey());
0536 return Res;
0537 }
0538
0539 static unsigned getHashValue(const PoisoningVH<T> &Val) {
0540 return DenseMapInfo<Value *>::getHashValue(Val.getRawValPtr());
0541 }
0542
0543 static bool isEqual(const PoisoningVH<T> &LHS, const PoisoningVH<T> &RHS) {
0544 return DenseMapInfo<Value *>::isEqual(LHS.getRawValPtr(),
0545 RHS.getRawValPtr());
0546 }
0547
0548
0549
0550
0551 static unsigned getHashValue(const T *Val) {
0552 return DenseMapInfo<Value *>::getHashValue(Val);
0553 }
0554
0555 static bool isEqual(const T *LHS, const PoisoningVH<T> &RHS) {
0556 return DenseMapInfo<Value *>::isEqual(LHS, RHS.getRawValPtr());
0557 }
0558 };
0559
0560 }
0561
0562 #endif