diff --git a/docs/ProgrammersManual.rst b/docs/ProgrammersManual.rst index 0baa7c0bcf..b781ab1b45 100644 --- a/docs/ProgrammersManual.rst +++ b/docs/ProgrammersManual.rst @@ -1416,9 +1416,9 @@ llvm/IR/ValueMap.h ValueMap is a wrapper around a :ref:`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: diff --git a/include/llvm/Analysis/AssumptionCache.h b/include/llvm/Analysis/AssumptionCache.h index 1f00b691b3..0b493711dc 100644 --- a/include/llvm/Analysis/AssumptionCache.h +++ b/include/llvm/Analysis/AssumptionCache.h @@ -48,7 +48,7 @@ class AssumptionCache { /// \brief Vector of weak value handles to calls of the @llvm.assume /// intrinsic. - SmallVector AssumeHandles; + SmallVector AssumeHandles; /// \brief Flag tracking whether we have scanned the function yet. /// @@ -86,7 +86,7 @@ class AssumptionCache { /// FIXME: We should replace this with pointee_iterator> /// when we can write that to filter out the null values. Then caller code /// will become simpler. - MutableArrayRef assumptions() { + MutableArrayRef assumptions() { if (!Scanned) scanFunction(); return AssumeHandles; diff --git a/include/llvm/Analysis/CallGraph.h b/include/llvm/Analysis/CallGraph.h index 6310a68de0..723aa2e3d8 100644 --- a/include/llvm/Analysis/CallGraph.h +++ b/include/llvm/Analysis/CallGraph.h @@ -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 CallRecord; + typedef std::pair CallRecord; public: typedef std::vector CalledFunctionsVector; diff --git a/include/llvm/Analysis/DxilValueCache.h b/include/llvm/Analysis/DxilValueCache.h index e7f3c9acd9..355baae73e 100644 --- a/include/llvm/Analysis/DxilValueCache.h +++ b/include/llvm/Analysis/DxilValueCache.h @@ -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) { diff --git a/include/llvm/Analysis/IVUsers.h b/include/llvm/Analysis/IVUsers.h index a5be928b7b..78bbede907 100644 --- a/include/llvm/Analysis/IVUsers.h +++ b/include/llvm/Analysis/IVUsers.h @@ -79,7 +79,7 @@ class IVStrideUse : public CallbackVH, public ilist_node { /// 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. diff --git a/include/llvm/Analysis/MemoryBuiltins.h b/include/llvm/Analysis/MemoryBuiltins.h index 7d3cd466fd..8aa830478e 100644 --- a/include/llvm/Analysis/MemoryBuiltins.h +++ b/include/llvm/Analysis/MemoryBuiltins.h @@ -208,7 +208,7 @@ class ObjectSizeOffsetEvaluator : public InstVisitor { typedef IRBuilder BuilderTy; - typedef std::pair WeakEvalType; + typedef std::pair WeakEvalType; typedef DenseMap CacheMapTy; typedef SmallPtrSet PtrSetTy; diff --git a/include/llvm/Analysis/ScalarEvolutionExpander.h b/include/llvm/Analysis/ScalarEvolutionExpander.h index 8ec2078258..c70529d157 100644 --- a/include/llvm/Analysis/ScalarEvolutionExpander.h +++ b/include/llvm/Analysis/ScalarEvolutionExpander.h @@ -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 &DeadInsts, + SmallVectorImpl &DeadInsts, const TargetTransformInfo *TTI = nullptr); /// \brief Insert code to directly compute the specified SCEV expression diff --git a/include/llvm/IR/ValueHandle.h b/include/llvm/IR/ValueHandle.h index 7232bbfd08..6b17b71f53 100644 --- a/include/llvm/IR/ValueHandle.h +++ b/include/llvm/IR/ValueHandle.h @@ -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 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 && @@ -131,6 +134,37 @@ 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 { + typedef Value *SimpleType; + static SimpleType getSimplifiedValue(WeakVH &WVH) { return WVH; } +}; +template <> struct simplify_type { + 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 @@ -138,14 +172,14 @@ class ValueHandleBase { /// 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); @@ -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 { +template <> struct simplify_type { typedef Value *SimpleType; - static SimpleType getSimplifiedValue(WeakVH &WVH) { return WVH; } + static SimpleType getSimplifiedValue(WeakTrackingVH &WVH) { return WVH; } }; -template <> struct simplify_type { +template <> struct simplify_type { 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. @@ -274,39 +314,43 @@ struct isPodLike > { /// 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 -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 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(VP) && + assert(isa(InnerHandle) && "Tracked Value was replaced by one with an invalid type!"); + return cast(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 @@ -315,9 +359,9 @@ class TrackingVH : public ValueHandleBase { static Value *GetAsValue(const Value *V) { return const_cast(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(); @@ -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. /// @@ -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 *) {} diff --git a/include/llvm/Transforms/Utils/Cloning.h b/include/llvm/Transforms/Utils/Cloning.h index 2caa9a2462..cc4bb16016 100644 --- a/include/llvm/Transforms/Utils/Cloning.h +++ b/include/llvm/Transforms/Utils/Cloning.h @@ -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 InlinedCalls; + SmallVector InlinedCalls; void reset() { StaticAllocas.clear(); diff --git a/include/llvm/Transforms/Utils/SimplifyIndVar.h b/include/llvm/Transforms/Utils/SimplifyIndVar.h index dcb1d67cbf..ebd713ee7e 100644 --- a/include/llvm/Transforms/Utils/SimplifyIndVar.h +++ b/include/llvm/Transforms/Utils/SimplifyIndVar.h @@ -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 &Dead, IVVisitor *V = nullptr); + SmallVectorImpl &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 &Dead); + SmallVectorImpl &Dead); } // namespace llvm diff --git a/include/llvm/Transforms/Utils/ValueMapper.h b/include/llvm/Transforms/Utils/ValueMapper.h index 047ab81871..24bf091a78 100644 --- a/include/llvm/Transforms/Utils/ValueMapper.h +++ b/include/llvm/Transforms/Utils/ValueMapper.h @@ -20,7 +20,7 @@ namespace llvm { class Value; class Instruction; - typedef ValueMap ValueToValueMapTy; + typedef ValueMap ValueToValueMapTy; /// ValueMapTypeRemapper - This is a class that can be implemented by clients /// to remap types when cloning constants and instructions. diff --git a/lib/Analysis/IPA/CallGraphSCCPass.cpp b/lib/Analysis/IPA/CallGraphSCCPass.cpp index 94fef69f58..610f01a2c7 100644 --- a/lib/Analysis/IPA/CallGraphSCCPass.cpp +++ b/lib/Analysis/IPA/CallGraphSCCPass.cpp @@ -219,7 +219,7 @@ bool CGPassManager::RefreshCallGraph(CallGraphSCC &CurSCC, // Get the set of call sites currently in the function. for (CallGraphNode::iterator I = CGN->begin(), E = CGN->end(); I != E; ) { // If this call site is null, then the function pass deleted the call - // entirely and the WeakVH nulled it out. + // entirely and the WeakTrackingVH nulled it out. if (!I->first || // If we've already seen this call site, then the FunctionPass RAUW'd // one call with another, which resulted in two "uses" in the edge @@ -362,7 +362,8 @@ bool CGPassManager::RefreshCallGraph(CallGraphSCC &CurSCC, DevirtualizedCall = true; // After scanning this function, if we still have entries in callsites, then - // they are dangling pointers. WeakVH should save us for this, so abort if + // they are dangling pointers. WeakTrackingVH should save us for this, so + // abort if // this happens. assert(CallSites.empty() && "Dangling pointers found in call sites map"); diff --git a/lib/Analysis/ScalarEvolutionExpander.cpp b/lib/Analysis/ScalarEvolutionExpander.cpp index fee2a2d0d1..bcc1d3ed35 100644 --- a/lib/Analysis/ScalarEvolutionExpander.cpp +++ b/lib/Analysis/ScalarEvolutionExpander.cpp @@ -1689,9 +1689,10 @@ SCEVExpander::getOrInsertCanonicalInductionVariable(const Loop *L, /// /// This does not depend on any SCEVExpander state but should be used in /// the same context that SCEVExpander is used. -unsigned SCEVExpander::replaceCongruentIVs(Loop *L, const DominatorTree *DT, - SmallVectorImpl &DeadInsts, - const TargetTransformInfo *TTI) { +unsigned +SCEVExpander::replaceCongruentIVs(Loop *L, const DominatorTree *DT, + SmallVectorImpl &DeadInsts, + const TargetTransformInfo *TTI) { // Find integer phis in order of increasing width. SmallVector Phis; for (BasicBlock::iterator I = L->getHeader()->begin(); diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index c568656b39..185c291d66 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -44,7 +44,7 @@ enum { }; class BitcodeReaderValueList { - std::vector ValuePtrs; + std::vector ValuePtrs; /// As we resolve forward-referenced constants, we add information about them /// to this vector. This allows us to resolve them in bulk instead of @@ -786,7 +786,7 @@ void BitcodeReaderValueList::assignValue(Value *V, unsigned Idx) { if (Idx >= size()) resize(Idx+1); - WeakVH &OldV = ValuePtrs[Idx]; + WeakTrackingVH &OldV = ValuePtrs[Idx]; if (!OldV) { OldV = V; return; diff --git a/lib/HLSL/DxilPreparePasses.cpp b/lib/HLSL/DxilPreparePasses.cpp index 9c925d8329..1ef4307cd2 100644 --- a/lib/HLSL/DxilPreparePasses.cpp +++ b/lib/HLSL/DxilPreparePasses.cpp @@ -1410,7 +1410,7 @@ bool CleanupSharedMemoryAddrSpaceCast(Module &M) { } // Cleanup unused replacement instructions - SmallVector cleanupInsts; + SmallVector cleanupInsts; for (auto it : valueMap) { if (isa(it.first)) cleanupInsts.push_back(it.first); diff --git a/lib/IR/Value.cpp b/lib/IR/Value.cpp index a9cfce28e0..41148c26d6 100644 --- a/lib/IR/Value.cpp +++ b/lib/IR/Value.cpp @@ -559,7 +559,7 @@ void ValueHandleBase::AddToExistingUseList(ValueHandleBase **List) { setPrevPtr(List); if (Next) { Next->setPrevPtr(&Next); - assert(V == Next->V && "Added to wrong list?"); + assert(getValPtr() == Next->getValPtr() && "Added to wrong list?"); } } @@ -574,14 +574,14 @@ void ValueHandleBase::AddToExistingUseListAfter(ValueHandleBase *List) { } void ValueHandleBase::AddToUseList() { - assert(V && "Null pointer doesn't have a use list!"); + assert(getValPtr() && "Null pointer doesn't have a use list!"); - LLVMContextImpl *pImpl = V->getContext().pImpl; + LLVMContextImpl *pImpl = getValPtr()->getContext().pImpl; - if (V->HasValueHandle) { + if (getValPtr()->HasValueHandle) { // If this value already has a ValueHandle, then it must be in the // ValueHandles map already. - ValueHandleBase *&Entry = pImpl->ValueHandles[V]; + ValueHandleBase *&Entry = pImpl->ValueHandles[getValPtr()]; assert(Entry && "Value doesn't have any handles?"); AddToExistingUseList(&Entry); return; @@ -595,10 +595,10 @@ void ValueHandleBase::AddToUseList() { DenseMap &Handles = pImpl->ValueHandles; const void *OldBucketPtr = Handles.getPointerIntoBucketsArray(); - ValueHandleBase *&Entry = Handles[V]; + ValueHandleBase *&Entry = Handles[getValPtr()]; assert(!Entry && "Value really did already have handles?"); AddToExistingUseList(&Entry); - V->HasValueHandle = true; + getValPtr()->HasValueHandle = true; // If reallocation didn't happen or if this was the first insertion, don't // walk the table. @@ -610,16 +610,19 @@ void ValueHandleBase::AddToUseList() { // Okay, reallocation did happen. Fix the Prev Pointers. for (DenseMap::iterator I = Handles.begin(), E = Handles.end(); I != E; ++I) { - assert(I->second && I->first == I->second->V && + assert(I->second && I->first == I->second->getValPtr() && "List invariant broken!"); I->second->setPrevPtr(&I->second); } } void ValueHandleBase::RemoveFromUseList() { - assert(V && (std::current_exception() == nullptr || V->HasValueHandle) && // HLSL Change + assert(getValPtr() && + (std::current_exception() == nullptr || + getValPtr()->HasValueHandle) && // HLSL Change "Pointer doesn't have a use list!"); - if (!V->HasValueHandle) return; // HLSL Change + if (!getValPtr()->HasValueHandle) + return; // HLSL Change // Unlink this from its use list. ValueHandleBase **PrevPtr = getPrevPtr(); assert(*PrevPtr == this && "List invariant broken"); @@ -634,11 +637,11 @@ void ValueHandleBase::RemoveFromUseList() { // If the Next pointer was null, then it is possible that this was the last // ValueHandle watching VP. If so, delete its entry from the ValueHandles // map. - LLVMContextImpl *pImpl = V->getContext().pImpl; + LLVMContextImpl *pImpl = getValPtr()->getContext().pImpl; DenseMap &Handles = pImpl->ValueHandles; if (Handles.isPointerIntoBucketsArray(PrevPtr)) { - Handles.erase(V); - V->HasValueHandle = false; + Handles.erase(getValPtr()); + getValPtr()->HasValueHandle = false; } } @@ -669,13 +672,9 @@ void ValueHandleBase::ValueIsDeleted(Value *V) { switch (Entry->getKind()) { case Assert: break; - case Tracking: - // Mark that this value has been deleted by setting it to an invalid Value - // pointer. - Entry->operator=(DenseMapInfo::getTombstoneKey()); - break; case Weak: - // Weak just goes to null, which will unlink it from the list. + case WeakTracking: + // WeakTracking just goes to null, which will unlink it from the list. Entry->operator=(nullptr); break; case Callback: @@ -724,16 +723,10 @@ void ValueHandleBase::ValueIsRAUWd(Value *Old, Value *New) { switch (Entry->getKind()) { 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 sees this value. - - LLVM_FALLTHROUGH; // HLSL CHANGE case Weak: + // Asserting and Weak handles do not follow RAUW implicitly. + break; + case WeakTracking: // Weak goes to the new value, which will unlink it from Old's list. Entry->operator=(New); break; @@ -745,18 +738,17 @@ void ValueHandleBase::ValueIsRAUWd(Value *Old, Value *New) { } #ifndef NDEBUG - // If any new tracking or weak value handles were added while processing the + // If any new weak value handles were added while processing the // list, then complain about it now. if (Old->HasValueHandle) for (Entry = pImpl->ValueHandles[Old]; Entry; Entry = Entry->Next) switch (Entry->getKind()) { - case Tracking: - case Weak: + case WeakTracking: dbgs() << "After RAUW from " << *Old->getType() << " %" << Old->getName() << " to " << *New->getType() << " %" << New->getName() << "\n"; - llvm_unreachable("A tracking or weak value handle still pointed to the" - " old value!\n"); + llvm_unreachable( + "A weak tracking value handle still pointed to the old value!\n"); default: break; } diff --git a/lib/Transforms/IPO/GlobalOpt.cpp b/lib/Transforms/IPO/GlobalOpt.cpp index dfe496de13..109988eacf 100644 --- a/lib/Transforms/IPO/GlobalOpt.cpp +++ b/lib/Transforms/IPO/GlobalOpt.cpp @@ -276,7 +276,7 @@ static bool CleanupConstantGlobalUsers(Value *V, Constant *Init, // we delete a constant array, we may also be holding pointer to one of its // elements (or an element of one of its elements if we're dealing with an // array of arrays) in the worklist. - SmallVector WorkList(V->user_begin(), V->user_end()); + SmallVector WorkList(V->user_begin(), V->user_end()); while (!WorkList.empty()) { Value *UV = WorkList.pop_back_val(); if (!UV) diff --git a/lib/Transforms/IPO/MergeFunctions.cpp b/lib/Transforms/IPO/MergeFunctions.cpp index e8fdf05275..355165c145 100644 --- a/lib/Transforms/IPO/MergeFunctions.cpp +++ b/lib/Transforms/IPO/MergeFunctions.cpp @@ -1097,11 +1097,11 @@ class MergeFunctions : public ModulePass { /// A work queue of functions that may have been modified and should be /// analyzed again. - std::vector Deferred; + std::vector Deferred; /// Checks the rules of order relation introduced among functions set. /// Returns true, if sanity check has been passed, and false if failed. - bool doSanityCheck(std::vector &Worklist); + bool doSanityCheck(std::vector &Worklist); /// Insert a ComparableFunction into the FnTree, or merge it away if it's /// equal to one that's already present. @@ -1154,7 +1154,7 @@ ModulePass *llvm::createMergeFunctionsPass() { return new MergeFunctions(); } -bool MergeFunctions::doSanityCheck(std::vector &Worklist) { +bool MergeFunctions::doSanityCheck(std::vector &Worklist) { #if 0 // Begin HLSL Change (NumFunctionsForSanityCheck is always zero) if (const unsigned Max = NumFunctionsForSanityCheck) { unsigned TripleNumber = 0; @@ -1163,10 +1163,10 @@ bool MergeFunctions::doSanityCheck(std::vector &Worklist) { dbgs() << "MERGEFUNC-SANITY: Started for first " << Max << " functions.\n"; unsigned i = 0; - for (std::vector::iterator I = Worklist.begin(), E = Worklist.end(); + for (std::vector::iterator I = Worklist.begin(), E = Worklist.end(); I != E && i < Max; ++I, ++i) { unsigned j = i; - for (std::vector::iterator J = I; J != E && j < Max; ++J, ++j) { + for (std::vector::iterator J = I; J != E && j < Max; ++J, ++j) { Function *F1 = cast(*I); Function *F2 = cast(*J); int Res1 = FunctionComparator(F1, F2).compare(); @@ -1185,7 +1185,7 @@ bool MergeFunctions::doSanityCheck(std::vector &Worklist) { continue; unsigned k = j; - for (std::vector::iterator K = J; K != E && k < Max; + for (std::vector::iterator K = J; K != E && k < Max; ++k, ++K, ++TripleNumber) { if (K == J) continue; @@ -1233,11 +1233,11 @@ bool MergeFunctions::runOnModule(Module &M) { for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) { if (!I->isDeclaration() && !I->hasAvailableExternallyLinkage()) - Deferred.push_back(WeakVH(I)); + Deferred.push_back(WeakTrackingVH(I)); } do { - std::vector Worklist; + std::vector Worklist; Deferred.swap(Worklist); DEBUG(doSanityCheck(Worklist)); @@ -1247,7 +1247,7 @@ bool MergeFunctions::runOnModule(Module &M) { // Insert only strong functions and merge them. Strong function merging // always deletes one of them. - for (std::vector::iterator I = Worklist.begin(), + for (std::vector::iterator I = Worklist.begin(), E = Worklist.end(); I != E; ++I) { if (!*I) continue; Function *F = cast(*I); @@ -1261,7 +1261,7 @@ bool MergeFunctions::runOnModule(Module &M) { // create thunks to the strong function when possible. When two weak // functions are identical, we create a new strong function with two weak // weak thunks to it which are identical but not mergable. - for (std::vector::iterator I = Worklist.begin(), + for (std::vector::iterator I = Worklist.begin(), E = Worklist.end(); I != E; ++I) { if (!*I) continue; Function *F = cast(*I); diff --git a/lib/Transforms/InstCombine/InstructionCombining.cpp b/lib/Transforms/InstCombine/InstructionCombining.cpp index 3608eecf88..d4e6ed387d 100644 --- a/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -1841,8 +1841,8 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) { return nullptr; } -static bool -isAllocSiteRemovable(Instruction *AI, SmallVectorImpl &Users, +static bool isAllocSiteRemovable(Instruction *AI, + SmallVectorImpl &Users, const TargetLibraryInfo *TLI) { SmallVector Worklist; Worklist.push_back(AI); @@ -1922,7 +1922,7 @@ Instruction *InstCombiner::visitAllocSite(Instruction &MI) { // If we have a malloc call which is only used in any amount of comparisons // to null and free calls, delete the calls and replace the comparisons with // true or false as appropriate. - SmallVector Users; + SmallVector Users; if (isAllocSiteRemovable(&MI, Users, TLI)) { for (unsigned i = 0, e = Users.size(); i != e; ++i) { Instruction *I = cast_or_null(&*Users[i]); diff --git a/lib/Transforms/Scalar/DeadStoreElimination.cpp b/lib/Transforms/Scalar/DeadStoreElimination.cpp index 3860c9aedb..d5a22cf6b3 100644 --- a/lib/Transforms/Scalar/DeadStoreElimination.cpp +++ b/lib/Transforms/Scalar/DeadStoreElimination.cpp @@ -511,7 +511,7 @@ bool DSE::runOnBasicBlock(BasicBlock &BB) { // DeleteDeadInstruction can delete the current instruction. Save BBI // in case we need it. - WeakVH NextInst(BBI); + WeakTrackingVH NextInst(BBI); DeleteDeadInstruction(SI, *MD, TLI); diff --git a/lib/Transforms/Scalar/IndVarSimplify.cpp b/lib/Transforms/Scalar/IndVarSimplify.cpp index f5b1455d59..31961b4ddb 100644 --- a/lib/Transforms/Scalar/IndVarSimplify.cpp +++ b/lib/Transforms/Scalar/IndVarSimplify.cpp @@ -100,7 +100,7 @@ namespace { TargetLibraryInfo *TLI; const TargetTransformInfo *TTI; - SmallVector DeadInsts; + SmallVector DeadInsts; bool Changed; public: @@ -441,8 +441,8 @@ void IndVarSimplify::HandleFloatingPointIV(Loop *L, PHINode *PN) { Compare->getName()); // In the following deletions, PN may become dead and may be deleted. - // Use a WeakVH to observe whether this happens. - WeakVH WeakPH = PN; + // Use a WeakTrackingVH to observe whether this happens. + WeakTrackingVH WeakPH = PN; // Delete the old floating point exit comparison. The branch starts using the // new comparison. @@ -477,7 +477,7 @@ void IndVarSimplify::RewriteNonIntegerIVs(Loop *L) { // BasicBlock *Header = L->getHeader(); - SmallVector PHIs; + SmallVector PHIs; for (BasicBlock::iterator I = Header->begin(); PHINode *PN = dyn_cast(I); ++I) PHIs.push_back(PN); @@ -897,15 +897,15 @@ class WidenIV { PHINode *WidePhi; Instruction *WideInc; const SCEV *WideIncExpr; - SmallVectorImpl &DeadInsts; + SmallVectorImpl &DeadInsts; SmallPtrSet Widened; SmallVector NarrowIVUsers; public: WidenIV(const WideIVInfo &WI, LoopInfo *LInfo, - ScalarEvolution *SEv, DominatorTree *DTree, - SmallVectorImpl &DI) : + ScalarEvolution *SEv, DominatorTree *DTree, SmallVectorImpl &DI) + : OrigPhi(WI.NarrowIV), WideType(WI.WidestNativeType), IsSigned(WI.IsSigned), diff --git a/lib/Transforms/Scalar/LoopIdiomRecognize.cpp b/lib/Transforms/Scalar/LoopIdiomRecognize.cpp index 656cddc516..e5fd96c014 100644 --- a/lib/Transforms/Scalar/LoopIdiomRecognize.cpp +++ b/lib/Transforms/Scalar/LoopIdiomRecognize.cpp @@ -696,7 +696,7 @@ bool LoopIdiomRecognize::runOnLoopBlock(BasicBlock *BB, const SCEV *BECount, Instruction *Inst = I++; // Look for store instructions, which may be optimized to memset/memcpy. if (StoreInst *SI = dyn_cast(Inst)) { - WeakVH InstPtr(I); + WeakTrackingVH InstPtr(I); if (!processLoopStore(SI, BECount)) continue; MadeChange = true; @@ -709,7 +709,7 @@ bool LoopIdiomRecognize::runOnLoopBlock(BasicBlock *BB, const SCEV *BECount, // Look for memset instructions, which may be optimized to a larger memset. if (MemSetInst *MSI = dyn_cast(Inst)) { - WeakVH InstPtr(I); + WeakTrackingVH InstPtr(I); if (!processLoopMemSet(MSI, BECount)) continue; MadeChange = true; diff --git a/lib/Transforms/Scalar/LoopStrengthReduce.cpp b/lib/Transforms/Scalar/LoopStrengthReduce.cpp index 023f7fa9cb..e5c60a432d 100644 --- a/lib/Transforms/Scalar/LoopStrengthReduce.cpp +++ b/lib/Transforms/Scalar/LoopStrengthReduce.cpp @@ -802,7 +802,7 @@ static bool isHighCostExpansion(const SCEV *S, /// specified set are trivially dead, delete them and see if this makes any of /// their operands subsequently dead. static bool -DeleteTriviallyDeadInstructions(SmallVectorImpl &DeadInsts) { +DeleteTriviallyDeadInstructions(SmallVectorImpl &DeadInsts) { bool Changed = false; while (!DeadInsts.empty()) { @@ -1686,7 +1686,7 @@ class LSRInstance { void FinalizeChain(IVChain &Chain); void CollectChains(); void GenerateIVChain(const IVChain &Chain, SCEVExpander &Rewriter, - SmallVectorImpl &DeadInsts); + SmallVectorImpl &DeadInsts); void CollectInterestingTypesAndFactors(); void CollectFixupsAndInitialFormulae(); @@ -1770,16 +1770,16 @@ class LSRInstance { const Formula &F, BasicBlock::iterator IP, SCEVExpander &Rewriter, - SmallVectorImpl &DeadInsts) const; + SmallVectorImpl &DeadInsts) const; void RewriteForPHI(PHINode *PN, const LSRFixup &LF, const Formula &F, SCEVExpander &Rewriter, - SmallVectorImpl &DeadInsts, + SmallVectorImpl &DeadInsts, Pass *P) const; void Rewrite(const LSRFixup &LF, const Formula &F, SCEVExpander &Rewriter, - SmallVectorImpl &DeadInsts, + SmallVectorImpl &DeadInsts, Pass *P) const; void ImplementSolution(const SmallVectorImpl &Solution, Pass *P); @@ -2848,7 +2848,7 @@ static bool canFoldIVIncExpr(const SCEV *IncExpr, Instruction *UserInst, /// GenerateIVChains - Generate an add or subtract for each IVInc in a chain to /// materialize the IV user's operand from the previous IV user's operand. void LSRInstance::GenerateIVChain(const IVChain &Chain, SCEVExpander &Rewriter, - SmallVectorImpl &DeadInsts) { + SmallVectorImpl &DeadInsts) { // Find the new IVOperand for the head of the chain. It may have been replaced // by LSR. const IVInc &Head = Chain.Incs[0]; @@ -4453,7 +4453,7 @@ Value *LSRInstance::Expand(const LSRFixup &LF, const Formula &F, BasicBlock::iterator IP, SCEVExpander &Rewriter, - SmallVectorImpl &DeadInsts) const { + SmallVectorImpl &DeadInsts) const { const LSRUse &LU = Uses[LF.LUIdx]; if (LU.RigidFormula) return LF.OperandValToReplace; @@ -4638,7 +4638,7 @@ void LSRInstance::RewriteForPHI(PHINode *PN, const LSRFixup &LF, const Formula &F, SCEVExpander &Rewriter, - SmallVectorImpl &DeadInsts, + SmallVectorImpl &DeadInsts, Pass *P) const { DenseMap Inserted; for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) @@ -4713,7 +4713,7 @@ void LSRInstance::RewriteForPHI(PHINode *PN, void LSRInstance::Rewrite(const LSRFixup &LF, const Formula &F, SCEVExpander &Rewriter, - SmallVectorImpl &DeadInsts, + SmallVectorImpl &DeadInsts, Pass *P) const { // First, find an insertion point that dominates UserInst. For PHI nodes, // find the nearest block which dominates all the relevant uses. @@ -4752,7 +4752,7 @@ LSRInstance::ImplementSolution(const SmallVectorImpl &Solution, Pass *P) { // Keep track of instructions we may have made dead, so that // we can remove them after we are done working. - SmallVector DeadInsts; + SmallVector DeadInsts; SCEVExpander Rewriter(SE, L->getHeader()->getModule()->getDataLayout(), "lsr"); @@ -5016,7 +5016,7 @@ bool LoopStrengthReduce::runOnLoop(Loop *L, LPPassManager & /*LPM*/) { // Remove any extra phis created by processing inner loops. Changed |= DeleteDeadPHIs(L->getHeader()); if (EnablePhiElim && L->isLoopSimplifyForm()) { - SmallVector DeadInsts; + SmallVector DeadInsts; const DataLayout &DL = L->getHeader()->getModule()->getDataLayout(); SCEVExpander Rewriter(getAnalysis(), DL, "lsr"); #ifndef NDEBUG diff --git a/lib/Transforms/Scalar/LoopUnswitch.cpp b/lib/Transforms/Scalar/LoopUnswitch.cpp index 88bf510800..00a1594e8c 100644 --- a/lib/Transforms/Scalar/LoopUnswitch.cpp +++ b/lib/Transforms/Scalar/LoopUnswitch.cpp @@ -980,11 +980,11 @@ void LoopUnswitch::UnswitchNontrivialCondition(Value *LIC, Constant *Val, LoopProcessWorklist.push_back(NewLoop); redoLoop = true; - // Keep a WeakVH holding onto LIC. If the first call to RewriteLoopBody + // Keep a WeakTrackingVH holding onto LIC. If the first call to RewriteLoopBody // deletes the instruction (for example by simplifying a PHI that feeds into // the condition that we're unswitching on), we don't rewrite the second // iteration. - WeakVH LICHandle(LIC); + WeakTrackingVH LICHandle(LIC); // Now we rewrite the original code to know that the condition is true and the // new code to know that the condition is false. diff --git a/lib/Transforms/Scalar/Reassociate.cpp b/lib/Transforms/Scalar/Reassociate.cpp index 9f2b32f852..c52dac4a54 100644 --- a/lib/Transforms/Scalar/Reassociate.cpp +++ b/lib/Transforms/Scalar/Reassociate.cpp @@ -1134,7 +1134,7 @@ static unsigned FindInOperandList(SmallVectorImpl &Ops, unsigned i, /// Emit a tree of add instructions, summing Ops together /// and returning the result. Insert the tree before I. static Value *EmitAddTreeOfValues(Instruction *I, - SmallVectorImpl &Ops){ + SmallVectorImpl &Ops) { if (Ops.size() == 1) return Ops.back(); Value *V1 = Ops.back(); @@ -1699,7 +1699,7 @@ Value *Reassociate::OptimizeAdd(Instruction *I, ? BinaryOperator::CreateAdd(MaxOccVal, MaxOccVal) : BinaryOperator::CreateFAdd(MaxOccVal, MaxOccVal); - SmallVector NewMulOps; + SmallVector NewMulOps; for (unsigned i = 0; i != Ops.size(); ++i) { // Only try to remove factors from expressions we're allowed to. BinaryOperator *BOp = diff --git a/lib/Transforms/Utils/BasicBlockUtils.cpp b/lib/Transforms/Utils/BasicBlockUtils.cpp index ef7dacac79..700c947fbf 100644 --- a/lib/Transforms/Utils/BasicBlockUtils.cpp +++ b/lib/Transforms/Utils/BasicBlockUtils.cpp @@ -91,8 +91,8 @@ void llvm::FoldSingleEntryPHINodes(BasicBlock *BB, AliasAnalysis *AA, /// it is ultimately unused or if it reaches an unused cycle. bool llvm::DeleteDeadPHIs(BasicBlock *BB, const TargetLibraryInfo *TLI) { // Recursively deleting a PHI may cause multiple PHIs to be deleted - // or RAUW'd undef, so use an array of WeakVH for the PHIs to delete. - SmallVector PHIs; + // or RAUW'd undef, so use an array of WeakTrackingVH for the PHIs to delete. + SmallVector PHIs; for (BasicBlock::iterator I = BB->begin(); PHINode *PN = dyn_cast(I); ++I) PHIs.push_back(PN); diff --git a/lib/Transforms/Utils/CloneFunction.cpp b/lib/Transforms/Utils/CloneFunction.cpp index cc4d6c6fb1..f0d2dbcd7a 100644 --- a/lib/Transforms/Utils/CloneFunction.cpp +++ b/lib/Transforms/Utils/CloneFunction.cpp @@ -297,7 +297,7 @@ namespace { void PruningFunctionCloner::CloneBlock(const BasicBlock *BB, BasicBlock::const_iterator StartingInst, std::vector &ToClone){ - WeakVH &BBEntry = VMap[BB]; + WeakTrackingVH &BBEntry = VMap[BB]; // Have we already cloned this block? if (BBEntry) return; @@ -632,7 +632,7 @@ void llvm::CloneAndPruneIntoFromInst(Function *NewFunc, const Function *OldFunc, // Make a second pass over the PHINodes now that all of them have been // remapped into the new function, simplifying the PHINode and performing any // recursive simplifications exposed. This will transparently update the - // WeakVH in the VMap. Notably, we rely on that so that if we coalesce + // WeakTrackingVH in the VMap. Notably, we rely on that so that if we coalesce // two PHINodes, the iteration over the old PHIs remains valid, and the // mapping will just map us to the new node (which may not even be a PHI // node). diff --git a/lib/Transforms/Utils/InlineFunction.cpp b/lib/Transforms/Utils/InlineFunction.cpp index e72743d139..ff4b29dd56 100644 --- a/lib/Transforms/Utils/InlineFunction.cpp +++ b/lib/Transforms/Utils/InlineFunction.cpp @@ -219,7 +219,7 @@ static void HandleCallsInBlockInlinedThroughInvoke(BasicBlock *BB, II->setAttributes(CI->getAttributes()); // Make sure that anything using the call now uses the invoke! This also - // updates the CallGraph if present, because it uses a WeakVH. + // updates the CallGraph if present, because it uses a WeakTrackingVH. CI->replaceAllUsesWith(II); // Delete the original call diff --git a/lib/Transforms/Utils/Local.cpp b/lib/Transforms/Utils/Local.cpp index 1b97d5669c..b9918e960d 100644 --- a/lib/Transforms/Utils/Local.cpp +++ b/lib/Transforms/Utils/Local.cpp @@ -447,7 +447,7 @@ bool llvm::SimplifyInstructionsInBlock(BasicBlock *BB, assert(!BI->isTerminator()); Instruction *Inst = BI++; - WeakVH BIHandle(BI); + WeakTrackingVH BIHandle(BI); if (recursivelySimplifyInstruction(Inst, TLI)) { MadeChange = true; if (BIHandle != BI) @@ -488,7 +488,7 @@ void llvm::RemovePredecessorAndSimplify(BasicBlock *BB, BasicBlock *Pred) { // that can be removed. BB->removePredecessor(Pred, true); - WeakVH PhiIt = &BB->front(); + WeakTrackingVH PhiIt = &BB->front(); while (PHINode *PN = dyn_cast(PhiIt)) { PhiIt = &*++BasicBlock::iterator(cast(PhiIt)); Value *OldPhiIt = PhiIt; diff --git a/lib/Transforms/Utils/LoopUnroll.cpp b/lib/Transforms/Utils/LoopUnroll.cpp index 1dbce47468..bfb47c28ed 100644 --- a/lib/Transforms/Utils/LoopUnroll.cpp +++ b/lib/Transforms/Utils/LoopUnroll.cpp @@ -495,7 +495,7 @@ bool llvm::UnrollLoop(Loop *L, unsigned Count, unsigned TripCount, // Simplify any new induction variables in the partially unrolled loop. if (SE && !CompletelyUnroll) { - SmallVector DeadInsts; + SmallVector DeadInsts; simplifyLoopIVs(L, SE, LPM, DeadInsts); // Aggressively clean up dead instructions that simplifyLoopIVs already diff --git a/lib/Transforms/Utils/SimplifyIndVar.cpp b/lib/Transforms/Utils/SimplifyIndVar.cpp index ab30aa17c7..0d17526c98 100644 --- a/lib/Transforms/Utils/SimplifyIndVar.cpp +++ b/lib/Transforms/Utils/SimplifyIndVar.cpp @@ -48,13 +48,13 @@ namespace { LoopInfo *LI; ScalarEvolution *SE; - SmallVectorImpl &DeadInsts; + SmallVectorImpl &DeadInsts; bool Changed; public: SimplifyIndvar(Loop *Loop, ScalarEvolution *SE, LoopInfo *LI, - SmallVectorImpl &Dead) + SmallVectorImpl &Dead) : L(Loop), LI(LI), SE(SE), DeadInsts(Dead), Changed(false) { assert(LI && "IV simplification requires LoopInfo"); } @@ -514,8 +514,7 @@ void IVVisitor::anchor() { } /// 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 &Dead, IVVisitor *V) -{ + SmallVectorImpl &Dead, IVVisitor *V) { LoopInfo *LI = &LPM->getAnalysis().getLoopInfo(); SimplifyIndvar SIV(LI->getLoopFor(CurrIV->getParent()), SE, LI, Dead); SIV.simplifyUsers(CurrIV, V); @@ -525,7 +524,7 @@ bool simplifyUsersOfIV(PHINode *CurrIV, ScalarEvolution *SE, LPPassManager *LPM, /// 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 &Dead) { + SmallVectorImpl &Dead) { bool Changed = false; for (BasicBlock::iterator I = L->getHeader()->begin(); isa(I); ++I) { Changed |= simplifyUsersOfIV(cast(I), SE, LPM, Dead); diff --git a/tools/clang/lib/CodeGen/CGDeclCXX.cpp b/tools/clang/lib/CodeGen/CGDeclCXX.cpp index 4922e93ac5..699c0f7021 100644 --- a/tools/clang/lib/CodeGen/CGDeclCXX.cpp +++ b/tools/clang/lib/CodeGen/CGDeclCXX.cpp @@ -557,7 +557,7 @@ CodeGenFunction::GenerateCXXGlobalInitFunc(llvm::Function *Fn, } void CodeGenFunction::GenerateCXXGlobalDtorsFunc(llvm::Function *Fn, - const std::vector > + const std::vector> &DtorsAndObjects) { { auto NL = ApplyDebugLocation::CreateEmpty(*this); diff --git a/tools/clang/lib/CodeGen/CodeGenFunction.h b/tools/clang/lib/CodeGen/CodeGenFunction.h index be9c2389ef..7c7ff628b9 100644 --- a/tools/clang/lib/CodeGen/CodeGenFunction.h +++ b/tools/clang/lib/CodeGen/CodeGenFunction.h @@ -2849,7 +2849,7 @@ class CodeGenFunction : public CodeGenTypeCache { /// GenerateCXXGlobalDtorsFunc - Generates code for destroying global /// variables. void GenerateCXXGlobalDtorsFunc(llvm::Function *Fn, - const std::vector > &DtorsAndObjects); void GenerateCXXGlobalVarDeclInitFunc(llvm::Function *Fn, diff --git a/tools/clang/lib/CodeGen/CodeGenModule.cpp b/tools/clang/lib/CodeGen/CodeGenModule.cpp index bc88c32cbd..73ad296d47 100644 --- a/tools/clang/lib/CodeGen/CodeGenModule.cpp +++ b/tools/clang/lib/CodeGen/CodeGenModule.cpp @@ -990,7 +990,7 @@ void CodeGenModule::addCompilerUsedGlobal(llvm::GlobalValue *GV) { } static void emitUsed(CodeGenModule &CGM, StringRef Name, - std::vector &List) { + std::vector &List) { // Don't create llvm.used if there is no need. if (List.empty()) return; diff --git a/tools/clang/lib/CodeGen/CodeGenModule.h b/tools/clang/lib/CodeGen/CodeGenModule.h index 7f0e216e2a..1ef4e2c1c5 100644 --- a/tools/clang/lib/CodeGen/CodeGenModule.h +++ b/tools/clang/lib/CodeGen/CodeGenModule.h @@ -351,8 +351,8 @@ class CodeGenModule : public CodeGenTypeCache { /// List of global values which are required to be present in the object file; /// bitcast to i8*. This is used for forcing visibility of symbols which may /// otherwise be optimized out. - std::vector LLVMUsed; - std::vector LLVMCompilerUsed; + std::vector LLVMUsed; + std::vector LLVMCompilerUsed; /// Store the list of global constructors and their respective priorities to /// be emitted when the translation unit is complete. @@ -424,7 +424,7 @@ class CodeGenModule : public CodeGenTypeCache { SmallVector PrioritizedCXXGlobalInits; /// Global destructor functions and arguments that need to run on termination. - std::vector > CXXGlobalDtors; + std::vector> CXXGlobalDtors; /// \brief The complete set of modules that has been imported. llvm::SetVector ImportedModules; @@ -437,11 +437,11 @@ class CodeGenModule : public CodeGenTypeCache { /// Cached reference to the class for constant strings. This value has type /// int * but is actually an Obj-C class pointer. - llvm::WeakVH CFConstantStringClassRef; + llvm::WeakTrackingVH CFConstantStringClassRef; /// Cached reference to the class for constant strings. This value has type /// int * but is actually an Obj-C class pointer. - llvm::WeakVH ConstantStringClassRef; + llvm::WeakTrackingVH ConstantStringClassRef; /// \brief The LLVM type corresponding to NSConstantString. llvm::StructType *NSConstantStringType; diff --git a/unittests/IR/ValueHandleTest.cpp b/unittests/IR/ValueHandleTest.cpp index e6eb7cbedc..5cdad74b45 100644 --- a/unittests/IR/ValueHandleTest.cpp +++ b/unittests/IR/ValueHandleTest.cpp @@ -44,11 +44,29 @@ TEST_F(ValueHandle, WeakVH_BasicOperation) { // doesn't matter which method. EXPECT_EQ(Type::getInt32Ty(getGlobalContext()), WVH->getType()); EXPECT_EQ(Type::getInt32Ty(getGlobalContext()), (*WVH).getType()); + + WVH = BitcastV.get(); + BitcastV->replaceAllUsesWith(ConstantV); + EXPECT_EQ(WVH, BitcastV.get()); + BitcastV.reset(); + EXPECT_EQ(WVH, nullptr); } -TEST_F(ValueHandle, WeakVH_Comparisons) { - WeakVH BitcastWVH(BitcastV.get()); - WeakVH ConstantWVH(ConstantV); +TEST_F(ValueHandle, WeakTrackingVH_BasicOperation) { + WeakTrackingVH 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(getGlobalContext()), WVH->getType()); + EXPECT_EQ(Type::getInt32Ty(getGlobalContext()), (*WVH).getType()); +} + +TEST_F(ValueHandle, WeakTrackingVH_Comparisons) { + WeakTrackingVH BitcastWVH(BitcastV.get()); + WeakTrackingVH ConstantWVH(ConstantV); EXPECT_TRUE(BitcastWVH == BitcastWVH); EXPECT_TRUE(BitcastV.get() == BitcastWVH); @@ -79,20 +97,20 @@ TEST_F(ValueHandle, WeakVH_Comparisons) { EXPECT_EQ(BV >= CV, BitcastWVH >= ConstantV); } -TEST_F(ValueHandle, WeakVH_FollowsRAUW) { - WeakVH WVH(BitcastV.get()); - WeakVH WVH_Copy(WVH); - WeakVH WVH_Recreated(BitcastV.get()); +TEST_F(ValueHandle, WeakTrackingVH_FollowsRAUW) { + WeakTrackingVH WVH(BitcastV.get()); + WeakTrackingVH WVH_Copy(WVH); + WeakTrackingVH WVH_Recreated(BitcastV.get()); BitcastV->replaceAllUsesWith(ConstantV); EXPECT_EQ(ConstantV, WVH); EXPECT_EQ(ConstantV, WVH_Copy); EXPECT_EQ(ConstantV, WVH_Recreated); } -TEST_F(ValueHandle, WeakVH_NullOnDeletion) { - WeakVH WVH(BitcastV.get()); - WeakVH WVH_Copy(WVH); - WeakVH WVH_Recreated(BitcastV.get()); +TEST_F(ValueHandle, WeakTrackingVH_NullOnDeletion) { + WeakTrackingVH WVH(BitcastV.get()); + WeakTrackingVH WVH_Copy(WVH); + WeakTrackingVH WVH_Recreated(BitcastV.get()); BitcastV.reset(); Value *null_value = nullptr; EXPECT_EQ(null_value, WVH); @@ -100,7 +118,6 @@ TEST_F(ValueHandle, WeakVH_NullOnDeletion) { EXPECT_EQ(null_value, WVH_Recreated); } - TEST_F(ValueHandle, AssertingVH_BasicOperation) { AssertingVH AVH(BitcastV.get()); CastInst *implicit_to_exact_type = AVH; @@ -171,6 +188,12 @@ TEST_F(ValueHandle, AssertingVH_ReducesToPointer) { #else // !NDEBUG +TEST_F(ValueHandle, TrackingVH_Tracks) { + TrackingVH VH(BitcastV.get()); + BitcastV->replaceAllUsesWith(ConstantV); + EXPECT_EQ(VH, ConstantV); +} + #ifdef GTEST_HAS_DEATH_TEST TEST_F(ValueHandle, AssertingVH_Asserts) { @@ -185,6 +208,26 @@ TEST_F(ValueHandle, AssertingVH_Asserts) { BitcastV.reset(); } +TEST_F(ValueHandle, TrackingVH_Asserts) { + { + TrackingVH VH(BitcastV.get()); + + // The tracking handle shouldn't assert when the value is deleted. + BitcastV.reset(new BitCastInst(ConstantV, Type::getInt32Ty(Context))); + // But should when we access the handle. + EXPECT_DEATH((void)*VH, + "TrackingVH must be non-null and valid on dereference!"); + } + + { + TrackingVH VH(BitcastV.get()); + + BitcastV->replaceAllUsesWith(ConstantV); + EXPECT_DEATH((void)*VH, + "Tracked Value was replaced by one with an invalid type!"); + } +} + #endif // GTEST_HAS_DEATH_TEST #endif // NDEBUG @@ -341,11 +384,11 @@ TEST_F(ValueHandle, DestroyingOtherVHOnSameValueDoesntBreakIteration) { class DestroyingVH : public CallbackVH { public: - std::unique_ptr ToClear[2]; + std::unique_ptr ToClear[2]; DestroyingVH(Value *V) { - ToClear[0].reset(new WeakVH(V)); + ToClear[0].reset(new WeakTrackingVH(V)); setValPtr(V); - ToClear[1].reset(new WeakVH(V)); + ToClear[1].reset(new WeakTrackingVH(V)); } void deleted() override { ToClear[0].reset(); @@ -359,9 +402,9 @@ TEST_F(ValueHandle, DestroyingOtherVHOnSameValueDoesntBreakIteration) { }; { - WeakVH ShouldBeVisited1(BitcastV.get()); + WeakTrackingVH ShouldBeVisited1(BitcastV.get()); DestroyingVH C(BitcastV.get()); - WeakVH ShouldBeVisited2(BitcastV.get()); + WeakTrackingVH ShouldBeVisited2(BitcastV.get()); BitcastV->replaceAllUsesWith(ConstantV); EXPECT_EQ(ConstantV, static_cast(ShouldBeVisited1)); @@ -369,9 +412,9 @@ TEST_F(ValueHandle, DestroyingOtherVHOnSameValueDoesntBreakIteration) { } { - WeakVH ShouldBeVisited1(BitcastV.get()); + WeakTrackingVH ShouldBeVisited1(BitcastV.get()); DestroyingVH C(BitcastV.get()); - WeakVH ShouldBeVisited2(BitcastV.get()); + WeakTrackingVH ShouldBeVisited2(BitcastV.get()); BitcastV.reset(); EXPECT_EQ(nullptr, static_cast(ShouldBeVisited1));