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