[llvm-commits] [llvm] r82506 - in /llvm/trunk: include/llvm/Support/ValueHandle.h lib/VMCore/Value.cpp

Daniel Dunbar daniel at zuster.org
Sat Oct 10 12:38:54 PDT 2009


Will do.

 - Daniel

On Tue, Sep 22, 2009 at 5:02 AM, Daniel Dunbar <daniel at zuster.org> wrote:
> Author: ddunbar
> Date: Mon Sep 21 21:02:33 2009
> New Revision: 82506
>
> URL: http://llvm.org/viewvc/llvm-project?rev=82506&view=rev
> Log:
> Add a TrackingVH value handle.
>
> This is designed for tracking a value even when it might move (like WeakVH), but it is an error to delete the referenced value (unlike WeakVH0. TrackingVH is templated like AssertingVH on the tracked Value subclass, it is an error to RAUW a tracked value to an incompatible type.
>
> For implementation reasons the latter error is only diagnosed on accesses to a mis-RAUWed TrackingVH, because we don't want a virtual interface in a templated class.
>
> The former error is also only diagnosed on access, so that clients are allowed to delete a tracked value, as long as they don't use it. This makes it easier for the client to reason about destruction.
>
> Modified:
>    llvm/trunk/include/llvm/Support/ValueHandle.h
>    llvm/trunk/lib/VMCore/Value.cpp
>
> Modified: llvm/trunk/include/llvm/Support/ValueHandle.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/ValueHandle.h?rev=82506&r1=82505&r2=82506&view=diff
>
> ==============================================================================
> --- llvm/trunk/include/llvm/Support/ValueHandle.h (original)
> +++ llvm/trunk/include/llvm/Support/ValueHandle.h Mon Sep 21 21:02:33 2009
> @@ -45,8 +45,9 @@
>   /// fully general Callback version does have a vtable.
>   enum HandleBaseKind {
>     Assert,
> -    Weak,
> -    Callback
> +    Callback,
> +    Tracking,
> +    Weak
>   };
>  private:
>
> @@ -92,13 +93,13 @@
>
>  protected:
>   Value *getValPtr() const { return VP; }
> -private:
>   static bool isValid(Value *V) {
>     return V &&
>            V != DenseMapInfo<Value *>::getEmptyKey() &&
>            V != DenseMapInfo<Value *>::getTombstoneKey();
>   }
>
> +private:
>   // Callbacks made from Value.
>   static void ValueIsDeleted(Value *V);
>   static void ValueIsRAUWd(Value *Old, Value *New);
> @@ -223,6 +224,88 @@
>  template<> struct simplify_type<AssertingVH<Value> >
>   : public simplify_type<const AssertingVH<Value> > {};
>
> +/// TrackingVH - This is a value handle that tracks a Value (or Value subclass),
> +/// even across RAUW operations.
> +///
> +/// TrackingVH is designed for situations where a client needs to hold a handle
> +/// to a Value (or subclass) across some operations which may move that value,
> +/// but should never destroy it or replace it with some unacceptable type.
> +///
> +/// It is an error to do anything with a TrackingVH whose value has been
> +/// destroyed, except to destruct it.
> +///
> +/// It is an error to attempt to replace a value with one of a type which is
> +/// incompatible with any of its outstanding TrackingVHs.
> +template<typename ValueTy>
> +class TrackingVH : public ValueHandleBase {
> +  void CheckValidity() const {
> +    Value *VP = ValueHandleBase::getValPtr();
> +
> +    // Null is always ok.
> +    if (!VP)
> +        return;
> +
> +    // Check that this value is valid (i.e., it hasn't been deleted). We
> +    // explicitly delay this check until access to avoid requiring clients to be
> +    // unnecessarily careful w.r.t. destruction.
> +    assert(ValueHandleBase::isValid(VP) && "Tracked Value was deleted!");
> +
> +    // Check that the value is a member of the correct subclass. We would like
> +    // to check this property on assignment for better debugging, but we don't
> +    // want to require a virtual interface on this VH. Instead we allow RAUW to
> +    // replace this value with a value of an invalid type, and check it here.
> +    assert(isa<ValueTy>(VP) &&
> +           "Tracked Value was replaced by one with an invalid type!");
> +  }
> +
> +  ValueTy *getValPtr() const {
> +    CheckValidity();
> +    return static_cast<ValueTy*>(ValueHandleBase::getValPtr());
> +  }
> +  void setValPtr(ValueTy *P) {
> +    CheckValidity();
> +    ValueHandleBase::operator=(GetAsValue(P));
> +  }
> +
> +  // Convert a ValueTy*, which may be const, to the type the base
> +  // class expects.
> +  static Value *GetAsValue(Value *V) { return V; }
> +  static Value *GetAsValue(const Value *V) { return const_cast<Value*>(V); }
> +
> +public:
> +  TrackingVH() : ValueHandleBase(Tracking) {}
> +  TrackingVH(ValueTy *P) : ValueHandleBase(Tracking, P) {}
> +  TrackingVH(const TrackingVH &RHS) : ValueHandleBase(Tracking, RHS) {}
> +
> +  operator ValueTy*() const {
> +    return getValPtr();
> +  }
> +
> +  ValueTy *operator=(ValueTy *RHS) {
> +    setValPtr(RHS);
> +    return getValPtr();
> +  }
> +  ValueTy *operator=(const TrackingVH<ValueTy> &RHS) {
> +    setValPtr(RHS.getValPtr());
> +    return getValPtr();
> +  }
> +
> +  ValueTy *operator->() const { return getValPtr(); }
> +  ValueTy &operator*() const { return *getValPtr(); }
> +};
> +
> +// Specialize simplify_type to allow TrackingVH to participate in
> +// dyn_cast, isa, etc.
> +template<typename From> struct simplify_type;
> +template<> struct simplify_type<const TrackingVH<Value> > {
> +  typedef Value* SimpleType;
> +  static SimpleType getSimplifiedValue(const TrackingVH<Value> &AVH) {
> +    return static_cast<Value *>(AVH);
> +  }
> +};
> +template<> struct simplify_type<TrackingVH<Value> >
> +  : public simplify_type<const TrackingVH<Value> > {};
> +
>  /// CallbackVH - This is a value handle that allows subclasses to define
>  /// callbacks that run when the underlying Value has RAUW called on it or is
>  /// destroyed.  This class can be used as the key of a map, as long as the user
>
> Modified: llvm/trunk/lib/VMCore/Value.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Value.cpp?rev=82506&r1=82505&r2=82506&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/VMCore/Value.cpp (original)
> +++ llvm/trunk/lib/VMCore/Value.cpp Mon Sep 21 21:02:33 2009
> @@ -503,6 +503,11 @@
>  #endif
>       llvm_unreachable("An asserting value handle still pointed to this"
>                        " value!");
> +    case Tracking:
> +      // Mark that this value has been deleted by setting it to an invalid Value
> +      // pointer.
> +      ThisNode->operator=(DenseMapInfo<Value *>::getTombstoneKey());
> +      break;
>     case Weak:
>       // Weak just goes to null, which will unlink it from the list.
>       ThisNode->operator=(0);
> @@ -539,6 +544,14 @@
>     case Assert:
>       // Asserting handle does not follow RAUW implicitly.
>       break;
> +    case Tracking:
> +      // Tracking goes to new value like a WeakVH. Note that this may make it
> +      // something incompatible with its templated type. We don't want to have a
> +      // virtual (or inline) interface to handle this though, so instead we make
> +      // the TrackingVH accessors guarantee that a client never seesl this
> +      // value.
> +
> +      // FALLTHROUGH
>     case Weak:
>       // Weak goes to the new value, which will unlink it from Old's list.
>       ThisNode->operator=(New);
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>




More information about the llvm-commits mailing list