summaryrefslogtreecommitdiff
path: root/llvm/lib/Analysis/LoopAccessAnalysis.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Analysis/LoopAccessAnalysis.cpp')
-rw-r--r--llvm/lib/Analysis/LoopAccessAnalysis.cpp55
1 files changed, 34 insertions, 21 deletions
diff --git a/llvm/lib/Analysis/LoopAccessAnalysis.cpp b/llvm/lib/Analysis/LoopAccessAnalysis.cpp
index c00f49332554..c7baf288838c 100644
--- a/llvm/lib/Analysis/LoopAccessAnalysis.cpp
+++ b/llvm/lib/Analysis/LoopAccessAnalysis.cpp
@@ -530,8 +530,10 @@ void RuntimePointerChecking::groupChecks(
// equivalence class, the iteration order is deterministic.
for (auto M : DepCands.members(Access)) {
auto PointerI = PositionMap.find(M.getPointer());
- assert(PointerI != PositionMap.end() &&
- "pointer in equivalence class not found in PositionMap");
+ // If we can't find the pointer in PositionMap that means we can't
+ // generate a memcheck for it.
+ if (PointerI == PositionMap.end())
+ continue;
for (unsigned Pointer : PointerI->second) {
bool Merged = false;
// Mark this pointer as seen.
@@ -693,10 +695,13 @@ public:
/// non-intersection.
///
/// Returns true if we need no check or if we do and we can generate them
- /// (i.e. the pointers have computable bounds).
+ /// (i.e. the pointers have computable bounds). A return value of false means
+ /// we couldn't analyze and generate runtime checks for all pointers in the
+ /// loop, but if \p AllowPartial is set then we will have checks for those
+ /// pointers we could analyze.
bool canCheckPtrAtRT(RuntimePointerChecking &RtCheck, Loop *TheLoop,
const DenseMap<Value *, const SCEV *> &Strides,
- Value *&UncomputablePtr);
+ Value *&UncomputablePtr, bool AllowPartial);
/// Goes over all memory accesses, checks whether a RT check is needed
/// and builds sets of dependent accesses.
@@ -1174,8 +1179,8 @@ bool AccessAnalysis::createCheckForAccess(
bool AccessAnalysis::canCheckPtrAtRT(
RuntimePointerChecking &RtCheck, Loop *TheLoop,
- const DenseMap<Value *, const SCEV *> &StridesMap,
- Value *&UncomputablePtr) {
+ const DenseMap<Value *, const SCEV *> &StridesMap, Value *&UncomputablePtr,
+ bool AllowPartial) {
// Find pointers with computable bounds. We are going to use this information
// to place a runtime bound check.
bool CanDoRT = true;
@@ -1268,7 +1273,8 @@ bool AccessAnalysis::canCheckPtrAtRT(
/*Assume=*/true)) {
CanDoAliasSetRT = false;
UncomputablePtr = Access.getPointer();
- break;
+ if (!AllowPartial)
+ break;
}
}
}
@@ -1308,7 +1314,7 @@ bool AccessAnalysis::canCheckPtrAtRT(
}
}
- if (MayNeedRTCheck && CanDoRT)
+ if (MayNeedRTCheck && (CanDoRT || AllowPartial))
RtCheck.generateChecks(DepCands, IsDepCheckNeeded);
LLVM_DEBUG(dbgs() << "LAA: We need to do " << RtCheck.getNumberOfChecks()
@@ -1322,7 +1328,7 @@ bool AccessAnalysis::canCheckPtrAtRT(
bool CanDoRTIfNeeded = !RtCheck.Need || CanDoRT;
assert(CanDoRTIfNeeded == (CanDoRT || !MayNeedRTCheck) &&
"CanDoRTIfNeeded depends on RtCheck.Need");
- if (!CanDoRTIfNeeded)
+ if (!CanDoRTIfNeeded && !AllowPartial)
RtCheck.reset();
return CanDoRTIfNeeded;
}
@@ -2592,9 +2598,9 @@ bool LoopAccessInfo::analyzeLoop(AAResults *AA, const LoopInfo *LI,
// Find pointers with computable bounds. We are going to use this information
// to place a runtime bound check.
Value *UncomputablePtr = nullptr;
- bool CanDoRTIfNeeded = Accesses.canCheckPtrAtRT(
- *PtrRtChecking, TheLoop, SymbolicStrides, UncomputablePtr);
- if (!CanDoRTIfNeeded) {
+ HasCompletePtrRtChecking = Accesses.canCheckPtrAtRT(
+ *PtrRtChecking, TheLoop, SymbolicStrides, UncomputablePtr, AllowPartial);
+ if (!HasCompletePtrRtChecking) {
const auto *I = dyn_cast_or_null<Instruction>(UncomputablePtr);
recordAnalysis("CantIdentifyArrayBounds", I)
<< "cannot identify array bounds";
@@ -2622,11 +2628,12 @@ bool LoopAccessInfo::analyzeLoop(AAResults *AA, const LoopInfo *LI,
PtrRtChecking->Need = true;
UncomputablePtr = nullptr;
- CanDoRTIfNeeded = Accesses.canCheckPtrAtRT(
- *PtrRtChecking, TheLoop, SymbolicStrides, UncomputablePtr);
+ HasCompletePtrRtChecking =
+ Accesses.canCheckPtrAtRT(*PtrRtChecking, TheLoop, SymbolicStrides,
+ UncomputablePtr, AllowPartial);
// Check that we found the bounds for the pointer.
- if (!CanDoRTIfNeeded) {
+ if (!HasCompletePtrRtChecking) {
auto *I = dyn_cast_or_null<Instruction>(UncomputablePtr);
recordAnalysis("CantCheckMemDepsAtRunTime", I)
<< "cannot check memory dependencies at runtime";
@@ -2901,9 +2908,10 @@ void LoopAccessInfo::collectStridedAccess(Value *MemAccess) {
LoopAccessInfo::LoopAccessInfo(Loop *L, ScalarEvolution *SE,
const TargetTransformInfo *TTI,
const TargetLibraryInfo *TLI, AAResults *AA,
- DominatorTree *DT, LoopInfo *LI)
+ DominatorTree *DT, LoopInfo *LI,
+ bool AllowPartial)
: PSE(std::make_unique<PredicatedScalarEvolution>(*SE, *L)),
- PtrRtChecking(nullptr), TheLoop(L) {
+ PtrRtChecking(nullptr), TheLoop(L), AllowPartial(AllowPartial) {
unsigned MaxTargetVectorWidthInBits = std::numeric_limits<unsigned>::max();
if (TTI && !TTI->enableScalableVectorization())
// Scale the vector width by 2 as rough estimate to also consider
@@ -2952,6 +2960,8 @@ void LoopAccessInfo::print(raw_ostream &OS, unsigned Depth) const {
// List the pair of accesses need run-time checks to prove independence.
PtrRtChecking->print(OS, Depth);
+ if (PtrRtChecking->Need && !HasCompletePtrRtChecking)
+ OS.indent(Depth) << "Generated run-time checks are incomplete\n";
OS << "\n";
OS.indent(Depth)
@@ -2971,12 +2981,15 @@ void LoopAccessInfo::print(raw_ostream &OS, unsigned Depth) const {
PSE->print(OS, Depth);
}
-const LoopAccessInfo &LoopAccessInfoManager::getInfo(Loop &L) {
+const LoopAccessInfo &LoopAccessInfoManager::getInfo(Loop &L,
+ bool AllowPartial) {
const auto &[It, Inserted] = LoopAccessInfoMap.try_emplace(&L);
- if (Inserted)
- It->second =
- std::make_unique<LoopAccessInfo>(&L, &SE, TTI, TLI, &AA, &DT, &LI);
+ // We need to create the LoopAccessInfo if either we don't already have one,
+ // or if it was created with a different value of AllowPartial.
+ if (Inserted || It->second->hasAllowPartial() != AllowPartial)
+ It->second = std::make_unique<LoopAccessInfo>(&L, &SE, TTI, TLI, &AA, &DT,
+ &LI, AllowPartial);
return *It->second;
}