forked from OSchip/llvm-project
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:
parent
9eed0bee3d
commit
2cbeb00f38
|
@ -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:
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 *) {}
|
||||||
};
|
};
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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.
|
||||||
///
|
///
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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()) {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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";
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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 =
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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).
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
|
|
@ -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));
|
||||||
|
|
Loading…
Reference in New Issue