xref: /freebsd-src/contrib/llvm-project/llvm/include/llvm/IR/ValueHandle.h (revision e8d8bef961a50d4dc22501cde4fb9fb0be1b2532)
10b57cec5SDimitry Andric //===- ValueHandle.h - Value Smart Pointer classes --------------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file declares the ValueHandle class and its sub-classes.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #ifndef LLVM_IR_VALUEHANDLE_H
140b57cec5SDimitry Andric #define LLVM_IR_VALUEHANDLE_H
150b57cec5SDimitry Andric 
160b57cec5SDimitry Andric #include "llvm/ADT/DenseMapInfo.h"
170b57cec5SDimitry Andric #include "llvm/ADT/PointerIntPair.h"
180b57cec5SDimitry Andric #include "llvm/IR/Value.h"
190b57cec5SDimitry Andric #include "llvm/Support/Casting.h"
200b57cec5SDimitry Andric #include <cassert>
210b57cec5SDimitry Andric 
220b57cec5SDimitry Andric namespace llvm {
230b57cec5SDimitry Andric 
240b57cec5SDimitry Andric /// This is the common base class of value handles.
250b57cec5SDimitry Andric ///
260b57cec5SDimitry Andric /// ValueHandle's are smart pointers to Value's that have special behavior when
270b57cec5SDimitry Andric /// the value is deleted or ReplaceAllUsesWith'd.  See the specific handles
280b57cec5SDimitry Andric /// below for details.
290b57cec5SDimitry Andric class ValueHandleBase {
300b57cec5SDimitry Andric   friend class Value;
310b57cec5SDimitry Andric 
320b57cec5SDimitry Andric protected:
330b57cec5SDimitry Andric   /// This indicates what sub class the handle actually is.
340b57cec5SDimitry Andric   ///
350b57cec5SDimitry Andric   /// This is to avoid having a vtable for the light-weight handle pointers. The
360b57cec5SDimitry Andric   /// fully general Callback version does have a vtable.
370b57cec5SDimitry Andric   enum HandleBaseKind { Assert, Callback, Weak, WeakTracking };
380b57cec5SDimitry Andric 
ValueHandleBase(const ValueHandleBase & RHS)390b57cec5SDimitry Andric   ValueHandleBase(const ValueHandleBase &RHS)
400b57cec5SDimitry Andric       : ValueHandleBase(RHS.PrevPair.getInt(), RHS) {}
410b57cec5SDimitry Andric 
ValueHandleBase(HandleBaseKind Kind,const ValueHandleBase & RHS)420b57cec5SDimitry Andric   ValueHandleBase(HandleBaseKind Kind, const ValueHandleBase &RHS)
430b57cec5SDimitry Andric       : PrevPair(nullptr, Kind), Val(RHS.getValPtr()) {
440b57cec5SDimitry Andric     if (isValid(getValPtr()))
450b57cec5SDimitry Andric       AddToExistingUseList(RHS.getPrevPtr());
460b57cec5SDimitry Andric   }
470b57cec5SDimitry Andric 
480b57cec5SDimitry Andric private:
490b57cec5SDimitry Andric   PointerIntPair<ValueHandleBase**, 2, HandleBaseKind> PrevPair;
500b57cec5SDimitry Andric   ValueHandleBase *Next = nullptr;
510b57cec5SDimitry Andric   Value *Val = nullptr;
520b57cec5SDimitry Andric 
setValPtr(Value * V)530b57cec5SDimitry Andric   void setValPtr(Value *V) { Val = V; }
540b57cec5SDimitry Andric 
550b57cec5SDimitry Andric public:
ValueHandleBase(HandleBaseKind Kind)560b57cec5SDimitry Andric   explicit ValueHandleBase(HandleBaseKind Kind)
570b57cec5SDimitry Andric       : PrevPair(nullptr, Kind) {}
ValueHandleBase(HandleBaseKind Kind,Value * V)580b57cec5SDimitry Andric   ValueHandleBase(HandleBaseKind Kind, Value *V)
590b57cec5SDimitry Andric       : PrevPair(nullptr, Kind), Val(V) {
600b57cec5SDimitry Andric     if (isValid(getValPtr()))
610b57cec5SDimitry Andric       AddToUseList();
620b57cec5SDimitry Andric   }
630b57cec5SDimitry Andric 
~ValueHandleBase()640b57cec5SDimitry Andric   ~ValueHandleBase() {
650b57cec5SDimitry Andric     if (isValid(getValPtr()))
660b57cec5SDimitry Andric       RemoveFromUseList();
670b57cec5SDimitry Andric   }
680b57cec5SDimitry Andric 
690b57cec5SDimitry Andric   Value *operator=(Value *RHS) {
700b57cec5SDimitry Andric     if (getValPtr() == RHS)
710b57cec5SDimitry Andric       return RHS;
720b57cec5SDimitry Andric     if (isValid(getValPtr()))
730b57cec5SDimitry Andric       RemoveFromUseList();
740b57cec5SDimitry Andric     setValPtr(RHS);
750b57cec5SDimitry Andric     if (isValid(getValPtr()))
760b57cec5SDimitry Andric       AddToUseList();
770b57cec5SDimitry Andric     return RHS;
780b57cec5SDimitry Andric   }
790b57cec5SDimitry Andric 
800b57cec5SDimitry Andric   Value *operator=(const ValueHandleBase &RHS) {
810b57cec5SDimitry Andric     if (getValPtr() == RHS.getValPtr())
820b57cec5SDimitry Andric       return RHS.getValPtr();
830b57cec5SDimitry Andric     if (isValid(getValPtr()))
840b57cec5SDimitry Andric       RemoveFromUseList();
850b57cec5SDimitry Andric     setValPtr(RHS.getValPtr());
860b57cec5SDimitry Andric     if (isValid(getValPtr()))
870b57cec5SDimitry Andric       AddToExistingUseList(RHS.getPrevPtr());
880b57cec5SDimitry Andric     return getValPtr();
890b57cec5SDimitry Andric   }
900b57cec5SDimitry Andric 
910b57cec5SDimitry Andric   Value *operator->() const { return getValPtr(); }
925ffd83dbSDimitry Andric   Value &operator*() const {
935ffd83dbSDimitry Andric     Value *V = getValPtr();
945ffd83dbSDimitry Andric     assert(V && "Dereferencing deleted ValueHandle");
955ffd83dbSDimitry Andric     return *V;
965ffd83dbSDimitry Andric   }
970b57cec5SDimitry Andric 
980b57cec5SDimitry Andric protected:
getValPtr()990b57cec5SDimitry Andric   Value *getValPtr() const { return Val; }
1000b57cec5SDimitry Andric 
isValid(Value * V)1010b57cec5SDimitry Andric   static bool isValid(Value *V) {
1020b57cec5SDimitry Andric     return V &&
1030b57cec5SDimitry Andric            V != DenseMapInfo<Value *>::getEmptyKey() &&
1040b57cec5SDimitry Andric            V != DenseMapInfo<Value *>::getTombstoneKey();
1050b57cec5SDimitry Andric   }
1060b57cec5SDimitry Andric 
1070b57cec5SDimitry Andric   /// Remove this ValueHandle from its current use list.
1080b57cec5SDimitry Andric   void RemoveFromUseList();
1090b57cec5SDimitry Andric 
1100b57cec5SDimitry Andric   /// Clear the underlying pointer without clearing the use list.
1110b57cec5SDimitry Andric   ///
1120b57cec5SDimitry Andric   /// This should only be used if a derived class has manually removed the
1130b57cec5SDimitry Andric   /// handle from the use list.
clearValPtr()1140b57cec5SDimitry Andric   void clearValPtr() { setValPtr(nullptr); }
1150b57cec5SDimitry Andric 
1160b57cec5SDimitry Andric public:
1170b57cec5SDimitry Andric   // Callbacks made from Value.
1180b57cec5SDimitry Andric   static void ValueIsDeleted(Value *V);
1190b57cec5SDimitry Andric   static void ValueIsRAUWd(Value *Old, Value *New);
1200b57cec5SDimitry Andric 
1210b57cec5SDimitry Andric private:
1220b57cec5SDimitry Andric   // Internal implementation details.
getPrevPtr()1230b57cec5SDimitry Andric   ValueHandleBase **getPrevPtr() const { return PrevPair.getPointer(); }
getKind()1240b57cec5SDimitry Andric   HandleBaseKind getKind() const { return PrevPair.getInt(); }
setPrevPtr(ValueHandleBase ** Ptr)1250b57cec5SDimitry Andric   void setPrevPtr(ValueHandleBase **Ptr) { PrevPair.setPointer(Ptr); }
1260b57cec5SDimitry Andric 
1270b57cec5SDimitry Andric   /// Add this ValueHandle to the use list for V.
1280b57cec5SDimitry Andric   ///
1290b57cec5SDimitry Andric   /// List is the address of either the head of the list or a Next node within
1300b57cec5SDimitry Andric   /// the existing use list.
1310b57cec5SDimitry Andric   void AddToExistingUseList(ValueHandleBase **List);
1320b57cec5SDimitry Andric 
1330b57cec5SDimitry Andric   /// Add this ValueHandle to the use list after Node.
1340b57cec5SDimitry Andric   void AddToExistingUseListAfter(ValueHandleBase *Node);
1350b57cec5SDimitry Andric 
1360b57cec5SDimitry Andric   /// Add this ValueHandle to the use list for V.
1370b57cec5SDimitry Andric   void AddToUseList();
1380b57cec5SDimitry Andric };
1390b57cec5SDimitry Andric 
1400b57cec5SDimitry Andric /// A nullable Value handle that is nullable.
1410b57cec5SDimitry Andric ///
1420b57cec5SDimitry Andric /// This is a value handle that points to a value, and nulls itself
1430b57cec5SDimitry Andric /// out if that value is deleted.
1440b57cec5SDimitry Andric class WeakVH : public ValueHandleBase {
1450b57cec5SDimitry Andric public:
WeakVH()1460b57cec5SDimitry Andric   WeakVH() : ValueHandleBase(Weak) {}
WeakVH(Value * P)1470b57cec5SDimitry Andric   WeakVH(Value *P) : ValueHandleBase(Weak, P) {}
WeakVH(const WeakVH & RHS)1480b57cec5SDimitry Andric   WeakVH(const WeakVH &RHS)
1490b57cec5SDimitry Andric       : ValueHandleBase(Weak, RHS) {}
1500b57cec5SDimitry Andric 
1510b57cec5SDimitry Andric   WeakVH &operator=(const WeakVH &RHS) = default;
1520b57cec5SDimitry Andric 
1530b57cec5SDimitry Andric   Value *operator=(Value *RHS) {
1540b57cec5SDimitry Andric     return ValueHandleBase::operator=(RHS);
1550b57cec5SDimitry Andric   }
1560b57cec5SDimitry Andric   Value *operator=(const ValueHandleBase &RHS) {
1570b57cec5SDimitry Andric     return ValueHandleBase::operator=(RHS);
1580b57cec5SDimitry Andric   }
1590b57cec5SDimitry Andric 
1600b57cec5SDimitry Andric   operator Value*() const {
1610b57cec5SDimitry Andric     return getValPtr();
1620b57cec5SDimitry Andric   }
1630b57cec5SDimitry Andric };
1640b57cec5SDimitry Andric 
1650b57cec5SDimitry Andric // Specialize simplify_type to allow WeakVH to participate in
1660b57cec5SDimitry Andric // dyn_cast, isa, etc.
1670b57cec5SDimitry Andric template <> struct simplify_type<WeakVH> {
1680b57cec5SDimitry Andric   using SimpleType = Value *;
1690b57cec5SDimitry Andric 
1700b57cec5SDimitry Andric   static SimpleType getSimplifiedValue(WeakVH &WVH) { return WVH; }
1710b57cec5SDimitry Andric };
1720b57cec5SDimitry Andric template <> struct simplify_type<const WeakVH> {
1730b57cec5SDimitry Andric   using SimpleType = Value *;
1740b57cec5SDimitry Andric 
1750b57cec5SDimitry Andric   static SimpleType getSimplifiedValue(const WeakVH &WVH) { return WVH; }
1760b57cec5SDimitry Andric };
1770b57cec5SDimitry Andric 
178480093f4SDimitry Andric // Specialize DenseMapInfo to allow WeakVH to participate in DenseMap.
179480093f4SDimitry Andric template <> struct DenseMapInfo<WeakVH> {
180480093f4SDimitry Andric   static inline WeakVH getEmptyKey() {
181480093f4SDimitry Andric     return WeakVH(DenseMapInfo<Value *>::getEmptyKey());
182480093f4SDimitry Andric   }
183480093f4SDimitry Andric 
184480093f4SDimitry Andric   static inline WeakVH getTombstoneKey() {
185480093f4SDimitry Andric     return WeakVH(DenseMapInfo<Value *>::getTombstoneKey());
186480093f4SDimitry Andric   }
187480093f4SDimitry Andric 
188480093f4SDimitry Andric   static unsigned getHashValue(const WeakVH &Val) {
189480093f4SDimitry Andric     return DenseMapInfo<Value *>::getHashValue(Val);
190480093f4SDimitry Andric   }
191480093f4SDimitry Andric 
192480093f4SDimitry Andric   static bool isEqual(const WeakVH &LHS, const WeakVH &RHS) {
193480093f4SDimitry Andric     return DenseMapInfo<Value *>::isEqual(LHS, RHS);
194480093f4SDimitry Andric   }
195480093f4SDimitry Andric };
196480093f4SDimitry Andric 
1970b57cec5SDimitry Andric /// Value handle that is nullable, but tries to track the Value.
1980b57cec5SDimitry Andric ///
1990b57cec5SDimitry Andric /// This is a value handle that tries hard to point to a Value, even across
2000b57cec5SDimitry Andric /// RAUW operations, but will null itself out if the value is destroyed.  this
2010b57cec5SDimitry Andric /// is useful for advisory sorts of information, but should not be used as the
2020b57cec5SDimitry Andric /// key of a map (since the map would have to rearrange itself when the pointer
2030b57cec5SDimitry Andric /// changes).
2040b57cec5SDimitry Andric class WeakTrackingVH : public ValueHandleBase {
2050b57cec5SDimitry Andric public:
2060b57cec5SDimitry Andric   WeakTrackingVH() : ValueHandleBase(WeakTracking) {}
2070b57cec5SDimitry Andric   WeakTrackingVH(Value *P) : ValueHandleBase(WeakTracking, P) {}
2080b57cec5SDimitry Andric   WeakTrackingVH(const WeakTrackingVH &RHS)
2090b57cec5SDimitry Andric       : ValueHandleBase(WeakTracking, RHS) {}
2100b57cec5SDimitry Andric 
2110b57cec5SDimitry Andric   WeakTrackingVH &operator=(const WeakTrackingVH &RHS) = default;
2120b57cec5SDimitry Andric 
2130b57cec5SDimitry Andric   Value *operator=(Value *RHS) {
2140b57cec5SDimitry Andric     return ValueHandleBase::operator=(RHS);
2150b57cec5SDimitry Andric   }
2160b57cec5SDimitry Andric   Value *operator=(const ValueHandleBase &RHS) {
2170b57cec5SDimitry Andric     return ValueHandleBase::operator=(RHS);
2180b57cec5SDimitry Andric   }
2190b57cec5SDimitry Andric 
2200b57cec5SDimitry Andric   operator Value*() const {
2210b57cec5SDimitry Andric     return getValPtr();
2220b57cec5SDimitry Andric   }
2230b57cec5SDimitry Andric 
2240b57cec5SDimitry Andric   bool pointsToAliveValue() const {
2250b57cec5SDimitry Andric     return ValueHandleBase::isValid(getValPtr());
2260b57cec5SDimitry Andric   }
2270b57cec5SDimitry Andric };
2280b57cec5SDimitry Andric 
2290b57cec5SDimitry Andric // Specialize simplify_type to allow WeakTrackingVH to participate in
2300b57cec5SDimitry Andric // dyn_cast, isa, etc.
2310b57cec5SDimitry Andric template <> struct simplify_type<WeakTrackingVH> {
2320b57cec5SDimitry Andric   using SimpleType = Value *;
2330b57cec5SDimitry Andric 
2340b57cec5SDimitry Andric   static SimpleType getSimplifiedValue(WeakTrackingVH &WVH) { return WVH; }
2350b57cec5SDimitry Andric };
2360b57cec5SDimitry Andric template <> struct simplify_type<const WeakTrackingVH> {
2370b57cec5SDimitry Andric   using SimpleType = Value *;
2380b57cec5SDimitry Andric 
2390b57cec5SDimitry Andric   static SimpleType getSimplifiedValue(const WeakTrackingVH &WVH) {
2400b57cec5SDimitry Andric     return WVH;
2410b57cec5SDimitry Andric   }
2420b57cec5SDimitry Andric };
2430b57cec5SDimitry Andric 
2440b57cec5SDimitry Andric /// Value handle that asserts if the Value is deleted.
2450b57cec5SDimitry Andric ///
2460b57cec5SDimitry Andric /// This is a Value Handle that points to a value and asserts out if the value
2470b57cec5SDimitry Andric /// is destroyed while the handle is still live.  This is very useful for
2480b57cec5SDimitry Andric /// catching dangling pointer bugs and other things which can be non-obvious.
2490b57cec5SDimitry Andric /// One particularly useful place to use this is as the Key of a map.  Dangling
2500b57cec5SDimitry Andric /// pointer bugs often lead to really subtle bugs that only occur if another
2510b57cec5SDimitry Andric /// object happens to get allocated to the same address as the old one.  Using
2520b57cec5SDimitry Andric /// an AssertingVH ensures that an assert is triggered as soon as the bad
2530b57cec5SDimitry Andric /// delete occurs.
2540b57cec5SDimitry Andric ///
2550b57cec5SDimitry Andric /// Note that an AssertingVH handle does *not* follow values across RAUW
2560b57cec5SDimitry Andric /// operations.  This means that RAUW's need to explicitly update the
2570b57cec5SDimitry Andric /// AssertingVH's as it moves.  This is required because in non-assert mode this
2580b57cec5SDimitry Andric /// class turns into a trivial wrapper around a pointer.
2590b57cec5SDimitry Andric template <typename ValueTy>
2600b57cec5SDimitry Andric class AssertingVH
261*e8d8bef9SDimitry Andric #if LLVM_ENABLE_ABI_BREAKING_CHECKS
2620b57cec5SDimitry Andric     : public ValueHandleBase
2630b57cec5SDimitry Andric #endif
2640b57cec5SDimitry Andric {
2650b57cec5SDimitry Andric   friend struct DenseMapInfo<AssertingVH<ValueTy>>;
2660b57cec5SDimitry Andric 
267*e8d8bef9SDimitry Andric #if LLVM_ENABLE_ABI_BREAKING_CHECKS
2680b57cec5SDimitry Andric   Value *getRawValPtr() const { return ValueHandleBase::getValPtr(); }
2690b57cec5SDimitry Andric   void setRawValPtr(Value *P) { ValueHandleBase::operator=(P); }
2700b57cec5SDimitry Andric #else
2710b57cec5SDimitry Andric   Value *ThePtr;
2720b57cec5SDimitry Andric   Value *getRawValPtr() const { return ThePtr; }
2730b57cec5SDimitry Andric   void setRawValPtr(Value *P) { ThePtr = P; }
2740b57cec5SDimitry Andric #endif
2750b57cec5SDimitry Andric   // Convert a ValueTy*, which may be const, to the raw Value*.
2760b57cec5SDimitry Andric   static Value *GetAsValue(Value *V) { return V; }
2770b57cec5SDimitry Andric   static Value *GetAsValue(const Value *V) { return const_cast<Value*>(V); }
2780b57cec5SDimitry Andric 
2790b57cec5SDimitry Andric   ValueTy *getValPtr() const { return static_cast<ValueTy *>(getRawValPtr()); }
2800b57cec5SDimitry Andric   void setValPtr(ValueTy *P) { setRawValPtr(GetAsValue(P)); }
2810b57cec5SDimitry Andric 
2820b57cec5SDimitry Andric public:
283*e8d8bef9SDimitry Andric #if LLVM_ENABLE_ABI_BREAKING_CHECKS
2840b57cec5SDimitry Andric   AssertingVH() : ValueHandleBase(Assert) {}
2850b57cec5SDimitry Andric   AssertingVH(ValueTy *P) : ValueHandleBase(Assert, GetAsValue(P)) {}
2860b57cec5SDimitry Andric   AssertingVH(const AssertingVH &RHS) : ValueHandleBase(Assert, RHS) {}
2870b57cec5SDimitry Andric #else
2880b57cec5SDimitry Andric   AssertingVH() : ThePtr(nullptr) {}
2890b57cec5SDimitry Andric   AssertingVH(ValueTy *P) : ThePtr(GetAsValue(P)) {}
290*e8d8bef9SDimitry Andric   AssertingVH(const AssertingVH &) = default;
2910b57cec5SDimitry Andric #endif
2920b57cec5SDimitry Andric 
2930b57cec5SDimitry Andric   operator ValueTy*() const {
2940b57cec5SDimitry Andric     return getValPtr();
2950b57cec5SDimitry Andric   }
2960b57cec5SDimitry Andric 
2970b57cec5SDimitry Andric   ValueTy *operator=(ValueTy *RHS) {
2980b57cec5SDimitry Andric     setValPtr(RHS);
2990b57cec5SDimitry Andric     return getValPtr();
3000b57cec5SDimitry Andric   }
3010b57cec5SDimitry Andric   ValueTy *operator=(const AssertingVH<ValueTy> &RHS) {
3020b57cec5SDimitry Andric     setValPtr(RHS.getValPtr());
3030b57cec5SDimitry Andric     return getValPtr();
3040b57cec5SDimitry Andric   }
3050b57cec5SDimitry Andric 
3060b57cec5SDimitry Andric   ValueTy *operator->() const { return getValPtr(); }
3070b57cec5SDimitry Andric   ValueTy &operator*() const { return *getValPtr(); }
3080b57cec5SDimitry Andric };
3090b57cec5SDimitry Andric 
3105ffd83dbSDimitry Andric // Treat AssertingVH<T> like T* inside maps. This also allows using find_as()
3115ffd83dbSDimitry Andric // to look up a value without constructing a value handle.
3120b57cec5SDimitry Andric template<typename T>
3135ffd83dbSDimitry Andric struct DenseMapInfo<AssertingVH<T>> : DenseMapInfo<T *> {};
3140b57cec5SDimitry Andric 
3150b57cec5SDimitry Andric /// Value handle that tracks a Value across RAUW.
3160b57cec5SDimitry Andric ///
3170b57cec5SDimitry Andric /// TrackingVH is designed for situations where a client needs to hold a handle
3180b57cec5SDimitry Andric /// to a Value (or subclass) across some operations which may move that value,
3190b57cec5SDimitry Andric /// but should never destroy it or replace it with some unacceptable type.
3200b57cec5SDimitry Andric ///
3210b57cec5SDimitry Andric /// It is an error to attempt to replace a value with one of a type which is
3220b57cec5SDimitry Andric /// incompatible with any of its outstanding TrackingVHs.
3230b57cec5SDimitry Andric ///
3240b57cec5SDimitry Andric /// It is an error to read from a TrackingVH that does not point to a valid
3250b57cec5SDimitry Andric /// value.  A TrackingVH is said to not point to a valid value if either it
3260b57cec5SDimitry Andric /// hasn't yet been assigned a value yet or because the value it was tracking
3270b57cec5SDimitry Andric /// has since been deleted.
3280b57cec5SDimitry Andric ///
3290b57cec5SDimitry Andric /// Assigning a value to a TrackingVH is always allowed, even if said TrackingVH
3300b57cec5SDimitry Andric /// no longer points to a valid value.
3310b57cec5SDimitry Andric template <typename ValueTy> class TrackingVH {
3320b57cec5SDimitry Andric   WeakTrackingVH InnerHandle;
3330b57cec5SDimitry Andric 
3340b57cec5SDimitry Andric public:
3350b57cec5SDimitry Andric   ValueTy *getValPtr() const {
3360b57cec5SDimitry Andric     assert(InnerHandle.pointsToAliveValue() &&
3370b57cec5SDimitry Andric            "TrackingVH must be non-null and valid on dereference!");
3380b57cec5SDimitry Andric 
3390b57cec5SDimitry Andric     // Check that the value is a member of the correct subclass. We would like
3400b57cec5SDimitry Andric     // to check this property on assignment for better debugging, but we don't
3410b57cec5SDimitry Andric     // want to require a virtual interface on this VH. Instead we allow RAUW to
3420b57cec5SDimitry Andric     // replace this value with a value of an invalid type, and check it here.
3430b57cec5SDimitry Andric     assert(isa<ValueTy>(InnerHandle) &&
3440b57cec5SDimitry Andric            "Tracked Value was replaced by one with an invalid type!");
3450b57cec5SDimitry Andric     return cast<ValueTy>(InnerHandle);
3460b57cec5SDimitry Andric   }
3470b57cec5SDimitry Andric 
3480b57cec5SDimitry Andric   void setValPtr(ValueTy *P) {
3490b57cec5SDimitry Andric     // Assigning to non-valid TrackingVH's are fine so we just unconditionally
3500b57cec5SDimitry Andric     // assign here.
3510b57cec5SDimitry Andric     InnerHandle = GetAsValue(P);
3520b57cec5SDimitry Andric   }
3530b57cec5SDimitry Andric 
3540b57cec5SDimitry Andric   // Convert a ValueTy*, which may be const, to the type the base
3550b57cec5SDimitry Andric   // class expects.
3560b57cec5SDimitry Andric   static Value *GetAsValue(Value *V) { return V; }
3570b57cec5SDimitry Andric   static Value *GetAsValue(const Value *V) { return const_cast<Value*>(V); }
3580b57cec5SDimitry Andric 
3590b57cec5SDimitry Andric public:
3600b57cec5SDimitry Andric   TrackingVH() = default;
3610b57cec5SDimitry Andric   TrackingVH(ValueTy *P) { setValPtr(P); }
3620b57cec5SDimitry Andric 
3630b57cec5SDimitry Andric   operator ValueTy*() const {
3640b57cec5SDimitry Andric     return getValPtr();
3650b57cec5SDimitry Andric   }
3660b57cec5SDimitry Andric 
3670b57cec5SDimitry Andric   ValueTy *operator=(ValueTy *RHS) {
3680b57cec5SDimitry Andric     setValPtr(RHS);
3690b57cec5SDimitry Andric     return getValPtr();
3700b57cec5SDimitry Andric   }
3710b57cec5SDimitry Andric 
3720b57cec5SDimitry Andric   ValueTy *operator->() const { return getValPtr(); }
3730b57cec5SDimitry Andric   ValueTy &operator*() const { return *getValPtr(); }
3740b57cec5SDimitry Andric };
3750b57cec5SDimitry Andric 
3760b57cec5SDimitry Andric /// Value handle with callbacks on RAUW and destruction.
3770b57cec5SDimitry Andric ///
3780b57cec5SDimitry Andric /// This is a value handle that allows subclasses to define callbacks that run
3790b57cec5SDimitry Andric /// when the underlying Value has RAUW called on it or is destroyed.  This
3800b57cec5SDimitry Andric /// class can be used as the key of a map, as long as the user takes it out of
3810b57cec5SDimitry Andric /// the map before calling setValPtr() (since the map has to rearrange itself
3820b57cec5SDimitry Andric /// when the pointer changes).  Unlike ValueHandleBase, this class has a vtable.
3830b57cec5SDimitry Andric class CallbackVH : public ValueHandleBase {
3840b57cec5SDimitry Andric   virtual void anchor();
3850b57cec5SDimitry Andric protected:
3860b57cec5SDimitry Andric   ~CallbackVH() = default;
3870b57cec5SDimitry Andric   CallbackVH(const CallbackVH &) = default;
3880b57cec5SDimitry Andric   CallbackVH &operator=(const CallbackVH &) = default;
3890b57cec5SDimitry Andric 
3900b57cec5SDimitry Andric   void setValPtr(Value *P) {
3910b57cec5SDimitry Andric     ValueHandleBase::operator=(P);
3920b57cec5SDimitry Andric   }
3930b57cec5SDimitry Andric 
3940b57cec5SDimitry Andric public:
3950b57cec5SDimitry Andric   CallbackVH() : ValueHandleBase(Callback) {}
3960b57cec5SDimitry Andric   CallbackVH(Value *P) : ValueHandleBase(Callback, P) {}
3975ffd83dbSDimitry Andric   CallbackVH(const Value *P) : CallbackVH(const_cast<Value *>(P)) {}
3980b57cec5SDimitry Andric 
3990b57cec5SDimitry Andric   operator Value*() const {
4000b57cec5SDimitry Andric     return getValPtr();
4010b57cec5SDimitry Andric   }
4020b57cec5SDimitry Andric 
4030b57cec5SDimitry Andric   /// Callback for Value destruction.
4040b57cec5SDimitry Andric   ///
4050b57cec5SDimitry Andric   /// Called when this->getValPtr() is destroyed, inside ~Value(), so you
4060b57cec5SDimitry Andric   /// may call any non-virtual Value method on getValPtr(), but no subclass
4070b57cec5SDimitry Andric   /// methods.  If WeakTrackingVH were implemented as a CallbackVH, it would use
4080b57cec5SDimitry Andric   /// this
4090b57cec5SDimitry Andric   /// method to call setValPtr(NULL).  AssertingVH would use this method to
4100b57cec5SDimitry Andric   /// cause an assertion failure.
4110b57cec5SDimitry Andric   ///
4120b57cec5SDimitry Andric   /// All implementations must remove the reference from this object to the
4130b57cec5SDimitry Andric   /// Value that's being destroyed.
4140b57cec5SDimitry Andric   virtual void deleted() { setValPtr(nullptr); }
4150b57cec5SDimitry Andric 
4160b57cec5SDimitry Andric   /// Callback for Value RAUW.
4170b57cec5SDimitry Andric   ///
4180b57cec5SDimitry Andric   /// Called when this->getValPtr()->replaceAllUsesWith(new_value) is called,
4190b57cec5SDimitry Andric   /// _before_ any of the uses have actually been replaced.  If WeakTrackingVH
4200b57cec5SDimitry Andric   /// were
4210b57cec5SDimitry Andric   /// implemented as a CallbackVH, it would use this method to call
4220b57cec5SDimitry Andric   /// setValPtr(new_value).  AssertingVH would do nothing in this method.
4230b57cec5SDimitry Andric   virtual void allUsesReplacedWith(Value *) {}
4240b57cec5SDimitry Andric };
4250b57cec5SDimitry Andric 
4260b57cec5SDimitry Andric /// Value handle that poisons itself if the Value is deleted.
4270b57cec5SDimitry Andric ///
4280b57cec5SDimitry Andric /// This is a Value Handle that points to a value and poisons itself if the
4290b57cec5SDimitry Andric /// value is destroyed while the handle is still live.  This is very useful for
4300b57cec5SDimitry Andric /// catching dangling pointer bugs where an \c AssertingVH cannot be used
4310b57cec5SDimitry Andric /// because the dangling handle needs to outlive the value without ever being
4320b57cec5SDimitry Andric /// used.
4330b57cec5SDimitry Andric ///
4340b57cec5SDimitry Andric /// One particularly useful place to use this is as the Key of a map. Dangling
4350b57cec5SDimitry Andric /// pointer bugs often lead to really subtle bugs that only occur if another
4360b57cec5SDimitry Andric /// object happens to get allocated to the same address as the old one. Using
4370b57cec5SDimitry Andric /// a PoisoningVH ensures that an assert is triggered if looking up a new value
4380b57cec5SDimitry Andric /// in the map finds a handle from the old value.
4390b57cec5SDimitry Andric ///
4400b57cec5SDimitry Andric /// Note that a PoisoningVH handle does *not* follow values across RAUW
4410b57cec5SDimitry Andric /// operations. This means that RAUW's need to explicitly update the
4420b57cec5SDimitry Andric /// PoisoningVH's as it moves. This is required because in non-assert mode this
4430b57cec5SDimitry Andric /// class turns into a trivial wrapper around a pointer.
4440b57cec5SDimitry Andric template <typename ValueTy>
445*e8d8bef9SDimitry Andric class PoisoningVH final
446*e8d8bef9SDimitry Andric #if LLVM_ENABLE_ABI_BREAKING_CHECKS
447*e8d8bef9SDimitry Andric     : public CallbackVH
4480b57cec5SDimitry Andric #endif
4490b57cec5SDimitry Andric {
4500b57cec5SDimitry Andric   friend struct DenseMapInfo<PoisoningVH<ValueTy>>;
4510b57cec5SDimitry Andric 
4520b57cec5SDimitry Andric   // Convert a ValueTy*, which may be const, to the raw Value*.
4530b57cec5SDimitry Andric   static Value *GetAsValue(Value *V) { return V; }
4540b57cec5SDimitry Andric   static Value *GetAsValue(const Value *V) { return const_cast<Value *>(V); }
4550b57cec5SDimitry Andric 
456*e8d8bef9SDimitry Andric #if LLVM_ENABLE_ABI_BREAKING_CHECKS
4570b57cec5SDimitry Andric   /// A flag tracking whether this value has been poisoned.
4580b57cec5SDimitry Andric   ///
4590b57cec5SDimitry Andric   /// On delete and RAUW, we leave the value pointer alone so that as a raw
4600b57cec5SDimitry Andric   /// pointer it produces the same value (and we fit into the same key of
4610b57cec5SDimitry Andric   /// a hash table, etc), but we poison the handle so that any top-level usage
4620b57cec5SDimitry Andric   /// will fail.
4630b57cec5SDimitry Andric   bool Poisoned = false;
4640b57cec5SDimitry Andric 
4650b57cec5SDimitry Andric   Value *getRawValPtr() const { return ValueHandleBase::getValPtr(); }
4660b57cec5SDimitry Andric   void setRawValPtr(Value *P) { ValueHandleBase::operator=(P); }
4670b57cec5SDimitry Andric 
4680b57cec5SDimitry Andric   /// Handle deletion by poisoning the handle.
4690b57cec5SDimitry Andric   void deleted() override {
4700b57cec5SDimitry Andric     assert(!Poisoned && "Tried to delete an already poisoned handle!");
4710b57cec5SDimitry Andric     Poisoned = true;
4720b57cec5SDimitry Andric     RemoveFromUseList();
4730b57cec5SDimitry Andric   }
4740b57cec5SDimitry Andric 
4750b57cec5SDimitry Andric   /// Handle RAUW by poisoning the handle.
4760b57cec5SDimitry Andric   void allUsesReplacedWith(Value *) override {
4770b57cec5SDimitry Andric     assert(!Poisoned && "Tried to RAUW an already poisoned handle!");
4780b57cec5SDimitry Andric     Poisoned = true;
4790b57cec5SDimitry Andric     RemoveFromUseList();
4800b57cec5SDimitry Andric   }
481*e8d8bef9SDimitry Andric #else // LLVM_ENABLE_ABI_BREAKING_CHECKS
4820b57cec5SDimitry Andric   Value *ThePtr = nullptr;
4830b57cec5SDimitry Andric 
4840b57cec5SDimitry Andric   Value *getRawValPtr() const { return ThePtr; }
4850b57cec5SDimitry Andric   void setRawValPtr(Value *P) { ThePtr = P; }
4860b57cec5SDimitry Andric #endif
4870b57cec5SDimitry Andric 
4880b57cec5SDimitry Andric   ValueTy *getValPtr() const {
489*e8d8bef9SDimitry Andric #if LLVM_ENABLE_ABI_BREAKING_CHECKS
4900b57cec5SDimitry Andric     assert(!Poisoned && "Accessed a poisoned value handle!");
491*e8d8bef9SDimitry Andric #endif
4920b57cec5SDimitry Andric     return static_cast<ValueTy *>(getRawValPtr());
4930b57cec5SDimitry Andric   }
4940b57cec5SDimitry Andric   void setValPtr(ValueTy *P) { setRawValPtr(GetAsValue(P)); }
4950b57cec5SDimitry Andric 
4960b57cec5SDimitry Andric public:
4970b57cec5SDimitry Andric   PoisoningVH() = default;
498*e8d8bef9SDimitry Andric #if LLVM_ENABLE_ABI_BREAKING_CHECKS
4990b57cec5SDimitry Andric   PoisoningVH(ValueTy *P) : CallbackVH(GetAsValue(P)) {}
5000b57cec5SDimitry Andric   PoisoningVH(const PoisoningVH &RHS)
5010b57cec5SDimitry Andric       : CallbackVH(RHS), Poisoned(RHS.Poisoned) {}
5020b57cec5SDimitry Andric 
5030b57cec5SDimitry Andric   ~PoisoningVH() {
5040b57cec5SDimitry Andric     if (Poisoned)
5050b57cec5SDimitry Andric       clearValPtr();
5060b57cec5SDimitry Andric   }
5070b57cec5SDimitry Andric 
5080b57cec5SDimitry Andric   PoisoningVH &operator=(const PoisoningVH &RHS) {
5090b57cec5SDimitry Andric     if (Poisoned)
5100b57cec5SDimitry Andric       clearValPtr();
5110b57cec5SDimitry Andric     CallbackVH::operator=(RHS);
5120b57cec5SDimitry Andric     Poisoned = RHS.Poisoned;
5130b57cec5SDimitry Andric     return *this;
5140b57cec5SDimitry Andric   }
5150b57cec5SDimitry Andric #else
5160b57cec5SDimitry Andric   PoisoningVH(ValueTy *P) : ThePtr(GetAsValue(P)) {}
5170b57cec5SDimitry Andric #endif
5180b57cec5SDimitry Andric 
5190b57cec5SDimitry Andric   operator ValueTy *() const { return getValPtr(); }
5200b57cec5SDimitry Andric 
5210b57cec5SDimitry Andric   ValueTy *operator->() const { return getValPtr(); }
5220b57cec5SDimitry Andric   ValueTy &operator*() const { return *getValPtr(); }
5230b57cec5SDimitry Andric };
5240b57cec5SDimitry Andric 
5250b57cec5SDimitry Andric // Specialize DenseMapInfo to allow PoisoningVH to participate in DenseMap.
5260b57cec5SDimitry Andric template <typename T> struct DenseMapInfo<PoisoningVH<T>> {
5270b57cec5SDimitry Andric   static inline PoisoningVH<T> getEmptyKey() {
5280b57cec5SDimitry Andric     PoisoningVH<T> Res;
5290b57cec5SDimitry Andric     Res.setRawValPtr(DenseMapInfo<Value *>::getEmptyKey());
5300b57cec5SDimitry Andric     return Res;
5310b57cec5SDimitry Andric   }
5320b57cec5SDimitry Andric 
5330b57cec5SDimitry Andric   static inline PoisoningVH<T> getTombstoneKey() {
5340b57cec5SDimitry Andric     PoisoningVH<T> Res;
5350b57cec5SDimitry Andric     Res.setRawValPtr(DenseMapInfo<Value *>::getTombstoneKey());
5360b57cec5SDimitry Andric     return Res;
5370b57cec5SDimitry Andric   }
5380b57cec5SDimitry Andric 
5390b57cec5SDimitry Andric   static unsigned getHashValue(const PoisoningVH<T> &Val) {
5400b57cec5SDimitry Andric     return DenseMapInfo<Value *>::getHashValue(Val.getRawValPtr());
5410b57cec5SDimitry Andric   }
5420b57cec5SDimitry Andric 
5430b57cec5SDimitry Andric   static bool isEqual(const PoisoningVH<T> &LHS, const PoisoningVH<T> &RHS) {
5440b57cec5SDimitry Andric     return DenseMapInfo<Value *>::isEqual(LHS.getRawValPtr(),
5450b57cec5SDimitry Andric                                           RHS.getRawValPtr());
5460b57cec5SDimitry Andric   }
5475ffd83dbSDimitry Andric 
5485ffd83dbSDimitry Andric   // Allow lookup by T* via find_as(), without constructing a temporary
5495ffd83dbSDimitry Andric   // value handle.
5505ffd83dbSDimitry Andric 
5515ffd83dbSDimitry Andric   static unsigned getHashValue(const T *Val) {
5525ffd83dbSDimitry Andric     return DenseMapInfo<Value *>::getHashValue(Val);
5535ffd83dbSDimitry Andric   }
5545ffd83dbSDimitry Andric 
5555ffd83dbSDimitry Andric   static bool isEqual(const T *LHS, const PoisoningVH<T> &RHS) {
5565ffd83dbSDimitry Andric     return DenseMapInfo<Value *>::isEqual(LHS, RHS.getRawValPtr());
5575ffd83dbSDimitry Andric   }
5580b57cec5SDimitry Andric };
5590b57cec5SDimitry Andric 
5600b57cec5SDimitry Andric } // end namespace llvm
5610b57cec5SDimitry Andric 
5620b57cec5SDimitry Andric #endif // LLVM_IR_VALUEHANDLE_H
563