diff options
author | Sanjoy Das <sanjoy@playingwithpointers.com> | 2017-04-26 16:20:59 +0000 |
---|---|---|
committer | Sanjoy Das <sanjoy@playingwithpointers.com> | 2017-04-26 16:20:59 +0000 |
commit | 7de051ba0c4632dc5fcabc4f17cdf0cedf97724e (patch) | |
tree | 0ebb49094b5c389a8028fb5ef8e34cca64b7e36b | |
parent | 01de5577388a02ea289b5517d55dc0e8eb4efc76 (diff) | |
download | bcm5719-llvm-7de051ba0c4632dc5fcabc4f17cdf0cedf97724e.tar.gz bcm5719-llvm-7de051ba0c4632dc5fcabc4f17cdf0cedf97724e.zip |
Add a new WeakVH value handle; NFC
Summary:
WeakVH nulls itself out if the value it was tracking gets deleted, but
it does not track RAUW.
Reviewers: dblaikie, davide
Subscribers: mcrosier, llvm-commits
Differential Revision: https://reviews.llvm.org/D32267
llvm-svn: 301425
-rw-r--r-- | llvm/include/llvm/IR/ValueHandle.h | 40 | ||||
-rw-r--r-- | llvm/lib/IR/Value.cpp | 7 | ||||
-rw-r--r-- | llvm/unittests/IR/ValueHandleTest.cpp | 18 |
3 files changed, 61 insertions, 4 deletions
diff --git a/llvm/include/llvm/IR/ValueHandle.h b/llvm/include/llvm/IR/ValueHandle.h index 7109c7b19f4..cba06671314 100644 --- a/llvm/include/llvm/IR/ValueHandle.h +++ b/llvm/include/llvm/IR/ValueHandle.h @@ -34,7 +34,7 @@ protected: /// /// This is to avoid having a vtable for the light-weight handle pointers. The /// fully general Callback version does have a vtable. - enum HandleBaseKind { Assert, Callback, Tracking, WeakTracking }; + enum HandleBaseKind { Assert, Callback, Tracking, Weak, WeakTracking }; ValueHandleBase(const ValueHandleBase &RHS) : ValueHandleBase(RHS.PrevPair.getInt(), RHS) {} @@ -46,7 +46,7 @@ protected: } private: - PointerIntPair<ValueHandleBase**, 2, HandleBaseKind> PrevPair; + PointerIntPair<ValueHandleBase**, 3, HandleBaseKind> PrevPair; ValueHandleBase *Next; Value* V; @@ -126,6 +126,42 @@ private: void AddToUseList(); }; +/// \brief A nullable Value handle that is nullable. +/// +/// This is a value handle that points to a value, and nulls itself +/// out if that value is deleted. +class WeakVH : public ValueHandleBase { +public: + WeakVH() : ValueHandleBase(Weak) {} + WeakVH(Value *P) : ValueHandleBase(Weak, P) {} + WeakVH(const WeakVH &RHS) + : ValueHandleBase(Weak, RHS) {} + + WeakVH &operator=(const WeakVH &RHS) = default; + + Value *operator=(Value *RHS) { + return ValueHandleBase::operator=(RHS); + } + Value *operator=(const ValueHandleBase &RHS) { + return ValueHandleBase::operator=(RHS); + } + + operator Value*() const { + return getValPtr(); + } +}; + +// Specialize simplify_type to allow WeakVH to participate in +// dyn_cast, isa, etc. +template <> struct simplify_type<WeakVH> { + typedef Value *SimpleType; + static SimpleType getSimplifiedValue(WeakVH &WVH) { return WVH; } +}; +template <> struct simplify_type<const WeakVH> { + typedef Value *SimpleType; + static SimpleType getSimplifiedValue(const WeakVH &WVH) { return WVH; } +}; + /// \brief Value handle that is nullable, but tries to track the Value. /// /// This is a value handle that tries hard to point to a Value, even across diff --git a/llvm/lib/IR/Value.cpp b/llvm/lib/IR/Value.cpp index 23a0f7a2601..18e44dcd352 100644 --- a/llvm/lib/IR/Value.cpp +++ b/llvm/lib/IR/Value.cpp @@ -825,8 +825,10 @@ void ValueHandleBase::ValueIsDeleted(Value *V) { // pointer. Entry->operator=(DenseMapInfo<Value *>::getTombstoneKey()); break; + case Weak: case WeakTracking: - // WeakTracking just goes to null, which will unlink it from the list. + // WeakTracking and Weak just go to null, which unlinks them + // from the list. Entry->operator=(nullptr); break; case Callback: @@ -874,7 +876,8 @@ void ValueHandleBase::ValueIsRAUWd(Value *Old, Value *New) { switch (Entry->getKind()) { case Assert: - // Asserting handle does not follow RAUW implicitly. + case Weak: + // Asserting and Weak handles do not follow RAUW implicitly. break; case Tracking: // Tracking goes to new value like a WeakTrackingVH. Note that this may diff --git a/llvm/unittests/IR/ValueHandleTest.cpp b/llvm/unittests/IR/ValueHandleTest.cpp index f4cacd3f7dd..191fdbb8f0f 100644 --- a/llvm/unittests/IR/ValueHandleTest.cpp +++ b/llvm/unittests/IR/ValueHandleTest.cpp @@ -34,6 +34,24 @@ public: ConcreteCallbackVH(Value *V) : CallbackVH(V) {} }; +TEST_F(ValueHandle, WeakVH_BasicOperation) { + WeakVH WVH(BitcastV.get()); + EXPECT_EQ(BitcastV.get(), WVH); + WVH = ConstantV; + EXPECT_EQ(ConstantV, WVH); + + // Make sure I can call a method on the underlying Value. It + // doesn't matter which method. + EXPECT_EQ(Type::getInt32Ty(Context), WVH->getType()); + EXPECT_EQ(Type::getInt32Ty(Context), (*WVH).getType()); + + WVH = BitcastV.get(); + BitcastV->replaceAllUsesWith(ConstantV); + EXPECT_EQ(WVH, BitcastV.get()); + BitcastV.reset(); + EXPECT_EQ(WVH, nullptr); +} + TEST_F(ValueHandle, WeakTrackingVH_BasicOperation) { WeakTrackingVH WVH(BitcastV.get()); EXPECT_EQ(BitcastV.get(), WVH); |