diff options
Diffstat (limited to 'llvm/lib/Analysis/LoopAccessAnalysis.cpp')
| -rw-r--r-- | llvm/lib/Analysis/LoopAccessAnalysis.cpp | 55 |
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; } |
