diff options
author | Florian Hahn <flo@fhahn.com> | 2025-02-13 22:06:04 +0100 |
---|---|---|
committer | Florian Hahn <flo@fhahn.com> | 2025-02-13 22:06:12 +0100 |
commit | 424fcc5df7d7ba1db3d83023885dcbaf33a49b39 (patch) | |
tree | e647064783b4d6ee96e3fa9b0f38a9d5c2d63ca8 /llvm/lib/Analysis/LoopAccessAnalysis.cpp | |
parent | 0aafb8aca3444ef1a1f797a6facbb087ea608f4e (diff) | |
download | llvm-424fcc5df7d7ba1db3d83023885dcbaf33a49b39.zip llvm-424fcc5df7d7ba1db3d83023885dcbaf33a49b39.tar.gz llvm-424fcc5df7d7ba1db3d83023885dcbaf33a49b39.tar.bz2 |
[LAA] Split off code to compute stride from AddRec for reuse (NFC).
Refactors to code to expose the core logic from getPtrStride to compute
the stride for a given AddRec.
Split off from https://github.com/llvm/llvm-project/pull/126971 as
suggested.
Diffstat (limited to 'llvm/lib/Analysis/LoopAccessAnalysis.cpp')
-rw-r--r-- | llvm/lib/Analysis/LoopAccessAnalysis.cpp | 81 |
1 files changed, 45 insertions, 36 deletions
diff --git a/llvm/lib/Analysis/LoopAccessAnalysis.cpp b/llvm/lib/Analysis/LoopAccessAnalysis.cpp index d24a48d..cd1294b 100644 --- a/llvm/lib/Analysis/LoopAccessAnalysis.cpp +++ b/llvm/lib/Analysis/LoopAccessAnalysis.cpp @@ -813,6 +813,48 @@ static bool hasComputableBounds(PredicatedScalarEvolution &PSE, Value *Ptr, return AR->isAffine(); } +/// Try to compute the stride for \p AR. Used by getPtrStride. +static std::optional<int64_t> +getStrideFromAddRec(const SCEVAddRecExpr *AR, const Loop *Lp, Type *AccessTy, + Value *Ptr, PredicatedScalarEvolution &PSE) { + // The access function must stride over the innermost loop. + if (Lp != AR->getLoop()) { + LLVM_DEBUG(dbgs() << "LAA: Bad stride - Not striding over innermost loop " + << *Ptr << " SCEV: " << *AR << "\n"); + return std::nullopt; + } + + // Check the step is constant. + const SCEV *Step = AR->getStepRecurrence(*PSE.getSE()); + + // Calculate the pointer stride and check if it is constant. + const SCEVConstant *C = dyn_cast<SCEVConstant>(Step); + if (!C) { + LLVM_DEBUG(dbgs() << "LAA: Bad stride - Not a constant strided " << *Ptr + << " SCEV: " << *AR << "\n"); + return std::nullopt; + } + + const auto &DL = Lp->getHeader()->getDataLayout(); + TypeSize AllocSize = DL.getTypeAllocSize(AccessTy); + int64_t Size = AllocSize.getFixedValue(); + const APInt &APStepVal = C->getAPInt(); + + // Huge step value - give up. + if (APStepVal.getBitWidth() > 64) + return std::nullopt; + + int64_t StepVal = APStepVal.getSExtValue(); + + // Strided access. + int64_t Stride = StepVal / Size; + int64_t Rem = StepVal % Size; + if (Rem) + return std::nullopt; + + return Stride; +} + /// Check whether a pointer address cannot wrap. static bool isNoWrap(PredicatedScalarEvolution &PSE, const DenseMap<Value *, const SCEV *> &Strides, Value *Ptr, @@ -1458,42 +1500,9 @@ llvm::getPtrStride(PredicatedScalarEvolution &PSE, Type *AccessTy, Value *Ptr, return std::nullopt; } - // The access function must stride over the innermost loop. - if (Lp != AR->getLoop()) { - LLVM_DEBUG(dbgs() << "LAA: Bad stride - Not striding over innermost loop " - << *Ptr << " SCEV: " << *AR << "\n"); - return std::nullopt; - } - - // Check the step is constant. - const SCEV *Step = AR->getStepRecurrence(*PSE.getSE()); - - // Calculate the pointer stride and check if it is constant. - const SCEVConstant *C = dyn_cast<SCEVConstant>(Step); - if (!C) { - LLVM_DEBUG(dbgs() << "LAA: Bad stride - Not a constant strided " << *Ptr - << " SCEV: " << *AR << "\n"); - return std::nullopt; - } - - const auto &DL = Lp->getHeader()->getDataLayout(); - TypeSize AllocSize = DL.getTypeAllocSize(AccessTy); - int64_t Size = AllocSize.getFixedValue(); - const APInt &APStepVal = C->getAPInt(); - - // Huge step value - give up. - if (APStepVal.getBitWidth() > 64) - return std::nullopt; - - int64_t StepVal = APStepVal.getSExtValue(); - - // Strided access. - int64_t Stride = StepVal / Size; - int64_t Rem = StepVal % Size; - if (Rem) - return std::nullopt; - - if (!ShouldCheckWrap) + std::optional<int64_t> Stride = + getStrideFromAddRec(AR, Lp, AccessTy, Ptr, PSE); + if (!ShouldCheckWrap || !Stride) return Stride; // The address calculation must not wrap. Otherwise, a dependence could be |