diff options
Diffstat (limited to 'llvm/lib/Analysis/AssumptionCache.cpp')
-rw-r--r-- | llvm/lib/Analysis/AssumptionCache.cpp | 64 |
1 files changed, 44 insertions, 20 deletions
diff --git a/llvm/lib/Analysis/AssumptionCache.cpp b/llvm/lib/Analysis/AssumptionCache.cpp index f4d4a5ac8f88..16bfd5c75902 100644 --- a/llvm/lib/Analysis/AssumptionCache.cpp +++ b/llvm/lib/Analysis/AssumptionCache.cpp @@ -11,6 +11,7 @@ // //===----------------------------------------------------------------------===// +#include "llvm/Analysis/AssumeBundleQueries.h" #include "llvm/Analysis/AssumptionCache.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallPtrSet.h" @@ -41,7 +42,7 @@ static cl::opt<bool> cl::desc("Enable verification of assumption cache"), cl::init(false)); -SmallVector<WeakTrackingVH, 1> & +SmallVector<AssumptionCache::ResultElem, 1> & AssumptionCache::getOrInsertAffectedValues(Value *V) { // Try using find_as first to avoid creating extra value handles just for the // purpose of doing the lookup. @@ -50,32 +51,39 @@ AssumptionCache::getOrInsertAffectedValues(Value *V) { return AVI->second; auto AVIP = AffectedValues.insert( - {AffectedValueCallbackVH(V, this), SmallVector<WeakTrackingVH, 1>()}); + {AffectedValueCallbackVH(V, this), SmallVector<ResultElem, 1>()}); return AVIP.first->second; } -static void findAffectedValues(CallInst *CI, - SmallVectorImpl<Value *> &Affected) { +static void +findAffectedValues(CallInst *CI, + SmallVectorImpl<AssumptionCache::ResultElem> &Affected) { // Note: This code must be kept in-sync with the code in // computeKnownBitsFromAssume in ValueTracking. - auto AddAffected = [&Affected](Value *V) { + auto AddAffected = [&Affected](Value *V, unsigned Idx = + AssumptionCache::ExprResultIdx) { if (isa<Argument>(V)) { - Affected.push_back(V); + Affected.push_back({V, Idx}); } else if (auto *I = dyn_cast<Instruction>(V)) { - Affected.push_back(I); + Affected.push_back({I, Idx}); // Peek through unary operators to find the source of the condition. Value *Op; if (match(I, m_BitCast(m_Value(Op))) || - match(I, m_PtrToInt(m_Value(Op))) || - match(I, m_Not(m_Value(Op)))) { + match(I, m_PtrToInt(m_Value(Op))) || match(I, m_Not(m_Value(Op)))) { if (isa<Instruction>(Op) || isa<Argument>(Op)) - Affected.push_back(Op); + Affected.push_back({Op, Idx}); } } }; + for (unsigned Idx = 0; Idx != CI->getNumOperandBundles(); Idx++) { + if (CI->getOperandBundleAt(Idx).Inputs.size() > ABA_WasOn && + CI->getOperandBundleAt(Idx).getTagName() != IgnoreBundleTag) + AddAffected(CI->getOperandBundleAt(Idx).Inputs[ABA_WasOn], Idx); + } + Value *Cond = CI->getArgOperand(0), *A, *B; AddAffected(Cond); @@ -112,28 +120,44 @@ static void findAffectedValues(CallInst *CI, } void AssumptionCache::updateAffectedValues(CallInst *CI) { - SmallVector<Value *, 16> Affected; + SmallVector<AssumptionCache::ResultElem, 16> Affected; findAffectedValues(CI, Affected); for (auto &AV : Affected) { - auto &AVV = getOrInsertAffectedValues(AV); - if (std::find(AVV.begin(), AVV.end(), CI) == AVV.end()) - AVV.push_back(CI); + auto &AVV = getOrInsertAffectedValues(AV.Assume); + if (std::find_if(AVV.begin(), AVV.end(), [&](ResultElem &Elem) { + return Elem.Assume == CI && Elem.Index == AV.Index; + }) == AVV.end()) + AVV.push_back({CI, AV.Index}); } } void AssumptionCache::unregisterAssumption(CallInst *CI) { - SmallVector<Value *, 16> Affected; + SmallVector<AssumptionCache::ResultElem, 16> Affected; findAffectedValues(CI, Affected); for (auto &AV : Affected) { - auto AVI = AffectedValues.find_as(AV); - if (AVI != AffectedValues.end()) + auto AVI = AffectedValues.find_as(AV.Assume); + if (AVI == AffectedValues.end()) + continue; + bool Found = false; + bool HasNonnull = false; + for (ResultElem &Elem : AVI->second) { + if (Elem.Assume == CI) { + Found = true; + Elem.Assume = nullptr; + } + HasNonnull |= !!Elem.Assume; + if (HasNonnull && Found) + break; + } + assert(Found && "already unregistered or incorrect cache state"); + if (!HasNonnull) AffectedValues.erase(AVI); } AssumeHandles.erase( - remove_if(AssumeHandles, [CI](WeakTrackingVH &VH) { return CI == VH; }), + remove_if(AssumeHandles, [CI](ResultElem &RE) { return CI == RE; }), AssumeHandles.end()); } @@ -177,7 +201,7 @@ void AssumptionCache::scanFunction() { for (BasicBlock &B : F) for (Instruction &II : B) if (match(&II, m_Intrinsic<Intrinsic::assume>())) - AssumeHandles.push_back(&II); + AssumeHandles.push_back({&II, ExprResultIdx}); // Mark the scan as complete. Scanned = true; @@ -196,7 +220,7 @@ void AssumptionCache::registerAssumption(CallInst *CI) { if (!Scanned) return; - AssumeHandles.push_back(CI); + AssumeHandles.push_back({CI, ExprResultIdx}); #ifndef NDEBUG assert(CI->getParent() && |