Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a new WeakVH value handle; NFC #6664

Open
wants to merge 6 commits into
base: user/zhengxing/Rename-WeakVH-upstream
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions docs/ProgrammersManual.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1416,9 +1416,9 @@ llvm/IR/ValueMap.h
ValueMap is a wrapper around a :ref:`DenseMap <dss_densemap>` mapping
``Value*``\ s (or subclasses) to another type. When a Value is deleted or
RAUW'ed, ValueMap will update itself so the new version of the key is mapped to
the same value, just as if the key were a WeakVH. You can configure exactly how
this happens, and what else happens on these two events, by passing a ``Config``
parameter to the ValueMap template.
the same value, just as if the key were a WeakTrackingVH. You can configure
exactly how this happens, and what else happens on these two events, by passing
a ``Config`` parameter to the ValueMap template.

.. _dss_intervalmap:

Expand Down
4 changes: 2 additions & 2 deletions include/llvm/Analysis/AssumptionCache.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ class AssumptionCache {

/// \brief Vector of weak value handles to calls of the @llvm.assume
/// intrinsic.
SmallVector<WeakVH, 4> AssumeHandles;
SmallVector<WeakTrackingVH, 4> AssumeHandles;

/// \brief Flag tracking whether we have scanned the function yet.
///
Expand Down Expand Up @@ -86,7 +86,7 @@ class AssumptionCache {
/// FIXME: We should replace this with pointee_iterator<filter_iterator<...>>
/// when we can write that to filter out the null values. Then caller code
/// will become simpler.
MutableArrayRef<WeakVH> assumptions() {
MutableArrayRef<WeakTrackingVH> assumptions() {
if (!Scanned)
scanFunction();
return AssumeHandles;
Expand Down
2 changes: 1 addition & 1 deletion include/llvm/Analysis/CallGraph.h
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ class CallGraphNode {
public:
/// \brief A pair of the calling instruction (a call or invoke)
/// and the call graph node being called.
typedef std::pair<WeakVH, CallGraphNode *> CallRecord;
typedef std::pair<WeakTrackingVH, CallGraphNode *> CallRecord;

public:
typedef std::vector<CallRecord> CalledFunctionsVector;
Expand Down
2 changes: 1 addition & 1 deletion include/llvm/Analysis/DxilValueCache.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ struct DxilValueCache : public ImmutablePass {
void allUsesReplacedWith(Value *) override { setValPtr(nullptr); }
};
struct ValueEntry {
WeakVH Value;
WeakTrackingVH Value;
ValueVH Self;
ValueEntry() : Value(nullptr), Self(nullptr) {}
inline void Set(llvm::Value *Key, llvm::Value *V) {
Expand Down
2 changes: 1 addition & 1 deletion include/llvm/Analysis/IVUsers.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ class IVStrideUse : public CallbackVH, public ilist_node<IVStrideUse> {

/// OperandValToReplace - The Value of the operand in the user instruction
/// that this IVStrideUse is representing.
WeakVH OperandValToReplace;
WeakTrackingVH OperandValToReplace;

/// PostIncLoops - The set of loops for which Expr has been adjusted to
/// use post-inc mode. This corresponds with SCEVExpander's post-inc concept.
Expand Down
2 changes: 1 addition & 1 deletion include/llvm/Analysis/MemoryBuiltins.h
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ class ObjectSizeOffsetEvaluator
: public InstVisitor<ObjectSizeOffsetEvaluator, SizeOffsetEvalType> {

typedef IRBuilder<true, TargetFolder> BuilderTy;
typedef std::pair<WeakVH, WeakVH> WeakEvalType;
typedef std::pair<WeakTrackingVH, WeakTrackingVH> WeakEvalType;
typedef DenseMap<const Value*, WeakEvalType> CacheMapTy;
typedef SmallPtrSet<const Value*, 8> PtrSetTy;

Expand Down
2 changes: 1 addition & 1 deletion include/llvm/Analysis/ScalarEvolutionExpander.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ namespace llvm {
/// \brief replace congruent phis with their most canonical
/// representative. Return the number of phis eliminated.
unsigned replaceCongruentIVs(Loop *L, const DominatorTree *DT,
SmallVectorImpl<WeakVH> &DeadInsts,
SmallVectorImpl<WeakTrackingVH> &DeadInsts,
const TargetTransformInfo *TTI = nullptr);

/// \brief Insert code to directly compute the specified SCEV expression
Expand Down
168 changes: 107 additions & 61 deletions include/llvm/IR/ValueHandle.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,59 +45,62 @@ class ValueHandleBase {
///
/// 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,
Weak
};
enum HandleBaseKind { Assert, Callback, Weak, WeakTracking };

private:
PointerIntPair<ValueHandleBase**, 2, HandleBaseKind> PrevPair;
ValueHandleBase *Next;

Value* V;
Value *Val;

void setValPtr(Value *V) { Val = V; }

ValueHandleBase(const ValueHandleBase&) = delete;
public:
explicit ValueHandleBase(HandleBaseKind Kind)
: PrevPair(nullptr, Kind), Next(nullptr), V(nullptr) {}
: PrevPair(nullptr, Kind), Next(nullptr), Val(nullptr) {}
ValueHandleBase(HandleBaseKind Kind, Value *V)
: PrevPair(nullptr, Kind), Next(nullptr), V(V) {
if (isValid(V))
: PrevPair(nullptr, Kind), Next(nullptr), Val(V) {
if (isValid(getValPtr()))
AddToUseList();
}
ValueHandleBase(HandleBaseKind Kind, const ValueHandleBase &RHS)
: PrevPair(nullptr, Kind), Next(nullptr), V(RHS.V) {
if (isValid(V))
: PrevPair(nullptr, Kind), Next(nullptr), Val(RHS.getValPtr()) {
if (isValid(getValPtr()))
AddToExistingUseList(RHS.getPrevPtr());
}
~ValueHandleBase() {
if (isValid(V))
if (isValid(getValPtr()))
RemoveFromUseList();
}

Value *operator=(Value *RHS) {
if (V == RHS) return RHS;
if (isValid(V)) RemoveFromUseList();
V = RHS;
if (isValid(V)) AddToUseList();
if (getValPtr() == RHS)
return RHS;
if (isValid(getValPtr()))
RemoveFromUseList();
setValPtr(RHS);
if (isValid(getValPtr()))
AddToUseList();
return RHS;
}

Value *operator=(const ValueHandleBase &RHS) {
if (V == RHS.V) return RHS.V;
if (isValid(V)) RemoveFromUseList();
V = RHS.V;
if (isValid(V)) AddToExistingUseList(RHS.getPrevPtr());
return V;
if (getValPtr() == RHS.getValPtr())
return RHS.getValPtr();
if (isValid(getValPtr()))
RemoveFromUseList();
setValPtr(RHS.getValPtr());
if (isValid(getValPtr()))
AddToExistingUseList(RHS.getPrevPtr());
return getValPtr();
}

Value *operator->() const { return V; }
Value &operator*() const { return *V; }
Value *operator->() const { return getValPtr(); }
Value &operator*() const { return *getValPtr(); }

protected:
Value *getValPtr() const { return V; }
Value *getValPtr() const { return Val; }

static bool isValid(Value *V) {
return V &&
Expand Down Expand Up @@ -131,21 +134,52 @@ class ValueHandleBase {
void RemoveFromUseList();
};

/// \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
/// RAUW operations, but will null itself out if the value is destroyed. this
/// is useful for advisory sorts of information, but should not be used as the
/// key of a map (since the map would have to rearrange itself when the pointer
/// changes).
class WeakVH : public ValueHandleBase {
class WeakTrackingVH : public ValueHandleBase {
public:
WeakVH() : ValueHandleBase(Weak) {}
WeakVH(Value *P) : ValueHandleBase(Weak, P) {}
WeakVH(const WeakVH &RHS)
: ValueHandleBase(Weak, RHS) {}
WeakTrackingVH() : ValueHandleBase(WeakTracking) {}
WeakTrackingVH(Value *P) : ValueHandleBase(WeakTracking, P) {}
WeakTrackingVH(const WeakTrackingVH &RHS)
: ValueHandleBase(WeakTracking, RHS) {}

WeakVH &operator=(const WeakVH &RHS) = default;
WeakTrackingVH &operator=(const WeakTrackingVH &RHS) = default;

Value *operator=(Value *RHS) {
return ValueHandleBase::operator=(RHS);
Expand All @@ -157,17 +191,23 @@ class WeakVH : public ValueHandleBase {
operator Value*() const {
return getValPtr();
}

bool pointsToAliveValue() const {
return ValueHandleBase::isValid(getValPtr());
}
};

// Specialize simplify_type to allow WeakVH to participate in
// Specialize simplify_type to allow WeakTrackingVH to participate in
// dyn_cast, isa, etc.
template <> struct simplify_type<WeakVH> {
template <> struct simplify_type<WeakTrackingVH> {
typedef Value *SimpleType;
static SimpleType getSimplifiedValue(WeakVH &WVH) { return WVH; }
static SimpleType getSimplifiedValue(WeakTrackingVH &WVH) { return WVH; }
};
template <> struct simplify_type<const WeakVH> {
template <> struct simplify_type<const WeakTrackingVH> {
typedef Value *SimpleType;
static SimpleType getSimplifiedValue(const WeakVH &WVH) { return WVH; }
static SimpleType getSimplifiedValue(const WeakTrackingVH &WVH) {
return WVH;
}
};

/// \brief Value handle that asserts if the Value is deleted.
Expand Down Expand Up @@ -274,39 +314,43 @@ struct isPodLike<AssertingVH<T> > {
/// 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();
///
/// It is an error to read from a TrackingVH that does not point to a valid
/// value. A TrackingVH is said to not point to a valid value if either it
/// hasn't yet been assigned a value yet or because the value it was tracking
/// has since been deleted.
///
/// Assigning a value to a TrackingVH is always allowed, even if said TrackingVH
/// no longer points to a valid value.
template <typename ValueTy> class TrackingVH {
WeakTrackingVH InnerHandle;

// Null is always ok.
if (!VP) return;
public:
ValueTy *getValPtr() const {
// HLSL Change begin
// This is align with what the original TrackingVH does, Null is always ok.
if (InnerHandle.operator llvm::Value *() == nullptr)
return nullptr;
//HLSL Change end.

// 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!");
assert(InnerHandle.pointsToAliveValue() &&
"TrackingVH must be non-null and valid on dereference!");

// 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) &&
assert(isa<ValueTy>(InnerHandle) &&
"Tracked Value was replaced by one with an invalid type!");
return cast<ValueTy>(InnerHandle);
}

ValueTy *getValPtr() const {
CheckValidity();
return (ValueTy*)ValueHandleBase::getValPtr();
}
void setValPtr(ValueTy *P) {
CheckValidity();
ValueHandleBase::operator=(GetAsValue(P));
// Assigning to non-valid TrackingVH's are fine so we just unconditionally
// assign here.
InnerHandle = GetAsValue(P);
}

// Convert a ValueTy*, which may be const, to the type the base
Expand All @@ -315,9 +359,9 @@ class TrackingVH : public ValueHandleBase {
static Value *GetAsValue(const Value *V) { return const_cast<Value*>(V); }

public:
TrackingVH() : ValueHandleBase(Tracking) {}
TrackingVH(ValueTy *P) : ValueHandleBase(Tracking, GetAsValue(P)) {}
TrackingVH(const TrackingVH &RHS) : ValueHandleBase(Tracking, RHS) {}
TrackingVH() {}
TrackingVH(ValueTy *P) { setValPtr(P); }
TrackingVH(const TrackingVH &RHS) { setValPtr(RHS.getValPtr()); } // HLSL Change

operator ValueTy*() const {
return getValPtr();
Expand Down Expand Up @@ -368,7 +412,8 @@ class CallbackVH : public ValueHandleBase {
///
/// Called when this->getValPtr() is destroyed, inside ~Value(), so you
/// may call any non-virtual Value method on getValPtr(), but no subclass
/// methods. If WeakVH were implemented as a CallbackVH, it would use this
/// methods. If WeakTrackingVH were implemented as a CallbackVH, it would use
/// this
/// method to call setValPtr(NULL). AssertingVH would use this method to
/// cause an assertion failure.
///
Expand All @@ -379,7 +424,8 @@ class CallbackVH : public ValueHandleBase {
/// \brief Callback for Value RAUW.
///
/// Called when this->getValPtr()->replaceAllUsesWith(new_value) is called,
/// _before_ any of the uses have actually been replaced. If WeakVH were
/// _before_ any of the uses have actually been replaced. If WeakTrackingVH
/// were
/// implemented as a CallbackVH, it would use this method to call
/// setValPtr(new_value). AssertingVH would do nothing in this method.
virtual void allUsesReplacedWith(Value *) {}
Expand Down
2 changes: 1 addition & 1 deletion include/llvm/Transforms/Utils/Cloning.h
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ class InlineFunctionInfo {

/// InlinedCalls - InlineFunction fills this in with callsites that were
/// inlined from the callee. This is only filled in if CG is non-null.
SmallVector<WeakVH, 8> InlinedCalls;
SmallVector<WeakTrackingVH, 8> InlinedCalls;

void reset() {
StaticAllocas.clear();
Expand Down
5 changes: 3 additions & 2 deletions include/llvm/Transforms/Utils/SimplifyIndVar.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,13 @@ class IVVisitor {
/// simplifyUsersOfIV - Simplify instructions that use this induction variable
/// by using ScalarEvolution to analyze the IV's recurrence.
bool simplifyUsersOfIV(PHINode *CurrIV, ScalarEvolution *SE, LPPassManager *LPM,
SmallVectorImpl<WeakVH> &Dead, IVVisitor *V = nullptr);
SmallVectorImpl<WeakTrackingVH> &Dead,
IVVisitor *V = nullptr);

/// SimplifyLoopIVs - Simplify users of induction variables within this
/// loop. This does not actually change or add IVs.
bool simplifyLoopIVs(Loop *L, ScalarEvolution *SE, LPPassManager *LPM,
SmallVectorImpl<WeakVH> &Dead);
SmallVectorImpl<WeakTrackingVH> &Dead);

} // namespace llvm

Expand Down
2 changes: 1 addition & 1 deletion include/llvm/Transforms/Utils/ValueMapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
namespace llvm {
class Value;
class Instruction;
typedef ValueMap<const Value *, WeakVH> ValueToValueMapTy;
typedef ValueMap<const Value *, WeakTrackingVH> ValueToValueMapTy;

/// ValueMapTypeRemapper - This is a class that can be implemented by clients
/// to remap types when cloning constants and instructions.
Expand Down
Loading
Loading