diff options
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Analysis/LoopAccessAnalysis.cpp')
-rw-r--r-- | contrib/llvm-project/llvm/lib/Analysis/LoopAccessAnalysis.cpp | 106 |
1 files changed, 38 insertions, 68 deletions
diff --git a/contrib/llvm-project/llvm/lib/Analysis/LoopAccessAnalysis.cpp b/contrib/llvm-project/llvm/lib/Analysis/LoopAccessAnalysis.cpp index f409cd322146..e632fe25c24c 100644 --- a/contrib/llvm-project/llvm/lib/Analysis/LoopAccessAnalysis.cpp +++ b/contrib/llvm-project/llvm/lib/Analysis/LoopAccessAnalysis.cpp @@ -149,27 +149,23 @@ const SCEV *llvm::replaceSymbolicStrideSCEV(PredicatedScalarEvolution &PSE, // symbolic stride replaced by one. ValueToValueMap::const_iterator SI = PtrToStride.find(OrigPtr ? OrigPtr : Ptr); - if (SI != PtrToStride.end()) { - Value *StrideVal = SI->second; + if (SI == PtrToStride.end()) + // For a non-symbolic stride, just return the original expression. + return OrigSCEV; - // Strip casts. - StrideVal = stripIntegerCast(StrideVal); + Value *StrideVal = stripIntegerCast(SI->second); - ScalarEvolution *SE = PSE.getSE(); - const auto *U = cast<SCEVUnknown>(SE->getSCEV(StrideVal)); - const auto *CT = - static_cast<const SCEVConstant *>(SE->getOne(StrideVal->getType())); - - PSE.addPredicate(*SE->getEqualPredicate(U, CT)); - auto *Expr = PSE.getSCEV(Ptr); + ScalarEvolution *SE = PSE.getSE(); + const auto *U = cast<SCEVUnknown>(SE->getSCEV(StrideVal)); + const auto *CT = + static_cast<const SCEVConstant *>(SE->getOne(StrideVal->getType())); - LLVM_DEBUG(dbgs() << "LAA: Replacing SCEV: " << *OrigSCEV - << " by: " << *Expr << "\n"); - return Expr; - } + PSE.addPredicate(*SE->getEqualPredicate(U, CT)); + auto *Expr = PSE.getSCEV(Ptr); - // Otherwise, just return the SCEV of the original pointer. - return OrigSCEV; + LLVM_DEBUG(dbgs() << "LAA: Replacing SCEV: " << *OrigSCEV + << " by: " << *Expr << "\n"); + return Expr; } RuntimeCheckingPtrGroup::RuntimeCheckingPtrGroup( @@ -227,9 +223,10 @@ void RuntimePointerChecking::insert(Loop *Lp, Value *Ptr, bool WritePtr, ScEnd = SE->getUMaxExpr(AR->getStart(), ScEnd); } // Add the size of the pointed element to ScEnd. - unsigned EltSize = - Ptr->getType()->getPointerElementType()->getScalarSizeInBits() / 8; - const SCEV *EltSizeSCEV = SE->getConstant(ScEnd->getType(), EltSize); + auto &DL = Lp->getHeader()->getModule()->getDataLayout(); + Type *IdxTy = DL.getIndexType(Ptr->getType()); + const SCEV *EltSizeSCEV = + SE->getStoreSizeOfExpr(IdxTy, Ptr->getType()->getPointerElementType()); ScEnd = SE->getAddExpr(ScEnd, EltSizeSCEV); } @@ -508,16 +505,16 @@ public: typedef PointerIntPair<Value *, 1, bool> MemAccessInfo; typedef SmallVector<MemAccessInfo, 8> MemAccessInfoList; - AccessAnalysis(const DataLayout &Dl, Loop *TheLoop, AAResults *AA, - LoopInfo *LI, MemoryDepChecker::DepCandidates &DA, + AccessAnalysis(Loop *TheLoop, AAResults *AA, LoopInfo *LI, + MemoryDepChecker::DepCandidates &DA, PredicatedScalarEvolution &PSE) - : DL(Dl), TheLoop(TheLoop), AST(*AA), LI(LI), DepCands(DA), + : TheLoop(TheLoop), AST(*AA), LI(LI), DepCands(DA), IsRTCheckAnalysisNeeded(false), PSE(PSE) {} /// Register a load and whether it is only read from. void addLoad(MemoryLocation &Loc, bool IsReadOnly) { Value *Ptr = const_cast<Value*>(Loc.Ptr); - AST.add(Ptr, LocationSize::unknown(), Loc.AATags); + AST.add(Ptr, LocationSize::beforeOrAfterPointer(), Loc.AATags); Accesses.insert(MemAccessInfo(Ptr, false)); if (IsReadOnly) ReadOnlyPtr.insert(Ptr); @@ -526,7 +523,7 @@ public: /// Register a store. void addStore(MemoryLocation &Loc) { Value *Ptr = const_cast<Value*>(Loc.Ptr); - AST.add(Ptr, LocationSize::unknown(), Loc.AATags); + AST.add(Ptr, LocationSize::beforeOrAfterPointer(), Loc.AATags); Accesses.insert(MemAccessInfo(Ptr, true)); } @@ -585,8 +582,6 @@ private: /// Set of all accesses. PtrAccessSet Accesses; - const DataLayout &DL; - /// The loop being checked. const Loop *TheLoop; @@ -732,7 +727,7 @@ bool AccessAnalysis::canCheckPtrAtRT(RuntimePointerChecking &RtCheck, // First, count how many write and read accesses are in the alias set. Also // collect MemAccessInfos for later. SmallVector<MemAccessInfo, 4> AccessInfos; - for (auto A : AS) { + for (const auto &A : AS) { Value *Ptr = A.getValue(); bool IsWrite = Accesses.count(MemAccessInfo(Ptr, true)); @@ -866,7 +861,7 @@ void AccessAnalysis::processMemAccesses() { // compatibility and potential for underlying-object overlap. As a result, we // only need to check for potential pointer dependencies within each alias // set. - for (auto &AS : AST) { + for (const auto &AS : AST) { // Note that both the alias-set tracker and the alias sets themselves used // linked lists internally and so the iteration order here is deterministic // (matching the original instruction order within each set). @@ -886,12 +881,12 @@ void AccessAnalysis::processMemAccesses() { bool UseDeferred = SetIteration > 0; PtrAccessSet &S = UseDeferred ? DeferredAccesses : Accesses; - for (auto AV : AS) { + for (const auto &AV : AS) { Value *Ptr = AV.getValue(); // For a single memory access in AliasSetTracker, Accesses may contain // both read and write, and they both need to be handled for CheckDeps. - for (auto AC : S) { + for (const auto &AC : S) { if (AC.getPointer() != Ptr) continue; @@ -938,7 +933,7 @@ void AccessAnalysis::processMemAccesses() { typedef SmallVector<const Value *, 16> ValueVector; ValueVector TempObjects; - GetUnderlyingObjects(Ptr, TempObjects, DL, LI); + getUnderlyingObjects(Ptr, TempObjects, LI); LLVM_DEBUG(dbgs() << "Underlying objects for pointer " << *Ptr << "\n"); for (const Value *UnderlyingObj : TempObjects) { @@ -992,7 +987,7 @@ static bool isNoWrapAddRec(Value *Ptr, const SCEVAddRecExpr *AR, // Make sure there is only one non-const index and analyze that. Value *NonConstIndex = nullptr; - for (Value *Index : make_range(GEP->idx_begin(), GEP->idx_end())) + for (Value *Index : GEP->indices()) if (!isa<ConstantInt>(Index)) { if (NonConstIndex) return false; @@ -1142,7 +1137,7 @@ bool llvm::sortPtrAccesses(ArrayRef<Value *> VL, const DataLayout &DL, // first pointer in the array. Value *Ptr0 = VL[0]; const SCEV *Scev0 = SE.getSCEV(Ptr0); - Value *Obj0 = GetUnderlyingObject(Ptr0, DL); + Value *Obj0 = getUnderlyingObject(Ptr0); llvm::SmallSet<int64_t, 4> Offsets; for (auto *Ptr : VL) { @@ -1153,7 +1148,7 @@ bool llvm::sortPtrAccesses(ArrayRef<Value *> VL, const DataLayout &DL, return false; // If a pointer refers to a different underlying object, bail - the // pointers are by definition incomparable. - Value *CurrObj = GetUnderlyingObject(Ptr, DL); + Value *CurrObj = getUnderlyingObject(Ptr); if (CurrObj != Obj0) return false; @@ -1343,7 +1338,7 @@ bool MemoryDepChecker::couldPreventStoreLoadForward(uint64_t Distance, // If the number of vector iteration between the store and the load are // small we could incur conflicts. if (Distance % VF && Distance / VF < NumItersForStoreLoadThroughMemory) { - MaxVFWithoutSLForwardIssues = (VF >>= 1); + MaxVFWithoutSLForwardIssues = (VF >> 1); break; } } @@ -1659,7 +1654,7 @@ MemoryDepChecker::isDependent(const MemAccessInfo &A, unsigned AIdx, LLVM_DEBUG(dbgs() << "LAA: Positive distance " << Val.getSExtValue() << " with max VF = " << MaxVF << '\n'); uint64_t MaxVFInBits = MaxVF * TypeByteSize * 8; - MaxSafeRegisterWidth = std::min(MaxSafeRegisterWidth, MaxVFInBits); + MaxSafeVectorWidthInBits = std::min(MaxSafeVectorWidthInBits, MaxVFInBits); return Dependence::BackwardVectorizable; } @@ -1771,7 +1766,7 @@ bool LoopAccessInfo::canAnalyzeLoop() { << TheLoop->getHeader()->getName() << '\n'); // We can only analyze innermost loops. - if (!TheLoop->empty()) { + if (!TheLoop->isInnermost()) { LLVM_DEBUG(dbgs() << "LAA: loop is not the innermost loop\n"); recordAnalysis("NotInnerMostLoop") << "loop is not the innermost loop"; return false; @@ -1786,29 +1781,9 @@ bool LoopAccessInfo::canAnalyzeLoop() { return false; } - // We must have a single exiting block. - if (!TheLoop->getExitingBlock()) { - LLVM_DEBUG( - dbgs() << "LAA: loop control flow is not understood by analyzer\n"); - recordAnalysis("CFGNotUnderstood") - << "loop control flow is not understood by analyzer"; - return false; - } - - // We only handle bottom-tested loops, i.e. loop in which the condition is - // checked at the end of each iteration. With that we can assume that all - // instructions in the loop are executed the same number of times. - if (TheLoop->getExitingBlock() != TheLoop->getLoopLatch()) { - LLVM_DEBUG( - dbgs() << "LAA: loop control flow is not understood by analyzer\n"); - recordAnalysis("CFGNotUnderstood") - << "loop control flow is not understood by analyzer"; - return false; - } - // ScalarEvolution needs to be able to find the exit count. const SCEV *ExitCount = PSE->getBackedgeTakenCount(); - if (ExitCount == PSE->getSE()->getCouldNotCompute()) { + if (isa<SCEVCouldNotCompute>(ExitCount)) { recordAnalysis("CantComputeNumberOfIterations") << "could not determine number of loop iterations"; LLVM_DEBUG(dbgs() << "LAA: SCEV could not compute the loop exit count.\n"); @@ -1947,10 +1922,9 @@ void LoopAccessInfo::analyzeLoop(AAResults *AA, LoopInfo *LI, } MemoryDepChecker::DepCandidates DependentAccesses; - AccessAnalysis Accesses(TheLoop->getHeader()->getModule()->getDataLayout(), - TheLoop, AA, LI, DependentAccesses, *PSE); + AccessAnalysis Accesses(TheLoop, AA, LI, DependentAccesses, *PSE); - // Holds the analyzed pointers. We don't want to call GetUnderlyingObjects + // Holds the analyzed pointers. We don't want to call getUnderlyingObjects // multiple times on the same object. If the ptr is accessed twice, once // for read and once for write, it will only appear once (on the write // list). This is okay, since we are going to check for conflicts between @@ -2152,12 +2126,8 @@ bool LoopAccessInfo::isUniform(Value *V) const { } void LoopAccessInfo::collectStridedAccess(Value *MemAccess) { - Value *Ptr = nullptr; - if (LoadInst *LI = dyn_cast<LoadInst>(MemAccess)) - Ptr = LI->getPointerOperand(); - else if (StoreInst *SI = dyn_cast<StoreInst>(MemAccess)) - Ptr = SI->getPointerOperand(); - else + Value *Ptr = getLoadStorePointerOperand(MemAccess); + if (!Ptr) return; Value *Stride = getStrideFromPointer(Ptr, PSE->getSE(), TheLoop); |