Reverts commit r301424, r301425 and r301426

Commits were:

"Use WeakVH instead of WeakTrackingVH in AliasSetTracker's UnkownInsts"
"Add a new WeakVH value handle; NFC"
"Rename WeakVH to WeakTrackingVH; NFC"

The changes assumed pointers are 8 byte aligned on all architectures.

llvm-svn: 301429
This commit is contained in:
Sanjoy Das 2017-04-26 16:37:05 +00:00
parent 9eed0bee3d
commit 2cbeb00f38
40 changed files with 207 additions and 276 deletions

View File

@ -2156,9 +2156,9 @@ llvm/IR/ValueMap.h
ValueMap is a wrapper around a :ref:`DenseMap <dss_densemap>` mapping ValueMap is a wrapper around a :ref:`DenseMap <dss_densemap>` mapping
``Value*``\ s (or subclasses) to another type. When a Value is deleted or ``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 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 WeakTrackingVH. You can configure the same value, just as if the key were a WeakVH. You can configure exactly how
exactly how this happens, and what else happens on these two events, by passing this happens, and what else happens on these two events, by passing a ``Config``
a ``Config`` parameter to the ValueMap template. parameter to the ValueMap template.
.. _dss_intervalmap: .. _dss_intervalmap:

View File

@ -43,7 +43,7 @@ class AssumptionCache {
/// \brief Vector of weak value handles to calls of the @llvm.assume /// \brief Vector of weak value handles to calls of the @llvm.assume
/// intrinsic. /// intrinsic.
SmallVector<WeakTrackingVH, 4> AssumeHandles; SmallVector<WeakVH, 4> AssumeHandles;
class AffectedValueCallbackVH final : public CallbackVH { class AffectedValueCallbackVH final : public CallbackVH {
AssumptionCache *AC; AssumptionCache *AC;
@ -62,12 +62,12 @@ class AssumptionCache {
/// \brief A map of values about which an assumption might be providing /// \brief A map of values about which an assumption might be providing
/// information to the relevant set of assumptions. /// information to the relevant set of assumptions.
using AffectedValuesMap = using AffectedValuesMap =
DenseMap<AffectedValueCallbackVH, SmallVector<WeakTrackingVH, 1>, DenseMap<AffectedValueCallbackVH, SmallVector<WeakVH, 1>,
AffectedValueCallbackVH::DMI>; AffectedValueCallbackVH::DMI>;
AffectedValuesMap AffectedValues; AffectedValuesMap AffectedValues;
/// Get the vector of assumptions which affect a value from the cache. /// Get the vector of assumptions which affect a value from the cache.
SmallVector<WeakTrackingVH, 1> &getOrInsertAffectedValues(Value *V); SmallVector<WeakVH, 1> &getOrInsertAffectedValues(Value *V);
/// Copy affected values in the cache for OV to be affected values for NV. /// Copy affected values in the cache for OV to be affected values for NV.
void copyAffectedValuesInCache(Value *OV, Value *NV); void copyAffectedValuesInCache(Value *OV, Value *NV);
@ -120,20 +120,20 @@ public:
/// FIXME: We should replace this with pointee_iterator<filter_iterator<...>> /// FIXME: We should replace this with pointee_iterator<filter_iterator<...>>
/// when we can write that to filter out the null values. Then caller code /// when we can write that to filter out the null values. Then caller code
/// will become simpler. /// will become simpler.
MutableArrayRef<WeakTrackingVH> assumptions() { MutableArrayRef<WeakVH> assumptions() {
if (!Scanned) if (!Scanned)
scanFunction(); scanFunction();
return AssumeHandles; return AssumeHandles;
} }
/// \brief Access the list of assumptions which affect this value. /// \brief Access the list of assumptions which affect this value.
MutableArrayRef<WeakTrackingVH> assumptionsFor(const Value *V) { MutableArrayRef<WeakVH> assumptionsFor(const Value *V) {
if (!Scanned) if (!Scanned)
scanFunction(); scanFunction();
auto AVI = AffectedValues.find_as(const_cast<Value *>(V)); auto AVI = AffectedValues.find_as(const_cast<Value *>(V));
if (AVI == AffectedValues.end()) if (AVI == AffectedValues.end())
return MutableArrayRef<WeakTrackingVH>(); return MutableArrayRef<WeakVH>();
return AVI->second; return AVI->second;
} }

View File

@ -646,7 +646,7 @@ public:
LazyCallGraph::SCC *C = &InitialC; LazyCallGraph::SCC *C = &InitialC;
// Collect value handles for all of the indirect call sites. // Collect value handles for all of the indirect call sites.
SmallVector<WeakTrackingVH, 8> CallHandles; SmallVector<WeakVH, 8> CallHandles;
// Struct to track the counts of direct and indirect calls in each function // Struct to track the counts of direct and indirect calls in each function
// of the SCC. // of the SCC.
@ -658,7 +658,7 @@ public:
// Put value handles on all of the indirect calls and return the number of // Put value handles on all of the indirect calls and return the number of
// direct calls for each function in the SCC. // direct calls for each function in the SCC.
auto ScanSCC = [](LazyCallGraph::SCC &C, auto ScanSCC = [](LazyCallGraph::SCC &C,
SmallVectorImpl<WeakTrackingVH> &CallHandles) { SmallVectorImpl<WeakVH> &CallHandles) {
assert(CallHandles.empty() && "Must start with a clear set of handles."); assert(CallHandles.empty() && "Must start with a clear set of handles.");
SmallVector<CallCount, 4> CallCounts; SmallVector<CallCount, 4> CallCounts;
@ -671,7 +671,7 @@ public:
++Count.Direct; ++Count.Direct;
} else { } else {
++Count.Indirect; ++Count.Indirect;
CallHandles.push_back(WeakTrackingVH(&I)); CallHandles.push_back(WeakVH(&I));
} }
} }
} }
@ -699,7 +699,7 @@ public:
"Cannot have changed the size of the SCC!"); "Cannot have changed the size of the SCC!");
// Check whether any of the handles were devirtualized. // Check whether any of the handles were devirtualized.
auto IsDevirtualizedHandle = [&](WeakTrackingVH &CallH) { auto IsDevirtualizedHandle = [&](WeakVH &CallH) {
if (!CallH) if (!CallH)
return false; return false;
auto CS = CallSite(CallH); auto CS = CallSite(CallH);

View File

@ -172,7 +172,7 @@ class CallGraphNode {
public: public:
/// \brief A pair of the calling instruction (a call or invoke) /// \brief A pair of the calling instruction (a call or invoke)
/// and the call graph node being called. /// and the call graph node being called.
typedef std::pair<WeakTrackingVH, CallGraphNode *> CallRecord; typedef std::pair<WeakVH, CallGraphNode *> CallRecord;
public: public:
typedef std::vector<CallRecord> CalledFunctionsVector; typedef std::vector<CallRecord> CalledFunctionsVector;

View File

@ -80,7 +80,7 @@ private:
/// OperandValToReplace - The Value of the operand in the user instruction /// OperandValToReplace - The Value of the operand in the user instruction
/// that this IVStrideUse is representing. /// that this IVStrideUse is representing.
WeakTrackingVH OperandValToReplace; WeakVH OperandValToReplace;
/// PostIncLoops - The set of loops for which Expr has been adjusted to /// PostIncLoops - The set of loops for which Expr has been adjusted to
/// use post-inc mode. This corresponds with SCEVExpander's post-inc concept. /// use post-inc mode. This corresponds with SCEVExpander's post-inc concept.

View File

@ -235,7 +235,7 @@ class ObjectSizeOffsetEvaluator
: public InstVisitor<ObjectSizeOffsetEvaluator, SizeOffsetEvalType> { : public InstVisitor<ObjectSizeOffsetEvaluator, SizeOffsetEvalType> {
typedef IRBuilder<TargetFolder> BuilderTy; typedef IRBuilder<TargetFolder> BuilderTy;
typedef std::pair<WeakTrackingVH, WeakTrackingVH> WeakEvalType; typedef std::pair<WeakVH, WeakVH> WeakEvalType;
typedef DenseMap<const Value*, WeakEvalType> CacheMapTy; typedef DenseMap<const Value*, WeakEvalType> CacheMapTy;
typedef SmallPtrSet<const Value*, 8> PtrSetTy; typedef SmallPtrSet<const Value*, 8> PtrSetTy;

View File

@ -189,7 +189,7 @@ namespace llvm {
/// replace congruent phis with their most canonical representative. Return /// replace congruent phis with their most canonical representative. Return
/// the number of phis eliminated. /// the number of phis eliminated.
unsigned replaceCongruentIVs(Loop *L, const DominatorTree *DT, unsigned replaceCongruentIVs(Loop *L, const DominatorTree *DT,
SmallVectorImpl<WeakTrackingVH> &DeadInsts, SmallVectorImpl<WeakVH> &DeadInsts,
const TargetTransformInfo *TTI = nullptr); const TargetTransformInfo *TTI = nullptr);
/// Insert code to directly compute the specified SCEV expression into the /// Insert code to directly compute the specified SCEV expression into the

View File

@ -34,7 +34,12 @@ protected:
/// ///
/// This is to avoid having a vtable for the light-weight handle pointers. The /// This is to avoid having a vtable for the light-weight handle pointers. The
/// fully general Callback version does have a vtable. /// fully general Callback version does have a vtable.
enum HandleBaseKind { Assert, Callback, Tracking, Weak, WeakTracking }; enum HandleBaseKind {
Assert,
Callback,
Tracking,
Weak
};
ValueHandleBase(const ValueHandleBase &RHS) ValueHandleBase(const ValueHandleBase &RHS)
: ValueHandleBase(RHS.PrevPair.getInt(), RHS) {} : ValueHandleBase(RHS.PrevPair.getInt(), RHS) {}
@ -46,7 +51,7 @@ protected:
} }
private: private:
PointerIntPair<ValueHandleBase**, 3, HandleBaseKind> PrevPair; PointerIntPair<ValueHandleBase**, 2, HandleBaseKind> PrevPair;
ValueHandleBase *Next; ValueHandleBase *Next;
Value* V; Value* V;
@ -126,16 +131,19 @@ private:
void AddToUseList(); void AddToUseList();
}; };
/// \brief A nullable Value handle that is nullable. /// \brief Value handle that is nullable, but tries to track the Value.
/// ///
/// This is a value handle that points to a value, and nulls itself /// This is a value handle that tries hard to point to a Value, even across
/// out if that value is deleted. /// 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 WeakVH : public ValueHandleBase {
public: public:
WeakVH() : ValueHandleBase(Weak) {} WeakVH() : ValueHandleBase(Weak) {}
WeakVH(Value *P) : ValueHandleBase(Weak, P) {} WeakVH(Value *P) : ValueHandleBase(Weak, P) {}
WeakVH(const WeakVH &RHS) WeakVH(const WeakVH &RHS)
: ValueHandleBase(Weak, RHS) {} : ValueHandleBase(Weak, RHS) {}
WeakVH &operator=(const WeakVH &RHS) = default; WeakVH &operator=(const WeakVH &RHS) = default;
@ -162,47 +170,6 @@ template <> struct simplify_type<const WeakVH> {
static SimpleType getSimplifiedValue(const WeakVH &WVH) { return WVH; } 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 WeakTrackingVH : public ValueHandleBase {
public:
WeakTrackingVH() : ValueHandleBase(WeakTracking) {}
WeakTrackingVH(Value *P) : ValueHandleBase(WeakTracking, P) {}
WeakTrackingVH(const WeakTrackingVH &RHS)
: ValueHandleBase(WeakTracking, RHS) {}
WeakTrackingVH &operator=(const WeakTrackingVH &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 WeakTrackingVH to participate in
// dyn_cast, isa, etc.
template <> struct simplify_type<WeakTrackingVH> {
typedef Value *SimpleType;
static SimpleType getSimplifiedValue(WeakTrackingVH &WVH) { return WVH; }
};
template <> struct simplify_type<const WeakTrackingVH> {
typedef Value *SimpleType;
static SimpleType getSimplifiedValue(const WeakTrackingVH &WVH) {
return WVH;
}
};
/// \brief Value handle that asserts if the Value is deleted. /// \brief Value handle that asserts if the Value is deleted.
/// ///
/// This is a Value Handle that points to a value and asserts out if the value /// This is a Value Handle that points to a value and asserts out if the value
@ -392,8 +359,8 @@ public:
/// ///
/// Called when this->getValPtr() is destroyed, inside ~Value(), so you /// Called when this->getValPtr() is destroyed, inside ~Value(), so you
/// may call any non-virtual Value method on getValPtr(), but no subclass /// may call any non-virtual Value method on getValPtr(), but no subclass
/// methods. If WeakTrackingVH were implemented as a CallbackVH, it would use /// methods. If WeakVH were implemented as a CallbackVH, it would use this
/// this method to call setValPtr(NULL). AssertingVH would use this method to /// method to call setValPtr(NULL). AssertingVH would use this method to
/// cause an assertion failure. /// cause an assertion failure.
/// ///
/// All implementations must remove the reference from this object to the /// All implementations must remove the reference from this object to the
@ -403,8 +370,8 @@ public:
/// \brief Callback for Value RAUW. /// \brief Callback for Value RAUW.
/// ///
/// Called when this->getValPtr()->replaceAllUsesWith(new_value) is called, /// Called when this->getValPtr()->replaceAllUsesWith(new_value) is called,
/// _before_ any of the uses have actually been replaced. If WeakTrackingVH /// _before_ any of the uses have actually been replaced. If WeakVH were
/// were implemented as a CallbackVH, it would use this method to call /// implemented as a CallbackVH, it would use this method to call
/// setValPtr(new_value). AssertingVH would do nothing in this method. /// setValPtr(new_value). AssertingVH would do nothing in this method.
virtual void allUsesReplacedWith(Value *) {} virtual void allUsesReplacedWith(Value *) {}
}; };

View File

@ -167,7 +167,7 @@ private:
// foo(a + b); // foo(a + b);
// if (p2) // if (p2)
// bar(a + b); // bar(a + b);
DenseMap<const SCEV *, SmallVector<WeakTrackingVH, 2>> SeenExprs; DenseMap<const SCEV *, SmallVector<WeakVH, 2>> SeenExprs;
}; };
} // namespace llvm } // namespace llvm

View File

@ -74,7 +74,7 @@ struct ClonedCodeInfo {
/// All cloned call sites that have operand bundles attached are appended to /// All cloned call sites that have operand bundles attached are appended to
/// this vector. This vector may contain nulls or undefs if some of the /// this vector. This vector may contain nulls or undefs if some of the
/// originally inserted callsites were DCE'ed after they were cloned. /// originally inserted callsites were DCE'ed after they were cloned.
std::vector<WeakTrackingVH> OperandBundleCallSites; std::vector<WeakVH> OperandBundleCallSites;
ClonedCodeInfo() = default; ClonedCodeInfo() = default;
}; };
@ -192,7 +192,7 @@ public:
/// InlinedCalls - InlineFunction fills this in with callsites that were /// InlinedCalls - InlineFunction fills this in with callsites that were
/// inlined from the callee. This is only filled in if CG is non-null. /// inlined from the callee. This is only filled in if CG is non-null.
SmallVector<WeakTrackingVH, 8> InlinedCalls; SmallVector<WeakVH, 8> InlinedCalls;
/// All of the new call sites inlined into the caller. /// All of the new call sites inlined into the caller.
/// ///

View File

@ -46,13 +46,13 @@ public:
/// simplifyUsersOfIV - Simplify instructions that use this induction variable /// simplifyUsersOfIV - Simplify instructions that use this induction variable
/// by using ScalarEvolution to analyze the IV's recurrence. /// by using ScalarEvolution to analyze the IV's recurrence.
bool simplifyUsersOfIV(PHINode *CurrIV, ScalarEvolution *SE, DominatorTree *DT, bool simplifyUsersOfIV(PHINode *CurrIV, ScalarEvolution *SE, DominatorTree *DT,
LoopInfo *LI, SmallVectorImpl<WeakTrackingVH> &Dead, LoopInfo *LI, SmallVectorImpl<WeakVH> &Dead,
IVVisitor *V = nullptr); IVVisitor *V = nullptr);
/// SimplifyLoopIVs - Simplify users of induction variables within this /// SimplifyLoopIVs - Simplify users of induction variables within this
/// loop. This does not actually change or add IVs. /// loop. This does not actually change or add IVs.
bool simplifyLoopIVs(Loop *L, ScalarEvolution *SE, DominatorTree *DT, bool simplifyLoopIVs(Loop *L, ScalarEvolution *SE, DominatorTree *DT,
LoopInfo *LI, SmallVectorImpl<WeakTrackingVH> &Dead); LoopInfo *LI, SmallVectorImpl<WeakVH> &Dead);
} // end namespace llvm } // end namespace llvm

View File

@ -23,7 +23,7 @@ namespace llvm {
class Value; class Value;
class Instruction; class Instruction;
typedef ValueMap<const Value *, WeakTrackingVH> ValueToValueMapTy; typedef ValueMap<const Value *, WeakVH> ValueToValueMapTy;
/// This is a class that can be implemented by clients to remap types when /// This is a class that can be implemented by clients to remap types when
/// cloning constants and instructions. /// cloning constants and instructions.

View File

@ -40,8 +40,8 @@ class BoUpSLP;
struct SLPVectorizerPass : public PassInfoMixin<SLPVectorizerPass> { struct SLPVectorizerPass : public PassInfoMixin<SLPVectorizerPass> {
typedef SmallVector<StoreInst *, 8> StoreList; typedef SmallVector<StoreInst *, 8> StoreList;
typedef MapVector<Value *, StoreList> StoreListMap; typedef MapVector<Value *, StoreList> StoreListMap;
typedef SmallVector<WeakTrackingVH, 8> WeakTrackingVHList; typedef SmallVector<WeakVH, 8> WeakVHList;
typedef MapVector<Value *, WeakTrackingVHList> WeakTrackingVHListMap; typedef MapVector<Value *, WeakVHList> WeakVHListMap;
ScalarEvolution *SE = nullptr; ScalarEvolution *SE = nullptr;
TargetTransformInfo *TTI = nullptr; TargetTransformInfo *TTI = nullptr;
@ -111,7 +111,7 @@ private:
StoreListMap Stores; StoreListMap Stores;
/// The getelementptr instructions in a basic block organized by base pointer. /// The getelementptr instructions in a basic block organized by base pointer.
WeakTrackingVHListMap GEPs; WeakVHListMap GEPs;
}; };
} }

View File

@ -29,16 +29,15 @@ static cl::opt<bool>
cl::desc("Enable verification of assumption cache"), cl::desc("Enable verification of assumption cache"),
cl::init(false)); cl::init(false));
SmallVector<WeakTrackingVH, 1> & SmallVector<WeakVH, 1> &AssumptionCache::getOrInsertAffectedValues(Value *V) {
AssumptionCache::getOrInsertAffectedValues(Value *V) {
// Try using find_as first to avoid creating extra value handles just for the // Try using find_as first to avoid creating extra value handles just for the
// purpose of doing the lookup. // purpose of doing the lookup.
auto AVI = AffectedValues.find_as(V); auto AVI = AffectedValues.find_as(V);
if (AVI != AffectedValues.end()) if (AVI != AffectedValues.end())
return AVI->second; return AVI->second;
auto AVIP = AffectedValues.insert( auto AVIP = AffectedValues.insert({
{AffectedValueCallbackVH(V, this), SmallVector<WeakTrackingVH, 1>()}); AffectedValueCallbackVH(V, this), SmallVector<WeakVH, 1>()});
return AVIP.first->second; return AVIP.first->second;
} }

View File

@ -204,7 +204,7 @@ bool CGPassManager::RefreshCallGraph(const CallGraphSCC &CurSCC, CallGraph &CG,
// Get the set of call sites currently in the function. // Get the set of call sites currently in the function.
for (CallGraphNode::iterator I = CGN->begin(), E = CGN->end(); I != E; ) { for (CallGraphNode::iterator I = CGN->begin(), E = CGN->end(); I != E; ) {
// If this call site is null, then the function pass deleted the call // If this call site is null, then the function pass deleted the call
// entirely and the WeakTrackingVH nulled it out. // entirely and the WeakVH nulled it out.
if (!I->first || if (!I->first ||
// If we've already seen this call site, then the FunctionPass RAUW'd // 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 // one call with another, which resulted in two "uses" in the edge
@ -345,10 +345,10 @@ bool CGPassManager::RefreshCallGraph(const CallGraphSCC &CurSCC, CallGraph &CG,
if (NumIndirectRemoved > NumIndirectAdded && if (NumIndirectRemoved > NumIndirectAdded &&
NumDirectRemoved < NumDirectAdded) NumDirectRemoved < NumDirectAdded)
DevirtualizedCall = true; DevirtualizedCall = true;
// After scanning this function, if we still have entries in callsites, then // After scanning this function, if we still have entries in callsites, then
// they are dangling pointers. WeakTrackingVH should save us for this, so // they are dangling pointers. WeakVH should save us for this, so abort if
// abort if this happens. // this happens.
assert(CallSites.empty() && "Dangling pointers found in call sites map"); assert(CallSites.empty() && "Dangling pointers found in call sites map");
// Periodically do an explicit clear to remove tombstones when processing // Periodically do an explicit clear to remove tombstones when processing

View File

@ -1772,10 +1772,9 @@ SCEVExpander::getOrInsertCanonicalInductionVariable(const Loop *L,
/// ///
/// This does not depend on any SCEVExpander state but should be used in /// This does not depend on any SCEVExpander state but should be used in
/// the same context that SCEVExpander is used. /// the same context that SCEVExpander is used.
unsigned unsigned SCEVExpander::replaceCongruentIVs(Loop *L, const DominatorTree *DT,
SCEVExpander::replaceCongruentIVs(Loop *L, const DominatorTree *DT, SmallVectorImpl<WeakVH> &DeadInsts,
SmallVectorImpl<WeakTrackingVH> &DeadInsts, const TargetTransformInfo *TTI) {
const TargetTransformInfo *TTI) {
// Find integer phis in order of increasing width. // Find integer phis in order of increasing width.
SmallVector<PHINode*, 8> Phis; SmallVector<PHINode*, 8> Phis;
for (auto &I : *L->getHeader()) { for (auto &I : *L->getHeader()) {

View File

@ -58,7 +58,7 @@ void BitcodeReaderValueList::assignValue(Value *V, unsigned Idx) {
if (Idx >= size()) if (Idx >= size())
resize(Idx + 1); resize(Idx + 1);
WeakTrackingVH &OldV = ValuePtrs[Idx]; WeakVH &OldV = ValuePtrs[Idx];
if (!OldV) { if (!OldV) {
OldV = V; OldV = V;
return; return;

View File

@ -20,7 +20,7 @@ namespace llvm {
class Constant; class Constant;
class BitcodeReaderValueList { class BitcodeReaderValueList {
std::vector<WeakTrackingVH> ValuePtrs; std::vector<WeakVH> ValuePtrs;
/// As we resolve forward-referenced constants, we add information about them /// As we resolve forward-referenced constants, we add information about them
/// to this vector. This allows us to resolve them in bulk instead of /// to this vector. This allows us to resolve them in bulk instead of

View File

@ -2226,10 +2226,10 @@ bool CodeGenPrepare::optimizeCallInst(CallInst *CI, bool& ModifiedDT) {
ConstantInt *RetVal = ConstantInt *RetVal =
lowerObjectSizeCall(II, *DL, TLInfo, /*MustSucceed=*/true); lowerObjectSizeCall(II, *DL, TLInfo, /*MustSucceed=*/true);
// Substituting this can cause recursive simplifications, which can // Substituting this can cause recursive simplifications, which can
// invalidate our iterator. Use a WeakTrackingVH to hold onto it in case // invalidate our iterator. Use a WeakVH to hold onto it in case this
// this happens. // happens.
Value *CurValue = &*CurInstIterator; Value *CurValue = &*CurInstIterator;
WeakTrackingVH IterHandle(CurValue); WeakVH IterHandle(CurValue);
replaceAndRecursivelySimplify(CI, RetVal, TLInfo, nullptr); replaceAndRecursivelySimplify(CI, RetVal, TLInfo, nullptr);
@ -4442,9 +4442,9 @@ bool CodeGenPrepare::optimizeMemoryInst(Instruction *MemoryInst, Value *Addr,
// using it. // using it.
if (Repl->use_empty()) { if (Repl->use_empty()) {
// This can cause recursive deletion, which can invalidate our iterator. // This can cause recursive deletion, which can invalidate our iterator.
// Use a WeakTrackingVH to hold onto it in case this happens. // Use a WeakVH to hold onto it in case this happens.
Value *CurValue = &*CurInstIterator; Value *CurValue = &*CurInstIterator;
WeakTrackingVH IterHandle(CurValue); WeakVH IterHandle(CurValue);
BasicBlock *BB = CurInstIterator->getParent(); BasicBlock *BB = CurInstIterator->getParent();
RecursivelyDeleteTriviallyDeadInstructions(Repl, TLInfo); RecursivelyDeleteTriviallyDeadInstructions(Repl, TLInfo);

View File

@ -826,9 +826,7 @@ void ValueHandleBase::ValueIsDeleted(Value *V) {
Entry->operator=(DenseMapInfo<Value *>::getTombstoneKey()); Entry->operator=(DenseMapInfo<Value *>::getTombstoneKey());
break; break;
case Weak: case Weak:
case WeakTracking: // Weak 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); Entry->operator=(nullptr);
break; break;
case Callback: case Callback:
@ -876,20 +874,17 @@ void ValueHandleBase::ValueIsRAUWd(Value *Old, Value *New) {
switch (Entry->getKind()) { switch (Entry->getKind()) {
case Assert: case Assert:
case Weak: // Asserting handle does not follow RAUW implicitly.
// Asserting and Weak handles do not follow RAUW implicitly.
break; break;
case Tracking: case Tracking:
// Tracking goes to new value like a WeakTrackingVH. Note that this may // Tracking goes to new value like a WeakVH. Note that this may make it
// make it something incompatible with its templated type. We don't want // something incompatible with its templated type. We don't want to have a
// to have a virtual (or inline) interface to handle this though, so // virtual (or inline) interface to handle this though, so instead we make
// instead we make the TrackingVH accessors guarantee that a client never // the TrackingVH accessors guarantee that a client never sees this value.
// sees this value.
LLVM_FALLTHROUGH; LLVM_FALLTHROUGH;
case WeakTracking: case Weak:
// WeakTracking goes to the new value, which will unlink it from Old's // Weak goes to the new value, which will unlink it from Old's list.
// list.
Entry->operator=(New); Entry->operator=(New);
break; break;
case Callback: case Callback:
@ -906,7 +901,7 @@ void ValueHandleBase::ValueIsRAUWd(Value *Old, Value *New) {
for (Entry = pImpl->ValueHandles[Old]; Entry; Entry = Entry->Next) for (Entry = pImpl->ValueHandles[Old]; Entry; Entry = Entry->Next)
switch (Entry->getKind()) { switch (Entry->getKind()) {
case Tracking: case Tracking:
case WeakTracking: case Weak:
dbgs() << "After RAUW from " << *Old->getType() << " %" dbgs() << "After RAUW from " << *Old->getType() << " %"
<< Old->getName() << " to " << *New->getType() << " %" << Old->getName() << " to " << *New->getType() << " %"
<< New->getName() << "\n"; << New->getName() << "\n";

View File

@ -77,10 +77,9 @@ class SIAnnotateControlFlow : public FunctionPass {
void insertElse(BranchInst *Term); void insertElse(BranchInst *Term);
Value * Value *handleLoopCondition(Value *Cond, PHINode *Broken,
handleLoopCondition(Value *Cond, PHINode *Broken, llvm::Loop *L, llvm::Loop *L, BranchInst *Term,
BranchInst *Term, SmallVectorImpl<WeakVH> &LoopPhiConditions);
SmallVectorImpl<WeakTrackingVH> &LoopPhiConditions);
void handleLoop(BranchInst *Term); void handleLoop(BranchInst *Term);
@ -213,8 +212,9 @@ void SIAnnotateControlFlow::insertElse(BranchInst *Term) {
/// \brief Recursively handle the condition leading to a loop /// \brief Recursively handle the condition leading to a loop
Value *SIAnnotateControlFlow::handleLoopCondition( Value *SIAnnotateControlFlow::handleLoopCondition(
Value *Cond, PHINode *Broken, llvm::Loop *L, BranchInst *Term, Value *Cond, PHINode *Broken,
SmallVectorImpl<WeakTrackingVH> &LoopPhiConditions) { llvm::Loop *L, BranchInst *Term,
SmallVectorImpl<WeakVH> &LoopPhiConditions) {
// Only search through PHI nodes which are inside the loop. If we try this // Only search through PHI nodes which are inside the loop. If we try this
// with PHI nodes that are outside of the loop, we end up inserting new PHI // with PHI nodes that are outside of the loop, we end up inserting new PHI
@ -281,7 +281,7 @@ Value *SIAnnotateControlFlow::handleLoopCondition(
NewPhi->setIncomingValue(i, PhiArg); NewPhi->setIncomingValue(i, PhiArg);
} }
LoopPhiConditions.push_back(WeakTrackingVH(Phi)); LoopPhiConditions.push_back(WeakVH(Phi));
return Ret; return Ret;
} }
@ -323,7 +323,7 @@ void SIAnnotateControlFlow::handleLoop(BranchInst *Term) {
BasicBlock *Target = Term->getSuccessor(1); BasicBlock *Target = Term->getSuccessor(1);
PHINode *Broken = PHINode::Create(Int64, 0, "phi.broken", &Target->front()); PHINode *Broken = PHINode::Create(Int64, 0, "phi.broken", &Target->front());
SmallVector<WeakTrackingVH, 8> LoopPhiConditions; SmallVector<WeakVH, 8> LoopPhiConditions;
Value *Cond = Term->getCondition(); Value *Cond = Term->getCondition();
Term->setCondition(BoolTrue); Term->setCondition(BoolTrue);
Value *Arg = handleLoopCondition(Cond, Broken, L, Term, LoopPhiConditions); Value *Arg = handleLoopCondition(Cond, Broken, L, Term, LoopPhiConditions);
@ -333,7 +333,7 @@ void SIAnnotateControlFlow::handleLoop(BranchInst *Term) {
Term->setCondition(CallInst::Create(Loop, Arg, "", Term)); Term->setCondition(CallInst::Create(Loop, Arg, "", Term));
for (WeakTrackingVH Val : reverse(LoopPhiConditions)) { for (WeakVH Val : reverse(LoopPhiConditions)) {
if (PHINode *Cond = cast_or_null<PHINode>(Val)) if (PHINode *Cond = cast_or_null<PHINode>(Val))
eraseIfUnused(Cond); eraseIfUnused(Cond);
} }

View File

@ -128,11 +128,11 @@ createReplacementInstr(ConstantExpr *CE, Instruction *Instr) {
static bool replaceConstantExprOp(ConstantExpr *CE, Pass *P) { static bool replaceConstantExprOp(ConstantExpr *CE, Pass *P) {
do { do {
SmallVector<WeakTrackingVH, 8> WUsers(CE->user_begin(), CE->user_end()); SmallVector<WeakVH,8> WUsers(CE->user_begin(), CE->user_end());
std::sort(WUsers.begin(), WUsers.end()); std::sort(WUsers.begin(), WUsers.end());
WUsers.erase(std::unique(WUsers.begin(), WUsers.end()), WUsers.end()); WUsers.erase(std::unique(WUsers.begin(), WUsers.end()), WUsers.end());
while (!WUsers.empty()) while (!WUsers.empty())
if (WeakTrackingVH WU = WUsers.pop_back_val()) { if (WeakVH WU = WUsers.pop_back_val()) {
if (PHINode *PN = dyn_cast<PHINode>(WU)) { if (PHINode *PN = dyn_cast<PHINode>(WU)) {
for (int I = 0, E = PN->getNumIncomingValues(); I < E; ++I) for (int I = 0, E = PN->getNumIncomingValues(); I < E; ++I)
if (PN->getIncomingValue(I) == CE) { if (PN->getIncomingValue(I) == CE) {
@ -159,12 +159,12 @@ static bool replaceConstantExprOp(ConstantExpr *CE, Pass *P) {
} }
static bool rewriteNonInstructionUses(GlobalVariable *GV, Pass *P) { static bool rewriteNonInstructionUses(GlobalVariable *GV, Pass *P) {
SmallVector<WeakTrackingVH, 8> WUsers; SmallVector<WeakVH,8> WUsers;
for (User *U : GV->users()) for (User *U : GV->users())
if (!isa<Instruction>(U)) if (!isa<Instruction>(U))
WUsers.push_back(WeakTrackingVH(U)); WUsers.push_back(WeakVH(U));
while (!WUsers.empty()) while (!WUsers.empty())
if (WeakTrackingVH WU = WUsers.pop_back_val()) { if (WeakVH WU = WUsers.pop_back_val()) {
ConstantExpr *CE = dyn_cast<ConstantExpr>(WU); ConstantExpr *CE = dyn_cast<ConstantExpr>(WU);
if (!CE || !replaceConstantExprOp(CE, P)) if (!CE || !replaceConstantExprOp(CE, P))
return false; return false;

View File

@ -239,7 +239,7 @@ static bool CleanupConstantGlobalUsers(Value *V, Constant *Init,
// we delete a constant array, we may also be holding pointer to one of its // 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 // elements (or an element of one of its elements if we're dealing with an
// array of arrays) in the worklist. // array of arrays) in the worklist.
SmallVector<WeakTrackingVH, 8> WorkList(V->user_begin(), V->user_end()); SmallVector<WeakVH, 8> WorkList(V->user_begin(), V->user_end());
while (!WorkList.empty()) { while (!WorkList.empty()) {
Value *UV = WorkList.pop_back_val(); Value *UV = WorkList.pop_back_val();
if (!UV) if (!UV)

View File

@ -207,11 +207,11 @@ private:
/// A work queue of functions that may have been modified and should be /// A work queue of functions that may have been modified and should be
/// analyzed again. /// analyzed again.
std::vector<WeakTrackingVH> Deferred; std::vector<WeakVH> Deferred;
/// Checks the rules of order relation introduced among functions set. /// Checks the rules of order relation introduced among functions set.
/// Returns true, if sanity check has been passed, and false if failed. /// Returns true, if sanity check has been passed, and false if failed.
bool doSanityCheck(std::vector<WeakTrackingVH> &Worklist); bool doSanityCheck(std::vector<WeakVH> &Worklist);
/// Insert a ComparableFunction into the FnTree, or merge it away if it's /// Insert a ComparableFunction into the FnTree, or merge it away if it's
/// equal to one that's already present. /// equal to one that's already present.
@ -283,7 +283,7 @@ ModulePass *llvm::createMergeFunctionsPass() {
return new MergeFunctions(); return new MergeFunctions();
} }
bool MergeFunctions::doSanityCheck(std::vector<WeakTrackingVH> &Worklist) { bool MergeFunctions::doSanityCheck(std::vector<WeakVH> &Worklist) {
if (const unsigned Max = NumFunctionsForSanityCheck) { if (const unsigned Max = NumFunctionsForSanityCheck) {
unsigned TripleNumber = 0; unsigned TripleNumber = 0;
bool Valid = true; bool Valid = true;
@ -291,12 +291,10 @@ bool MergeFunctions::doSanityCheck(std::vector<WeakTrackingVH> &Worklist) {
dbgs() << "MERGEFUNC-SANITY: Started for first " << Max << " functions.\n"; dbgs() << "MERGEFUNC-SANITY: Started for first " << Max << " functions.\n";
unsigned i = 0; unsigned i = 0;
for (std::vector<WeakTrackingVH>::iterator I = Worklist.begin(), for (std::vector<WeakVH>::iterator I = Worklist.begin(), E = Worklist.end();
E = Worklist.end();
I != E && i < Max; ++I, ++i) { I != E && i < Max; ++I, ++i) {
unsigned j = i; unsigned j = i;
for (std::vector<WeakTrackingVH>::iterator J = I; J != E && j < Max; for (std::vector<WeakVH>::iterator J = I; J != E && j < Max; ++J, ++j) {
++J, ++j) {
Function *F1 = cast<Function>(*I); Function *F1 = cast<Function>(*I);
Function *F2 = cast<Function>(*J); Function *F2 = cast<Function>(*J);
int Res1 = FunctionComparator(F1, F2, &GlobalNumbers).compare(); int Res1 = FunctionComparator(F1, F2, &GlobalNumbers).compare();
@ -314,7 +312,7 @@ bool MergeFunctions::doSanityCheck(std::vector<WeakTrackingVH> &Worklist) {
continue; continue;
unsigned k = j; unsigned k = j;
for (std::vector<WeakTrackingVH>::iterator K = J; K != E && k < Max; for (std::vector<WeakVH>::iterator K = J; K != E && k < Max;
++k, ++K, ++TripleNumber) { ++k, ++K, ++TripleNumber) {
if (K == J) if (K == J)
continue; continue;
@ -383,12 +381,12 @@ bool MergeFunctions::runOnModule(Module &M) {
// consider merging it. Otherwise it is dropped and never considered again. // consider merging it. Otherwise it is dropped and never considered again.
if ((I != S && std::prev(I)->first == I->first) || if ((I != S && std::prev(I)->first == I->first) ||
(std::next(I) != IE && std::next(I)->first == I->first) ) { (std::next(I) != IE && std::next(I)->first == I->first) ) {
Deferred.push_back(WeakTrackingVH(I->second)); Deferred.push_back(WeakVH(I->second));
} }
} }
do { do {
std::vector<WeakTrackingVH> Worklist; std::vector<WeakVH> Worklist;
Deferred.swap(Worklist); Deferred.swap(Worklist);
DEBUG(doSanityCheck(Worklist)); DEBUG(doSanityCheck(Worklist));
@ -397,7 +395,7 @@ bool MergeFunctions::runOnModule(Module &M) {
DEBUG(dbgs() << "size of worklist: " << Worklist.size() << '\n'); DEBUG(dbgs() << "size of worklist: " << Worklist.size() << '\n');
// Insert functions and merge them. // Insert functions and merge them.
for (WeakTrackingVH &I : Worklist) { for (WeakVH &I : Worklist) {
if (!I) if (!I)
continue; continue;
Function *F = cast<Function>(I); Function *F = cast<Function>(I);

View File

@ -1948,9 +1948,9 @@ static bool isNeverEqualToUnescapedAlloc(Value *V, const TargetLibraryInfo *TLI,
return isAllocLikeFn(V, TLI) && V != AI; return isAllocLikeFn(V, TLI) && V != AI;
} }
static bool isAllocSiteRemovable(Instruction *AI, static bool
SmallVectorImpl<WeakTrackingVH> &Users, isAllocSiteRemovable(Instruction *AI, SmallVectorImpl<WeakVH> &Users,
const TargetLibraryInfo *TLI) { const TargetLibraryInfo *TLI) {
SmallVector<Instruction*, 4> Worklist; SmallVector<Instruction*, 4> Worklist;
Worklist.push_back(AI); Worklist.push_back(AI);
@ -2034,7 +2034,7 @@ Instruction *InstCombiner::visitAllocSite(Instruction &MI) {
// If we have a malloc call which is only used in any amount of comparisons // 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 // to null and free calls, delete the calls and replace the comparisons with
// true or false as appropriate. // true or false as appropriate.
SmallVector<WeakTrackingVH, 64> Users; SmallVector<WeakVH, 64> Users;
if (isAllocSiteRemovable(&MI, Users, &TLI)) { if (isAllocSiteRemovable(&MI, Users, &TLI)) {
for (unsigned i = 0, e = Users.size(); i != e; ++i) { for (unsigned i = 0, e = Users.size(); i != e; ++i) {
// Lowering all @llvm.objectsize calls first because they may // Lowering all @llvm.objectsize calls first because they may

View File

@ -97,7 +97,7 @@ class IndVarSimplify {
TargetLibraryInfo *TLI; TargetLibraryInfo *TLI;
const TargetTransformInfo *TTI; const TargetTransformInfo *TTI;
SmallVector<WeakTrackingVH, 16> DeadInsts; SmallVector<WeakVH, 16> DeadInsts;
bool Changed = false; bool Changed = false;
bool isValidRewrite(Value *FromVal, Value *ToVal); bool isValidRewrite(Value *FromVal, Value *ToVal);
@ -415,8 +415,8 @@ void IndVarSimplify::handleFloatingPointIV(Loop *L, PHINode *PN) {
Compare->getName()); Compare->getName());
// In the following deletions, PN may become dead and may be deleted. // In the following deletions, PN may become dead and may be deleted.
// Use a WeakTrackingVH to observe whether this happens. // Use a WeakVH to observe whether this happens.
WeakTrackingVH WeakPH = PN; WeakVH WeakPH = PN;
// Delete the old floating point exit comparison. The branch starts using the // Delete the old floating point exit comparison. The branch starts using the
// new comparison. // new comparison.
@ -451,7 +451,7 @@ void IndVarSimplify::rewriteNonIntegerIVs(Loop *L) {
// //
BasicBlock *Header = L->getHeader(); BasicBlock *Header = L->getHeader();
SmallVector<WeakTrackingVH, 8> PHIs; SmallVector<WeakVH, 8> PHIs;
for (BasicBlock::iterator I = Header->begin(); for (BasicBlock::iterator I = Header->begin();
PHINode *PN = dyn_cast<PHINode>(I); ++I) PHINode *PN = dyn_cast<PHINode>(I); ++I)
PHIs.push_back(PN); PHIs.push_back(PN);
@ -901,7 +901,7 @@ class WidenIV {
PHINode *WidePhi; PHINode *WidePhi;
Instruction *WideInc; Instruction *WideInc;
const SCEV *WideIncExpr; const SCEV *WideIncExpr;
SmallVectorImpl<WeakTrackingVH> &DeadInsts; SmallVectorImpl<WeakVH> &DeadInsts;
SmallPtrSet<Instruction *,16> Widened; SmallPtrSet<Instruction *,16> Widened;
SmallVector<NarrowIVDefUse, 8> NarrowIVUsers; SmallVector<NarrowIVDefUse, 8> NarrowIVUsers;
@ -941,13 +941,20 @@ class WidenIV {
} }
public: public:
WidenIV(const WideIVInfo &WI, LoopInfo *LInfo, ScalarEvolution *SEv, WidenIV(const WideIVInfo &WI, LoopInfo *LInfo,
DominatorTree *DTree, SmallVectorImpl<WeakTrackingVH> &DI, ScalarEvolution *SEv, DominatorTree *DTree,
bool HasGuards) SmallVectorImpl<WeakVH> &DI, bool HasGuards) :
: OrigPhi(WI.NarrowIV), WideType(WI.WidestNativeType), LI(LInfo), OrigPhi(WI.NarrowIV),
L(LI->getLoopFor(OrigPhi->getParent())), SE(SEv), DT(DTree), WideType(WI.WidestNativeType),
HasGuards(HasGuards), WidePhi(nullptr), WideInc(nullptr), LI(LInfo),
WideIncExpr(nullptr), DeadInsts(DI) { L(LI->getLoopFor(OrigPhi->getParent())),
SE(SEv),
DT(DTree),
HasGuards(HasGuards),
WidePhi(nullptr),
WideInc(nullptr),
WideIncExpr(nullptr),
DeadInsts(DI) {
assert(L->getHeader() == OrigPhi->getParent() && "Phi must be an IV"); assert(L->getHeader() == OrigPhi->getParent() && "Phi must be an IV");
ExtendKindMap[OrigPhi] = WI.IsSigned ? SignExtended : ZeroExtended; ExtendKindMap[OrigPhi] = WI.IsSigned ? SignExtended : ZeroExtended;
} }

View File

@ -499,7 +499,7 @@ bool LoopIdiomRecognize::runOnLoopBlock(
Instruction *Inst = &*I++; Instruction *Inst = &*I++;
// Look for memset instructions, which may be optimized to a larger memset. // Look for memset instructions, which may be optimized to a larger memset.
if (MemSetInst *MSI = dyn_cast<MemSetInst>(Inst)) { if (MemSetInst *MSI = dyn_cast<MemSetInst>(Inst)) {
WeakTrackingVH InstPtr(&*I); WeakVH InstPtr(&*I);
if (!processLoopMemSet(MSI, BECount)) if (!processLoopMemSet(MSI, BECount))
continue; continue;
MadeChange = true; MadeChange = true;

View File

@ -40,7 +40,7 @@ static bool simplifyLoopCFG(Loop &L, DominatorTree &DT, LoopInfo &LI) {
bool Changed = false; bool Changed = false;
// Copy blocks into a temporary array to avoid iterator invalidation issues // Copy blocks into a temporary array to avoid iterator invalidation issues
// as we remove them. // as we remove them.
SmallVector<WeakTrackingVH, 16> Blocks(L.blocks()); SmallVector<WeakVH, 16> Blocks(L.blocks());
for (auto &Block : Blocks) { for (auto &Block : Blocks) {
// Attempt to merge blocks in the trivial case. Don't modify blocks which // Attempt to merge blocks in the trivial case. Don't modify blocks which

View File

@ -900,7 +900,7 @@ static bool isHighCostExpansion(const SCEV *S,
/// If any of the instructions is the specified set are trivially dead, delete /// If any of the instructions is the specified set are trivially dead, delete
/// them and see if this makes any of their operands subsequently dead. /// them and see if this makes any of their operands subsequently dead.
static bool static bool
DeleteTriviallyDeadInstructions(SmallVectorImpl<WeakTrackingVH> &DeadInsts) { DeleteTriviallyDeadInstructions(SmallVectorImpl<WeakVH> &DeadInsts) {
bool Changed = false; bool Changed = false;
while (!DeadInsts.empty()) { while (!DeadInsts.empty()) {
@ -1845,7 +1845,7 @@ class LSRInstance {
void FinalizeChain(IVChain &Chain); void FinalizeChain(IVChain &Chain);
void CollectChains(); void CollectChains();
void GenerateIVChain(const IVChain &Chain, SCEVExpander &Rewriter, void GenerateIVChain(const IVChain &Chain, SCEVExpander &Rewriter,
SmallVectorImpl<WeakTrackingVH> &DeadInsts); SmallVectorImpl<WeakVH> &DeadInsts);
void CollectInterestingTypesAndFactors(); void CollectInterestingTypesAndFactors();
void CollectFixupsAndInitialFormulae(); void CollectFixupsAndInitialFormulae();
@ -1920,15 +1920,19 @@ class LSRInstance {
const LSRUse &LU, const LSRUse &LU,
SCEVExpander &Rewriter) const; SCEVExpander &Rewriter) const;
Value *Expand(const LSRUse &LU, const LSRFixup &LF, const Formula &F, Value *Expand(const LSRUse &LU, const LSRFixup &LF,
BasicBlock::iterator IP, SCEVExpander &Rewriter, const Formula &F,
SmallVectorImpl<WeakTrackingVH> &DeadInsts) const; BasicBlock::iterator IP,
SCEVExpander &Rewriter,
SmallVectorImpl<WeakVH> &DeadInsts) const;
void RewriteForPHI(PHINode *PN, const LSRUse &LU, const LSRFixup &LF, void RewriteForPHI(PHINode *PN, const LSRUse &LU, const LSRFixup &LF,
const Formula &F, SCEVExpander &Rewriter, const Formula &F,
SmallVectorImpl<WeakTrackingVH> &DeadInsts) const; SCEVExpander &Rewriter,
void Rewrite(const LSRUse &LU, const LSRFixup &LF, const Formula &F, SmallVectorImpl<WeakVH> &DeadInsts) const;
void Rewrite(const LSRUse &LU, const LSRFixup &LF,
const Formula &F,
SCEVExpander &Rewriter, SCEVExpander &Rewriter,
SmallVectorImpl<WeakTrackingVH> &DeadInsts) const; SmallVectorImpl<WeakVH> &DeadInsts) const;
void ImplementSolution(const SmallVectorImpl<const Formula *> &Solution); void ImplementSolution(const SmallVectorImpl<const Formula *> &Solution);
public: public:
@ -3010,7 +3014,7 @@ static bool canFoldIVIncExpr(const SCEV *IncExpr, Instruction *UserInst,
/// Generate an add or subtract for each IVInc in a chain to materialize the IV /// 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. /// user's operand from the previous IV user's operand.
void LSRInstance::GenerateIVChain(const IVChain &Chain, SCEVExpander &Rewriter, void LSRInstance::GenerateIVChain(const IVChain &Chain, SCEVExpander &Rewriter,
SmallVectorImpl<WeakTrackingVH> &DeadInsts) { SmallVectorImpl<WeakVH> &DeadInsts) {
// Find the new IVOperand for the head of the chain. It may have been replaced // Find the new IVOperand for the head of the chain. It may have been replaced
// by LSR. // by LSR.
const IVInc &Head = Chain.Incs[0]; const IVInc &Head = Chain.Incs[0];
@ -4755,10 +4759,12 @@ LSRInstance::AdjustInsertPositionForExpand(BasicBlock::iterator LowestIP,
/// Emit instructions for the leading candidate expression for this LSRUse (this /// Emit instructions for the leading candidate expression for this LSRUse (this
/// is called "expanding"). /// is called "expanding").
Value *LSRInstance::Expand(const LSRUse &LU, const LSRFixup &LF, Value *LSRInstance::Expand(const LSRUse &LU,
const Formula &F, BasicBlock::iterator IP, const LSRFixup &LF,
const Formula &F,
BasicBlock::iterator IP,
SCEVExpander &Rewriter, SCEVExpander &Rewriter,
SmallVectorImpl<WeakTrackingVH> &DeadInsts) const { SmallVectorImpl<WeakVH> &DeadInsts) const {
if (LU.RigidFormula) if (LU.RigidFormula)
return LF.OperandValToReplace; return LF.OperandValToReplace;
@ -4933,9 +4939,12 @@ Value *LSRInstance::Expand(const LSRUse &LU, const LSRFixup &LF,
/// Helper for Rewrite. PHI nodes are special because the use of their operands /// Helper for Rewrite. PHI nodes are special because the use of their operands
/// effectively happens in their predecessor blocks, so the expression may need /// effectively happens in their predecessor blocks, so the expression may need
/// to be expanded in multiple places. /// to be expanded in multiple places.
void LSRInstance::RewriteForPHI( void LSRInstance::RewriteForPHI(PHINode *PN,
PHINode *PN, const LSRUse &LU, const LSRFixup &LF, const Formula &F, const LSRUse &LU,
SCEVExpander &Rewriter, SmallVectorImpl<WeakTrackingVH> &DeadInsts) const { const LSRFixup &LF,
const Formula &F,
SCEVExpander &Rewriter,
SmallVectorImpl<WeakVH> &DeadInsts) const {
DenseMap<BasicBlock *, Value *> Inserted; DenseMap<BasicBlock *, Value *> Inserted;
for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i)
if (PN->getIncomingValue(i) == LF.OperandValToReplace) { if (PN->getIncomingValue(i) == LF.OperandValToReplace) {
@ -5007,9 +5016,11 @@ void LSRInstance::RewriteForPHI(
/// Emit instructions for the leading candidate expression for this LSRUse (this /// Emit instructions for the leading candidate expression for this LSRUse (this
/// is called "expanding"), and update the UserInst to reference the newly /// is called "expanding"), and update the UserInst to reference the newly
/// expanded value. /// expanded value.
void LSRInstance::Rewrite(const LSRUse &LU, const LSRFixup &LF, void LSRInstance::Rewrite(const LSRUse &LU,
const Formula &F, SCEVExpander &Rewriter, const LSRFixup &LF,
SmallVectorImpl<WeakTrackingVH> &DeadInsts) const { const Formula &F,
SCEVExpander &Rewriter,
SmallVectorImpl<WeakVH> &DeadInsts) const {
// First, find an insertion point that dominates UserInst. For PHI nodes, // First, find an insertion point that dominates UserInst. For PHI nodes,
// find the nearest block which dominates all the relevant uses. // find the nearest block which dominates all the relevant uses.
if (PHINode *PN = dyn_cast<PHINode>(LF.UserInst)) { if (PHINode *PN = dyn_cast<PHINode>(LF.UserInst)) {
@ -5047,7 +5058,7 @@ void LSRInstance::ImplementSolution(
const SmallVectorImpl<const Formula *> &Solution) { const SmallVectorImpl<const Formula *> &Solution) {
// Keep track of instructions we may have made dead, so that // Keep track of instructions we may have made dead, so that
// we can remove them after we are done working. // we can remove them after we are done working.
SmallVector<WeakTrackingVH, 16> DeadInsts; SmallVector<WeakVH, 16> DeadInsts;
SCEVExpander Rewriter(SE, L->getHeader()->getModule()->getDataLayout(), SCEVExpander Rewriter(SE, L->getHeader()->getModule()->getDataLayout(),
"lsr"); "lsr");
@ -5297,7 +5308,7 @@ static bool ReduceLoopStrength(Loop *L, IVUsers &IU, ScalarEvolution &SE,
// Remove any extra phis created by processing inner loops. // Remove any extra phis created by processing inner loops.
Changed |= DeleteDeadPHIs(L->getHeader()); Changed |= DeleteDeadPHIs(L->getHeader());
if (EnablePhiElim && L->isLoopSimplifyForm()) { if (EnablePhiElim && L->isLoopSimplifyForm()) {
SmallVector<WeakTrackingVH, 16> DeadInsts; SmallVector<WeakVH, 16> DeadInsts;
const DataLayout &DL = L->getHeader()->getModule()->getDataLayout(); const DataLayout &DL = L->getHeader()->getModule()->getDataLayout();
SCEVExpander Rewriter(SE, DL, "lsr"); SCEVExpander Rewriter(SE, DL, "lsr");
#ifndef NDEBUG #ifndef NDEBUG

View File

@ -1231,11 +1231,11 @@ void LoopUnswitch::UnswitchNontrivialCondition(Value *LIC, Constant *Val,
LoopProcessWorklist.push_back(NewLoop); LoopProcessWorklist.push_back(NewLoop);
redoLoop = true; redoLoop = true;
// Keep a WeakTrackingVH holding onto LIC. If the first call to // Keep a WeakVH holding onto LIC. If the first call to RewriteLoopBody
// RewriteLoopBody deletes the instruction (for example by simplifying a PHI // deletes the instruction (for example by simplifying a PHI that feeds into
// that feeds into the condition that we're unswitching on), we don't rewrite // the condition that we're unswitching on), we don't rewrite the second
// the second iteration. // iteration.
WeakTrackingVH LICHandle(LIC); WeakVH LICHandle(LIC);
// Now we rewrite the original code to know that the condition is true and the // Now we rewrite the original code to know that the condition is true and the
// new code to know that the condition is false. // new code to know that the condition is false.

View File

@ -211,15 +211,15 @@ bool NaryReassociatePass::doOneIteration(Function &F) {
Changed = true; Changed = true;
SE->forgetValue(&*I); SE->forgetValue(&*I);
I->replaceAllUsesWith(NewI); I->replaceAllUsesWith(NewI);
// If SeenExprs constains I's WeakTrackingVH, that entry will be // If SeenExprs constains I's WeakVH, that entry will be replaced with
// replaced with nullptr. // nullptr.
RecursivelyDeleteTriviallyDeadInstructions(&*I, TLI); RecursivelyDeleteTriviallyDeadInstructions(&*I, TLI);
I = NewI->getIterator(); I = NewI->getIterator();
} }
// Add the rewritten instruction to SeenExprs; the original instruction // Add the rewritten instruction to SeenExprs; the original instruction
// is deleted. // is deleted.
const SCEV *NewSCEV = SE->getSCEV(&*I); const SCEV *NewSCEV = SE->getSCEV(&*I);
SeenExprs[NewSCEV].push_back(WeakTrackingVH(&*I)); SeenExprs[NewSCEV].push_back(WeakVH(&*I));
// Ideally, NewSCEV should equal OldSCEV because tryReassociate(I) // Ideally, NewSCEV should equal OldSCEV because tryReassociate(I)
// is equivalent to I. However, ScalarEvolution::getSCEV may // is equivalent to I. However, ScalarEvolution::getSCEV may
// weaken nsw causing NewSCEV not to equal OldSCEV. For example, suppose // weaken nsw causing NewSCEV not to equal OldSCEV. For example, suppose
@ -239,7 +239,7 @@ bool NaryReassociatePass::doOneIteration(Function &F) {
// //
// This improvement is exercised in @reassociate_gep_nsw in nary-gep.ll. // This improvement is exercised in @reassociate_gep_nsw in nary-gep.ll.
if (NewSCEV != OldSCEV) if (NewSCEV != OldSCEV)
SeenExprs[OldSCEV].push_back(WeakTrackingVH(&*I)); SeenExprs[OldSCEV].push_back(WeakVH(&*I));
} }
} }
} }
@ -494,8 +494,8 @@ NaryReassociatePass::findClosestMatchingDominator(const SCEV *CandidateExpr,
// future instruction either. Therefore, we pop it out of the stack. This // future instruction either. Therefore, we pop it out of the stack. This
// optimization makes the algorithm O(n). // optimization makes the algorithm O(n).
while (!Candidates.empty()) { while (!Candidates.empty()) {
// Candidates stores WeakTrackingVHs, so a candidate can be nullptr if it's // Candidates stores WeakVHs, so a candidate can be nullptr if it's removed
// removed during rewriting. // during rewriting.
if (Value *Candidate = Candidates.back()) { if (Value *Candidate = Candidates.back()) {
Instruction *CandidateInstruction = cast<Instruction>(Candidate); Instruction *CandidateInstruction = cast<Instruction>(Candidate);
if (DT->dominates(CandidateInstruction, Dominatee)) if (DT->dominates(CandidateInstruction, Dominatee))

View File

@ -982,7 +982,7 @@ static unsigned FindInOperandList(SmallVectorImpl<ValueEntry> &Ops, unsigned i,
/// Emit a tree of add instructions, summing Ops together /// Emit a tree of add instructions, summing Ops together
/// and returning the result. Insert the tree before I. /// and returning the result. Insert the tree before I.
static Value *EmitAddTreeOfValues(Instruction *I, static Value *EmitAddTreeOfValues(Instruction *I,
SmallVectorImpl<WeakTrackingVH> &Ops) { SmallVectorImpl<WeakVH> &Ops){
if (Ops.size() == 1) return Ops.back(); if (Ops.size() == 1) return Ops.back();
Value *V1 = Ops.back(); Value *V1 = Ops.back();
@ -1559,7 +1559,7 @@ Value *ReassociatePass::OptimizeAdd(Instruction *I,
? BinaryOperator::CreateAdd(MaxOccVal, MaxOccVal) ? BinaryOperator::CreateAdd(MaxOccVal, MaxOccVal)
: BinaryOperator::CreateFAdd(MaxOccVal, MaxOccVal); : BinaryOperator::CreateFAdd(MaxOccVal, MaxOccVal);
SmallVector<WeakTrackingVH, 4> NewMulOps; SmallVector<WeakVH, 4> NewMulOps;
for (unsigned i = 0; i != Ops.size(); ++i) { for (unsigned i = 0; i != Ops.size(); ++i) {
// Only try to remove factors from expressions we're allowed to. // Only try to remove factors from expressions we're allowed to.
BinaryOperator *BOp = BinaryOperator *BOp =

View File

@ -78,8 +78,8 @@ void llvm::FoldSingleEntryPHINodes(BasicBlock *BB,
bool llvm::DeleteDeadPHIs(BasicBlock *BB, const TargetLibraryInfo *TLI) { bool llvm::DeleteDeadPHIs(BasicBlock *BB, const TargetLibraryInfo *TLI) {
// Recursively deleting a PHI may cause multiple PHIs to be deleted // Recursively deleting a PHI may cause multiple PHIs to be deleted
// or RAUW'd undef, so use an array of WeakTrackingVH for the PHIs to delete. // or RAUW'd undef, so use an array of WeakVH for the PHIs to delete.
SmallVector<WeakTrackingVH, 8> PHIs; SmallVector<WeakVH, 8> PHIs;
for (BasicBlock::iterator I = BB->begin(); for (BasicBlock::iterator I = BB->begin();
PHINode *PN = dyn_cast<PHINode>(I); ++I) PHINode *PN = dyn_cast<PHINode>(I); ++I)
PHIs.push_back(PN); PHIs.push_back(PN);

View File

@ -245,7 +245,7 @@ namespace {
void PruningFunctionCloner::CloneBlock(const BasicBlock *BB, void PruningFunctionCloner::CloneBlock(const BasicBlock *BB,
BasicBlock::const_iterator StartingInst, BasicBlock::const_iterator StartingInst,
std::vector<const BasicBlock*> &ToClone){ std::vector<const BasicBlock*> &ToClone){
WeakTrackingVH &BBEntry = VMap[BB]; WeakVH &BBEntry = VMap[BB];
// Have we already cloned this block? // Have we already cloned this block?
if (BBEntry) return; if (BBEntry) return;
@ -547,7 +547,7 @@ void llvm::CloneAndPruneIntoFromInst(Function *NewFunc, const Function *OldFunc,
// Make a second pass over the PHINodes now that all of them have been // 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 // remapped into the new function, simplifying the PHINode and performing any
// recursive simplifications exposed. This will transparently update the // recursive simplifications exposed. This will transparently update the
// WeakTrackingVH in the VMap. Notably, we rely on that so that if we coalesce // WeakVH 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 // 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 // mapping will just map us to the new node (which may not even be a PHI
// node). // node).

View File

@ -561,7 +561,7 @@ void llvm::RemovePredecessorAndSimplify(BasicBlock *BB, BasicBlock *Pred) {
// that can be removed. // that can be removed.
BB->removePredecessor(Pred, true); BB->removePredecessor(Pred, true);
WeakTrackingVH PhiIt = &BB->front(); WeakVH PhiIt = &BB->front();
while (PHINode *PN = dyn_cast<PHINode>(PhiIt)) { while (PHINode *PN = dyn_cast<PHINode>(PhiIt)) {
PhiIt = &*++BasicBlock::iterator(cast<Instruction>(PhiIt)); PhiIt = &*++BasicBlock::iterator(cast<Instruction>(PhiIt));
Value *OldPhiIt = PhiIt; Value *OldPhiIt = PhiIt;
@ -1519,7 +1519,7 @@ BasicBlock *llvm::changeToInvokeAndSplitBasicBlock(CallInst *CI,
II->setAttributes(CI->getAttributes()); II->setAttributes(CI->getAttributes());
// Make sure that anything using the call now uses the invoke! This also // Make sure that anything using the call now uses the invoke! This also
// updates the CallGraph if present, because it uses a WeakTrackingVH. // updates the CallGraph if present, because it uses a WeakVH.
CI->replaceAllUsesWith(II); CI->replaceAllUsesWith(II);
// Delete the original call // Delete the original call

View File

@ -757,7 +757,7 @@ bool llvm::UnrollLoop(Loop *L, unsigned Count, unsigned TripCount, bool Force,
// Simplify any new induction variables in the partially unrolled loop. // Simplify any new induction variables in the partially unrolled loop.
if (SE && !CompletelyUnroll && Count > 1) { if (SE && !CompletelyUnroll && Count > 1) {
SmallVector<WeakTrackingVH, 16> DeadInsts; SmallVector<WeakVH, 16> DeadInsts;
simplifyLoopIVs(L, SE, DT, LI, DeadInsts); simplifyLoopIVs(L, SE, DT, LI, DeadInsts);
// Aggressively clean up dead instructions that simplifyLoopIVs already // Aggressively clean up dead instructions that simplifyLoopIVs already

View File

@ -51,13 +51,13 @@ namespace {
ScalarEvolution *SE; ScalarEvolution *SE;
DominatorTree *DT; DominatorTree *DT;
SmallVectorImpl<WeakTrackingVH> &DeadInsts; SmallVectorImpl<WeakVH> &DeadInsts;
bool Changed; bool Changed;
public: public:
SimplifyIndvar(Loop *Loop, ScalarEvolution *SE, DominatorTree *DT, SimplifyIndvar(Loop *Loop, ScalarEvolution *SE, DominatorTree *DT,
LoopInfo *LI, SmallVectorImpl<WeakTrackingVH> &Dead) LoopInfo *LI,SmallVectorImpl<WeakVH> &Dead)
: L(Loop), LI(LI), SE(SE), DT(DT), DeadInsts(Dead), Changed(false) { : L(Loop), LI(LI), SE(SE), DT(DT), DeadInsts(Dead), Changed(false) {
assert(LI && "IV simplification requires LoopInfo"); assert(LI && "IV simplification requires LoopInfo");
} }
@ -701,7 +701,7 @@ void IVVisitor::anchor() { }
/// Simplify instructions that use this induction variable /// Simplify instructions that use this induction variable
/// by using ScalarEvolution to analyze the IV's recurrence. /// by using ScalarEvolution to analyze the IV's recurrence.
bool simplifyUsersOfIV(PHINode *CurrIV, ScalarEvolution *SE, DominatorTree *DT, bool simplifyUsersOfIV(PHINode *CurrIV, ScalarEvolution *SE, DominatorTree *DT,
LoopInfo *LI, SmallVectorImpl<WeakTrackingVH> &Dead, LoopInfo *LI, SmallVectorImpl<WeakVH> &Dead,
IVVisitor *V) { IVVisitor *V) {
SimplifyIndvar SIV(LI->getLoopFor(CurrIV->getParent()), SE, DT, LI, Dead); SimplifyIndvar SIV(LI->getLoopFor(CurrIV->getParent()), SE, DT, LI, Dead);
SIV.simplifyUsers(CurrIV, V); SIV.simplifyUsers(CurrIV, V);
@ -711,7 +711,7 @@ bool simplifyUsersOfIV(PHINode *CurrIV, ScalarEvolution *SE, DominatorTree *DT,
/// Simplify users of induction variables within this /// Simplify users of induction variables within this
/// loop. This does not actually change or add IVs. /// loop. This does not actually change or add IVs.
bool simplifyLoopIVs(Loop *L, ScalarEvolution *SE, DominatorTree *DT, bool simplifyLoopIVs(Loop *L, ScalarEvolution *SE, DominatorTree *DT,
LoopInfo *LI, SmallVectorImpl<WeakTrackingVH> &Dead) { LoopInfo *LI, SmallVectorImpl<WeakVH> &Dead) {
bool Changed = false; bool Changed = false;
for (BasicBlock::iterator I = L->getHeader()->begin(); isa<PHINode>(I); ++I) { for (BasicBlock::iterator I = L->getHeader()->begin(); isa<PHINode>(I); ++I) {
Changed |= simplifyUsersOfIV(cast<PHINode>(I), SE, DT, LI, Dead); Changed |= simplifyUsersOfIV(cast<PHINode>(I), SE, DT, LI, Dead);

View File

@ -3899,13 +3899,11 @@ bool SLPVectorizerPass::runImpl(Function &F, ScalarEvolution *SE_,
} }
/// \brief Check that the Values in the slice in VL array are still existent in /// \brief Check that the Values in the slice in VL array are still existent in
/// the WeakTrackingVH array. /// the WeakVH array.
/// Vectorization of part of the VL array may cause later values in the VL array /// Vectorization of part of the VL array may cause later values in the VL array
/// to become invalid. We track when this has happened in the WeakTrackingVH /// to become invalid. We track when this has happened in the WeakVH array.
/// array. static bool hasValueBeenRAUWed(ArrayRef<Value *> VL, ArrayRef<WeakVH> VH,
static bool hasValueBeenRAUWed(ArrayRef<Value *> VL, unsigned SliceBegin, unsigned SliceSize) {
ArrayRef<WeakTrackingVH> VH, unsigned SliceBegin,
unsigned SliceSize) {
VL = VL.slice(SliceBegin, SliceSize); VL = VL.slice(SliceBegin, SliceSize);
VH = VH.slice(SliceBegin, SliceSize); VH = VH.slice(SliceBegin, SliceSize);
return !std::equal(VL.begin(), VL.end(), VH.begin()); return !std::equal(VL.begin(), VL.end(), VH.begin());
@ -3923,7 +3921,7 @@ bool SLPVectorizerPass::vectorizeStoreChain(ArrayRef<Value *> Chain, BoUpSLP &R,
return false; return false;
// Keep track of values that were deleted by vectorizing in the loop below. // Keep track of values that were deleted by vectorizing in the loop below.
SmallVector<WeakTrackingVH, 8> TrackValues(Chain.begin(), Chain.end()); SmallVector<WeakVH, 8> TrackValues(Chain.begin(), Chain.end());
bool Changed = false; bool Changed = false;
// Look for profitable vectorizable trees at all offsets, starting at zero. // Look for profitable vectorizable trees at all offsets, starting at zero.
@ -4109,7 +4107,7 @@ bool SLPVectorizerPass::tryToVectorizeList(ArrayRef<Value *> VL, BoUpSLP &R,
bool Changed = false; bool Changed = false;
// Keep track of values that were deleted by vectorizing in the loop below. // Keep track of values that were deleted by vectorizing in the loop below.
SmallVector<WeakTrackingVH, 8> TrackValues(VL.begin(), VL.end()); SmallVector<WeakVH, 8> TrackValues(VL.begin(), VL.end());
unsigned NextInst = 0, MaxInst = VL.size(); unsigned NextInst = 0, MaxInst = VL.size();
for (unsigned VF = MaxVF; NextInst + 1 < MaxInst && VF >= MinVF; for (unsigned VF = MaxVF; NextInst + 1 < MaxInst && VF >= MinVF;
@ -4736,7 +4734,7 @@ static Value *getReductionValue(const DominatorTree *DT, PHINode *P,
namespace { namespace {
/// Tracks instructons and its children. /// Tracks instructons and its children.
class WeakTrackingVHWithLevel final : public CallbackVH { class WeakVHWithLevel final : public CallbackVH {
/// Operand index of the instruction currently beeing analized. /// Operand index of the instruction currently beeing analized.
unsigned Level = 0; unsigned Level = 0;
/// Is this the instruction that should be vectorized, or are we now /// Is this the instruction that should be vectorized, or are we now
@ -4745,8 +4743,8 @@ class WeakTrackingVHWithLevel final : public CallbackVH {
bool IsInitial = true; bool IsInitial = true;
public: public:
explicit WeakTrackingVHWithLevel() = default; explicit WeakVHWithLevel() = default;
WeakTrackingVHWithLevel(Value *V) : CallbackVH(V){}; WeakVHWithLevel(Value *V) : CallbackVH(V){};
/// Restart children analysis each time it is repaced by the new instruction. /// Restart children analysis each time it is repaced by the new instruction.
void allUsesReplacedWith(Value *New) override { void allUsesReplacedWith(Value *New) override {
setValPtr(New); setValPtr(New);
@ -4773,7 +4771,7 @@ public:
cast<Instruction>(getValPtr())->getNumOperands() > Level); cast<Instruction>(getValPtr())->getNumOperands() > Level);
return cast<Instruction>(getValPtr())->getOperand(Level++); return cast<Instruction>(getValPtr())->getOperand(Level++);
} }
virtual ~WeakTrackingVHWithLevel() = default; virtual ~WeakVHWithLevel() = default;
}; };
} // namespace } // namespace
@ -4795,7 +4793,7 @@ static bool canBeVectorized(
if (Root->getParent() != BB) if (Root->getParent() != BB)
return false; return false;
SmallVector<WeakTrackingVHWithLevel, 8> Stack(1, Root); SmallVector<WeakVHWithLevel, 8> Stack(1, Root);
SmallSet<Value *, 8> VisitedInstrs; SmallSet<Value *, 8> VisitedInstrs;
bool Res = false; bool Res = false;
while (!Stack.empty()) { while (!Stack.empty()) {
@ -5071,8 +5069,8 @@ bool SLPVectorizerPass::vectorizeGEPIndices(BasicBlock *BB, BoUpSLP &R) {
SetVector<Value *> Candidates(GEPList.begin(), GEPList.end()); SetVector<Value *> Candidates(GEPList.begin(), GEPList.end());
// Some of the candidates may have already been vectorized after we // Some of the candidates may have already been vectorized after we
// initially collected them. If so, the WeakTrackingVHs will have // initially collected them. If so, the WeakVHs will have nullified the
// nullified the values, so remove them from the set of candidates. // values, so remove them from the set of candidates.
Candidates.remove(nullptr); Candidates.remove(nullptr);
// Remove from the set of candidates all pairs of getelementptrs with // Remove from the set of candidates all pairs of getelementptrs with

View File

@ -1,25 +0,0 @@
; RUN: opt -S -licm -loop-unswitch < %s | FileCheck %s
; This test checks for a crash. See PR32587.
@global = external global i32
declare i32 @f_1(i8, i32 returned)
define i32 @f_0() {
; CHECK-LABEL: @f_0(
bb:
br label %bb1
bb1: ; preds = %bb3, %bb
%tmp = load i32, i32* @global
%tmp2 = select i1 false, i16 1, i16 0
br label %bb3
bb3: ; preds = %bb3, %bb1
%tmp4 = phi i8 [ 0, %bb1 ], [ %tmp6, %bb3 ]
%tmp5 = icmp eq i16 %tmp2, 0
%tmp6 = select i1 %tmp5, i8 %tmp4, i8 1
%tmp7 = tail call i32 @f_1(i8 %tmp6, i32 1)
br i1 false, label %bb1, label %bb3
}

View File

@ -44,29 +44,11 @@ TEST_F(ValueHandle, WeakVH_BasicOperation) {
// doesn't matter which method. // doesn't matter which method.
EXPECT_EQ(Type::getInt32Ty(Context), WVH->getType()); EXPECT_EQ(Type::getInt32Ty(Context), WVH->getType());
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) { TEST_F(ValueHandle, WeakVH_Comparisons) {
WeakTrackingVH WVH(BitcastV.get()); WeakVH BitcastWVH(BitcastV.get());
EXPECT_EQ(BitcastV.get(), WVH); WeakVH ConstantWVH(ConstantV);
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());
}
TEST_F(ValueHandle, WeakTrackingVH_Comparisons) {
WeakTrackingVH BitcastWVH(BitcastV.get());
WeakTrackingVH ConstantWVH(ConstantV);
EXPECT_TRUE(BitcastWVH == BitcastWVH); EXPECT_TRUE(BitcastWVH == BitcastWVH);
EXPECT_TRUE(BitcastV.get() == BitcastWVH); EXPECT_TRUE(BitcastV.get() == BitcastWVH);
@ -97,20 +79,20 @@ TEST_F(ValueHandle, WeakTrackingVH_Comparisons) {
EXPECT_EQ(BV >= CV, BitcastWVH >= ConstantV); EXPECT_EQ(BV >= CV, BitcastWVH >= ConstantV);
} }
TEST_F(ValueHandle, WeakTrackingVH_FollowsRAUW) { TEST_F(ValueHandle, WeakVH_FollowsRAUW) {
WeakTrackingVH WVH(BitcastV.get()); WeakVH WVH(BitcastV.get());
WeakTrackingVH WVH_Copy(WVH); WeakVH WVH_Copy(WVH);
WeakTrackingVH WVH_Recreated(BitcastV.get()); WeakVH WVH_Recreated(BitcastV.get());
BitcastV->replaceAllUsesWith(ConstantV); BitcastV->replaceAllUsesWith(ConstantV);
EXPECT_EQ(ConstantV, WVH); EXPECT_EQ(ConstantV, WVH);
EXPECT_EQ(ConstantV, WVH_Copy); EXPECT_EQ(ConstantV, WVH_Copy);
EXPECT_EQ(ConstantV, WVH_Recreated); EXPECT_EQ(ConstantV, WVH_Recreated);
} }
TEST_F(ValueHandle, WeakTrackingVH_NullOnDeletion) { TEST_F(ValueHandle, WeakVH_NullOnDeletion) {
WeakTrackingVH WVH(BitcastV.get()); WeakVH WVH(BitcastV.get());
WeakTrackingVH WVH_Copy(WVH); WeakVH WVH_Copy(WVH);
WeakTrackingVH WVH_Recreated(BitcastV.get()); WeakVH WVH_Recreated(BitcastV.get());
BitcastV.reset(); BitcastV.reset();
Value *null_value = nullptr; Value *null_value = nullptr;
EXPECT_EQ(null_value, WVH); EXPECT_EQ(null_value, WVH);
@ -361,11 +343,11 @@ TEST_F(ValueHandle, DestroyingOtherVHOnSameValueDoesntBreakIteration) {
class DestroyingVH final : public CallbackVH { class DestroyingVH final : public CallbackVH {
public: public:
std::unique_ptr<WeakTrackingVH> ToClear[2]; std::unique_ptr<WeakVH> ToClear[2];
DestroyingVH(Value *V) { DestroyingVH(Value *V) {
ToClear[0].reset(new WeakTrackingVH(V)); ToClear[0].reset(new WeakVH(V));
setValPtr(V); setValPtr(V);
ToClear[1].reset(new WeakTrackingVH(V)); ToClear[1].reset(new WeakVH(V));
} }
void deleted() override { void deleted() override {
ToClear[0].reset(); ToClear[0].reset();
@ -379,9 +361,9 @@ TEST_F(ValueHandle, DestroyingOtherVHOnSameValueDoesntBreakIteration) {
}; };
{ {
WeakTrackingVH ShouldBeVisited1(BitcastV.get()); WeakVH ShouldBeVisited1(BitcastV.get());
DestroyingVH C(BitcastV.get()); DestroyingVH C(BitcastV.get());
WeakTrackingVH ShouldBeVisited2(BitcastV.get()); WeakVH ShouldBeVisited2(BitcastV.get());
BitcastV->replaceAllUsesWith(ConstantV); BitcastV->replaceAllUsesWith(ConstantV);
EXPECT_EQ(ConstantV, static_cast<Value*>(ShouldBeVisited1)); EXPECT_EQ(ConstantV, static_cast<Value*>(ShouldBeVisited1));
@ -389,9 +371,9 @@ TEST_F(ValueHandle, DestroyingOtherVHOnSameValueDoesntBreakIteration) {
} }
{ {
WeakTrackingVH ShouldBeVisited1(BitcastV.get()); WeakVH ShouldBeVisited1(BitcastV.get());
DestroyingVH C(BitcastV.get()); DestroyingVH C(BitcastV.get());
WeakTrackingVH ShouldBeVisited2(BitcastV.get()); WeakVH ShouldBeVisited2(BitcastV.get());
BitcastV.reset(); BitcastV.reset();
EXPECT_EQ(nullptr, static_cast<Value*>(ShouldBeVisited1)); EXPECT_EQ(nullptr, static_cast<Value*>(ShouldBeVisited1));