aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/AssumptionCache.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Analysis/AssumptionCache.cpp')
-rw-r--r--llvm/lib/Analysis/AssumptionCache.cpp64
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() &&