Skip to content

Commit 424fcc5

Browse files
committed
[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 #126971 as suggested.
1 parent 0aafb8a commit 424fcc5

File tree

1 file changed

+45
-36
lines changed

1 file changed

+45
-36
lines changed

llvm/lib/Analysis/LoopAccessAnalysis.cpp

Lines changed: 45 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -813,6 +813,48 @@ static bool hasComputableBounds(PredicatedScalarEvolution &PSE, Value *Ptr,
813813
return AR->isAffine();
814814
}
815815

816+
/// Try to compute the stride for \p AR. Used by getPtrStride.
817+
static std::optional<int64_t>
818+
getStrideFromAddRec(const SCEVAddRecExpr *AR, const Loop *Lp, Type *AccessTy,
819+
Value *Ptr, PredicatedScalarEvolution &PSE) {
820+
// The access function must stride over the innermost loop.
821+
if (Lp != AR->getLoop()) {
822+
LLVM_DEBUG(dbgs() << "LAA: Bad stride - Not striding over innermost loop "
823+
<< *Ptr << " SCEV: " << *AR << "\n");
824+
return std::nullopt;
825+
}
826+
827+
// Check the step is constant.
828+
const SCEV *Step = AR->getStepRecurrence(*PSE.getSE());
829+
830+
// Calculate the pointer stride and check if it is constant.
831+
const SCEVConstant *C = dyn_cast<SCEVConstant>(Step);
832+
if (!C) {
833+
LLVM_DEBUG(dbgs() << "LAA: Bad stride - Not a constant strided " << *Ptr
834+
<< " SCEV: " << *AR << "\n");
835+
return std::nullopt;
836+
}
837+
838+
const auto &DL = Lp->getHeader()->getDataLayout();
839+
TypeSize AllocSize = DL.getTypeAllocSize(AccessTy);
840+
int64_t Size = AllocSize.getFixedValue();
841+
const APInt &APStepVal = C->getAPInt();
842+
843+
// Huge step value - give up.
844+
if (APStepVal.getBitWidth() > 64)
845+
return std::nullopt;
846+
847+
int64_t StepVal = APStepVal.getSExtValue();
848+
849+
// Strided access.
850+
int64_t Stride = StepVal / Size;
851+
int64_t Rem = StepVal % Size;
852+
if (Rem)
853+
return std::nullopt;
854+
855+
return Stride;
856+
}
857+
816858
/// Check whether a pointer address cannot wrap.
817859
static bool isNoWrap(PredicatedScalarEvolution &PSE,
818860
const DenseMap<Value *, const SCEV *> &Strides, Value *Ptr,
@@ -1458,42 +1500,9 @@ llvm::getPtrStride(PredicatedScalarEvolution &PSE, Type *AccessTy, Value *Ptr,
14581500
return std::nullopt;
14591501
}
14601502

1461-
// The access function must stride over the innermost loop.
1462-
if (Lp != AR->getLoop()) {
1463-
LLVM_DEBUG(dbgs() << "LAA: Bad stride - Not striding over innermost loop "
1464-
<< *Ptr << " SCEV: " << *AR << "\n");
1465-
return std::nullopt;
1466-
}
1467-
1468-
// Check the step is constant.
1469-
const SCEV *Step = AR->getStepRecurrence(*PSE.getSE());
1470-
1471-
// Calculate the pointer stride and check if it is constant.
1472-
const SCEVConstant *C = dyn_cast<SCEVConstant>(Step);
1473-
if (!C) {
1474-
LLVM_DEBUG(dbgs() << "LAA: Bad stride - Not a constant strided " << *Ptr
1475-
<< " SCEV: " << *AR << "\n");
1476-
return std::nullopt;
1477-
}
1478-
1479-
const auto &DL = Lp->getHeader()->getDataLayout();
1480-
TypeSize AllocSize = DL.getTypeAllocSize(AccessTy);
1481-
int64_t Size = AllocSize.getFixedValue();
1482-
const APInt &APStepVal = C->getAPInt();
1483-
1484-
// Huge step value - give up.
1485-
if (APStepVal.getBitWidth() > 64)
1486-
return std::nullopt;
1487-
1488-
int64_t StepVal = APStepVal.getSExtValue();
1489-
1490-
// Strided access.
1491-
int64_t Stride = StepVal / Size;
1492-
int64_t Rem = StepVal % Size;
1493-
if (Rem)
1494-
return std::nullopt;
1495-
1496-
if (!ShouldCheckWrap)
1503+
std::optional<int64_t> Stride =
1504+
getStrideFromAddRec(AR, Lp, AccessTy, Ptr, PSE);
1505+
if (!ShouldCheckWrap || !Stride)
14971506
return Stride;
14981507

14991508
// The address calculation must not wrap. Otherwise, a dependence could be

0 commit comments

Comments
 (0)