Skip to content

Commit c4e67a9

Browse files
committed
add more comments and examples
1 parent a575131 commit c4e67a9

File tree

1 file changed

+41
-0
lines changed

1 file changed

+41
-0
lines changed

llvm/lib/Analysis/DependenceAnalysis.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3569,6 +3569,11 @@ bool DependenceInfo::invalidate(Function &F, const PreservedAnalyses &PA,
35693569
Inv.invalidate<LoopAnalysis>(F, PA);
35703570
}
35713571

3572+
// Check that memory access offsets in V are multiples of array element size
3573+
// EltSize. Param records the first parametric expression. If the scalar
3574+
// evolution V contains two or more parameters, we check that the subsequent
3575+
// parametric expressions are multiples of the first parametric expression
3576+
// Param.
35723577
static bool checkOffsets(ScalarEvolution *SE, const SCEV *V, const SCEV *&Param,
35733578
uint64_t EltSize) {
35743579
if (auto *AddRec = dyn_cast<SCEVAddRecExpr>(V)) {
@@ -3578,9 +3583,20 @@ static bool checkOffsets(ScalarEvolution *SE, const SCEV *V, const SCEV *&Param,
35783583
}
35793584
if (auto *Cst = dyn_cast<SCEVConstant>(V)) {
35803585
APInt C = Cst->getAPInt();
3586+
3587+
// For example, alias_with_different_offsets in
3588+
// test/Analysis/DependenceAnalysis/DifferentOffsets.ll accesses "%A + 2":
3589+
// %arrayidx = getelementptr inbounds i8, ptr %A, i64 2
3590+
// store i32 42, ptr %arrayidx, align 1
3591+
// which is writing an i32, i.e., EltSize = 4 bytes, with an offset C = 2.
3592+
// checkOffsets returns false, as the offset C=2 is not a multiple of 4.
35813593
return C.srem(EltSize) == 0;
35823594
}
35833595

3596+
// Use a lambda helper function to check V for parametric expressions.
3597+
// Param records the first parametric expression. If the scalar evolution V
3598+
// contains two or more parameters, we check that the subsequent parametric
3599+
// expressions are multiples of the first parametric expression Param.
35843600
auto checkParamsMultipleOfSize = [&](const SCEV *V,
35853601
const SCEV *&Param) -> bool {
35863602
if (EltSize == 1)
@@ -3600,6 +3616,12 @@ static bool checkOffsets(ScalarEvolution *SE, const SCEV *V, const SCEV *&Param,
36003616
return true;
36013617
auto Rem = Val.srem(APInt(Val.getBitWidth(), EltSize, /*isSigned=*/true));
36023618
if (Rem.isZero())
3619+
// For example in test/Analysis/DependenceAnalysis/Preliminary.ll
3620+
// SrcSCEV = ((4 * (sext i8 %n to i64))<nsw> + %A)
3621+
// DstSCEV = (4 + (4 * (sext i8 %n to i64))<nsw> + %A)
3622+
// Param = (4 * (sext i8 %n to i64))<nsw>
3623+
// V = 4 + (4 * (sext i8 %n to i64))<nsw>
3624+
// Diff = -4, Rem = 0, and so all offsets are multiple of 4.
36033625
return true;
36043626
LLVM_DEBUG(dbgs() << "SCEV with different offsets: " << *Param << " - "
36053627
<< *V << " = " << *Diff << " % " << EltSize << " = "
@@ -3614,6 +3636,10 @@ static bool checkOffsets(ScalarEvolution *SE, const SCEV *V, const SCEV *&Param,
36143636
const SCEV *Remainder = SE->getURemExpr(Diff, Val);
36153637
if (const SCEVConstant *C = dyn_cast<SCEVConstant>(Remainder))
36163638
if (C->getValue()->isZero())
3639+
// For example test/Analysis/DependenceAnalysis/DADelin.ll
3640+
// SrcSCEV = {{{%A,+,(4 * %m * %o)}<%for.cond1.preheader>,+,(4 * %o)}
3641+
// DstSCEV = {{{%A,+,(4 * %m * %o)}<%for.cond1.preheader>,+,(4 * %o)}
3642+
// The strides '(4 * %m * %o)' and '(4 * %o)' are multiple of 4.
36173643
return true;
36183644

36193645
// Check by using the division computation.
@@ -3625,17 +3651,32 @@ static bool checkOffsets(ScalarEvolution *SE, const SCEV *V, const SCEV *&Param,
36253651
<< *Param << " - " << *V << " = " << *Diff << "\n"
36263652
<< "Remainder = " << *Remainder << "\n"
36273653
<< "Q = " << *Q << " Product = " << *Product << "\n");
3654+
// For example in test/Analysis/DependenceAnalysis/MIVCheckConst.ll
3655+
// SrcSCEV = {(80640 + (4 * (1 + %n) * %v1) + %A),+,(8 * %v1)}<%bb13>
3656+
// DstSCEV = {(126720 + (128 * %m) + %A),+,256}<%bb13>
3657+
// We fail to prove that the offsets 80640 + (4 * (1 + %n) * %v1) and
3658+
// (8 * %v1) are multiples of 128.
3659+
// Param = 80640 + (4 * (1 + %n) * %v1)
3660+
// (80640 + (4 * (1 + %n) * %v1)) - (8 * %v1) =
3661+
// (80640 + ((-4 + (4 * %n)) * %v1))
3662+
// Remainder = (zext i7 ((trunc i32 %v1 to i7) *
3663+
// (-4 + (4 * (trunc i32 %n to i7)))) to i32)
3664+
// Q = ((80640 + ((-4 + (4 * %n)) * %v1)) /u 128)
3665+
// Product = (128 * ((80640 + ((-4 + (4 * %n)) * %v1)) /u 128))<nuw>
36283666
return false;
36293667
};
3668+
36303669
// Expressions like "n".
36313670
if (isa<SCEVUnknown>(V))
36323671
return checkParamsMultipleOfSize(V, Param);
3672+
36333673
// Expressions like "n + 1".
36343674
if (isa<SCEVAddExpr>(V))
36353675
return !SCEVExprContains(V, [](const SCEV *S) {
36363676
return isa<SCEVUnknown>(S);
36373677
}) || checkParamsMultipleOfSize(V, Param);
36383678

3679+
// Expressions like "n * 2".
36393680
if (isa<SCEVMulExpr>(V))
36403681
return !SCEVExprContains(V, [](const SCEV *S) {
36413682
return isa<SCEVUnknown>(S);

0 commit comments

Comments
 (0)