summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSanjoy Das <sanjoy@playingwithpointers.com>2017-04-26 16:20:59 +0000
committerSanjoy Das <sanjoy@playingwithpointers.com>2017-04-26 16:20:59 +0000
commit7de051ba0c4632dc5fcabc4f17cdf0cedf97724e (patch)
tree0ebb49094b5c389a8028fb5ef8e34cca64b7e36b
parent01de5577388a02ea289b5517d55dc0e8eb4efc76 (diff)
downloadbcm5719-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.h40
-rw-r--r--llvm/lib/IR/Value.cpp7
-rw-r--r--llvm/unittests/IR/ValueHandleTest.cpp18
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);
OpenPOWER on IntegriCloud