65#define DEBUG_TYPE "da"
71STATISTIC(NonlinearSubscriptPairs,
"Nonlinear subscript pairs");
74STATISTIC(StrongSIVapplications,
"Strong SIV applications");
75STATISTIC(StrongSIVsuccesses,
"Strong SIV successes");
76STATISTIC(StrongSIVindependence,
"Strong SIV independence");
77STATISTIC(WeakCrossingSIVapplications,
"Weak-Crossing SIV applications");
78STATISTIC(WeakCrossingSIVsuccesses,
"Weak-Crossing SIV successes");
79STATISTIC(WeakCrossingSIVindependence,
"Weak-Crossing SIV independence");
80STATISTIC(ExactSIVapplications,
"Exact SIV applications");
82STATISTIC(ExactSIVindependence,
"Exact SIV independence");
83STATISTIC(WeakZeroSIVapplications,
"Weak-Zero SIV applications");
84STATISTIC(WeakZeroSIVsuccesses,
"Weak-Zero SIV successes");
85STATISTIC(WeakZeroSIVindependence,
"Weak-Zero SIV independence");
86STATISTIC(ExactRDIVapplications,
"Exact RDIV applications");
87STATISTIC(ExactRDIVindependence,
"Exact RDIV independence");
91STATISTIC(BanerjeeApplications,
"Banerjee applications");
92STATISTIC(BanerjeeIndependence,
"Banerjee independence");
94STATISTIC(SameSDLoopsCount,
"Loops with Same iteration Space and Depth");
114 "Dependence Analysis",
true,
true)
159struct OverflowSafeSignedAPInt {
160 OverflowSafeSignedAPInt() :
Value(
std::nullopt) {}
161 OverflowSafeSignedAPInt(
const APInt &V) :
Value(V) {}
162 OverflowSafeSignedAPInt(
const std::optional<APInt> &V) :
Value(
V) {}
164 OverflowSafeSignedAPInt
operator+(
const OverflowSafeSignedAPInt &
RHS)
const {
166 return OverflowSafeSignedAPInt();
170 return OverflowSafeSignedAPInt();
171 return OverflowSafeSignedAPInt(Result);
176 return OverflowSafeSignedAPInt();
177 return *
this + fromInt(
RHS);
180 OverflowSafeSignedAPInt
operator-(
const OverflowSafeSignedAPInt &
RHS)
const {
182 return OverflowSafeSignedAPInt();
186 return OverflowSafeSignedAPInt();
187 return OverflowSafeSignedAPInt(Result);
192 return OverflowSafeSignedAPInt();
193 return *
this - fromInt(
RHS);
196 OverflowSafeSignedAPInt
operator*(
const OverflowSafeSignedAPInt &
RHS)
const {
198 return OverflowSafeSignedAPInt();
202 return OverflowSafeSignedAPInt();
203 return OverflowSafeSignedAPInt(Result);
206 OverflowSafeSignedAPInt
operator-()
const {
208 return OverflowSafeSignedAPInt();
209 if (
Value->isMinSignedValue())
210 return OverflowSafeSignedAPInt();
211 return OverflowSafeSignedAPInt(-*
Value);
214 operator bool()
const {
return Value.has_value(); }
223 const APInt *operator->()
const {
231 std::optional<APInt>
Value;
233 OverflowSafeSignedAPInt fromInt(
uint64_t V)
const {
235 return OverflowSafeSignedAPInt(
236 APInt(
Value->getBitWidth(), V,
true));
248 bool NormalizeResults) {
249 auto *
F = DA->getFunction();
253 if (SrcI->mayReadOrWriteMemory()) {
256 if (DstI->mayReadOrWriteMemory()) {
257 OS <<
"Src:" << *SrcI <<
" --> Dst:" << *DstI <<
"\n";
258 OS <<
" da analyze - ";
259 if (
auto D = DA->depends(&*SrcI, &*DstI,
265 for (
unsigned Level = 1; Level <=
D->getLevels(); Level++) {
266 const SCEV *Distance =
D->getDistance(Level);
267 bool IsDistanceZero = Distance && Distance->
isZero();
270 assert(IsDistanceZero == IsDirectionEQ &&
271 "Inconsistent distance and direction.");
276 if (NormalizeResults &&
D->normalize(&SE))
277 OS <<
"normalized - ";
296 OS <<
"Printing analysis 'Dependence Analysis' for function '" <<
F.getName()
309 return Src->mayReadFromMemory() &&
Dst->mayReadFromMemory();
314 return Src->mayWriteToMemory() &&
Dst->mayWriteToMemory();
319 return Src->mayWriteToMemory() &&
Dst->mayReadFromMemory();
324 return Src->mayReadFromMemory() &&
Dst->mayWriteToMemory();
338 bool PossiblyLoopIndependent,
339 unsigned CommonLevels)
340 :
Dependence(Source, Destination, Assumes), Levels(CommonLevels),
341 LoopIndependent(PossiblyLoopIndependent) {
344 DV = std::make_unique<
DVEntry[]>(CommonLevels);
363 for (
unsigned Level = 1; Level <= Levels; ++Level) {
364 unsigned char Direction = DV[Level - 1].Direction;
377 for (
unsigned Level = 1; Level <= Levels; ++Level) {
378 unsigned char Direction = DV[Level - 1].Direction;
386 DV[Level - 1].Direction = RevDirection;
388 if (DV[Level - 1].Distance !=
nullptr)
397 LLVM_DEBUG(
dbgs() <<
"Before normalizing negative direction vectors:\n";
400 LLVM_DEBUG(
dbgs() <<
"After normalizing negative direction vectors:\n";
430 assert(0 < Level && Level <=
static_cast<unsigned>(Levels) + SameSDLevels &&
431 "Level out of range");
432 return Level > Levels;
453 if (SameSDLevels > 0) {
454 OS <<
" / assuming " << SameSDLevels <<
" loop level(s) fused: ";
461 if (!Assumptions.isAlwaysTrue()) {
462 OS <<
" Runtime Assumptions:\n";
463 Assumptions.print(OS, 2);
472 bool OnSameSD =
false;
473 unsigned LevelNum = Levels;
475 LevelNum += SameSDLevels;
477 for (
unsigned II = 1;
II <= LevelNum; ++
II) {
548 return LI->isUnordered();
550 return SI->isUnordered();
558bool DependenceInfo::haveSameSD(
const Loop *SrcLoop,
559 const Loop *DstLoop)
const {
560 if (SrcLoop == DstLoop)
570 const SCEV *SrcUB = SE->getBackedgeTakenCount(SrcLoop);
571 const SCEV *DstUB = SE->getBackedgeTakenCount(DstLoop);
576 SrcUB = SE->getNoopOrZeroExtend(SrcUB, WiderType);
577 DstUB = SE->getNoopOrZeroExtend(DstUB, WiderType);
649void DependenceInfo::establishNestingLevels(
const Instruction *Src,
651 const BasicBlock *SrcBlock = Src->getParent();
652 const BasicBlock *DstBlock = Dst->getParent();
653 unsigned SrcLevel = LI->getLoopDepth(SrcBlock);
654 unsigned DstLevel = LI->getLoopDepth(DstBlock);
655 const Loop *SrcLoop = LI->getLoopFor(SrcBlock);
656 const Loop *DstLoop = LI->getLoopFor(DstBlock);
657 SrcLevels = SrcLevel;
658 MaxLevels = SrcLevel + DstLevel;
660 while (SrcLevel > DstLevel) {
664 while (DstLevel > SrcLevel) {
669 const Loop *SrcUncommonFrontier =
nullptr, *DstUncommonFrontier =
nullptr;
672 while (SrcLoop != DstLoop) {
673 SrcUncommonFrontier = SrcLoop;
674 DstUncommonFrontier = DstLoop;
679 if (SrcUncommonFrontier && DstUncommonFrontier &&
680 haveSameSD(SrcUncommonFrontier, DstUncommonFrontier))
682 CommonLevels = SrcLevel;
683 MaxLevels -= CommonLevels;
688unsigned DependenceInfo::mapSrcLoop(
const Loop *SrcLoop)
const {
694unsigned DependenceInfo::mapDstLoop(
const Loop *DstLoop)
const {
696 if (
D > CommonLevels)
699 return D - CommonLevels + SrcLevels;
726 if (Level <= CommonLevels && !SE->isLoopInvariant(Expression, LoopNest))
738 return isLoopInvariant(Expr, LoopNest);
745 const Loop *
L = LoopNest;
746 while (L && AddRec->
getLoop() != L)
747 L =
L->getParentLoop();
756 if (!isLoopInvariant(Step, LoopNest))
762 return checkSubscript(Start, LoopNest,
Loops, IsSrc);
767bool DependenceInfo::checkSrcSubscript(
const SCEV *Src,
const Loop *
LoopNest,
769 return checkSubscript(Src, LoopNest,
Loops,
true);
774bool DependenceInfo::checkDstSubscript(
const SCEV *Dst,
const Loop *
LoopNest,
776 return checkSubscript(Dst, LoopNest,
Loops,
false);
782DependenceInfo::Subscript::ClassificationKind
783DependenceInfo::classifyPair(
const SCEV *Src,
const Loop *SrcLoopNest,
784 const SCEV *Dst,
const Loop *DstLoopNest,
786 SmallBitVector SrcLoops(MaxLevels + 1);
787 SmallBitVector DstLoops(MaxLevels + 1);
788 if (!checkSrcSubscript(Src, SrcLoopNest, SrcLoops))
789 return Subscript::NonLinear;
790 if (!checkDstSubscript(Dst, DstLoopNest, DstLoops))
791 return Subscript::NonLinear;
794 unsigned N =
Loops.count();
796 return Subscript::ZIV;
798 return Subscript::SIV;
799 if (
N == 2 && SrcLoops.count() == 1 && DstLoops.count() == 1)
800 return Subscript::RDIV;
801 return Subscript::MIV;
811const SCEV *DependenceInfo::collectUpperBound(
const Loop *L,
Type *
T)
const {
812 if (SE->hasLoopInvariantBackedgeTakenCount(L)) {
813 const SCEV *UB = SE->getBackedgeTakenCount(L);
814 return SE->getTruncateOrZeroExtend(UB,
T);
822DependenceInfo::collectNonNegativeConstantUpperBound(
const Loop *L,
824 if (
const SCEV *UB = collectUpperBound(L,
T))
826 APInt Res =
C->getAPInt();
852 return Opts.da_enable_dependence_test ==
Test;
865bool DependenceInfo::testZIV(
const SCEV *Src,
const SCEV *Dst,
913 bool UnderRuntimeAssumptions) {
917 const SCEV *Coeff = Src->getStepRecurrence(*SE);
918 assert(Coeff == Dst->getStepRecurrence(*SE) &&
919 "Expecting same coefficient in Strong SIV test");
920 const SCEV *SrcConst = Src->getStart();
921 const SCEV *DstConst = Dst->getStart();
929 ++StrongSIVapplications;
930 assert(0 < Level && Level <= CommonLevels &&
"level out of range");
943 APInt Distance = ConstDelta;
944 APInt Remainder = ConstDelta;
949 if (Remainder != 0) {
951 ++StrongSIVindependence;
952 ++StrongSIVsuccesses;
955 Result.DV[
Level].Distance = SE->getConstant(Distance);
958 else if (Distance.
slt(0))
962 ++StrongSIVsuccesses;
963 }
else if (Delta->
isZero()) {
967 if (SE->isKnownNonZero(Coeff)) {
969 dbgs() <<
"\t Coefficient proven non-zero by SCEV analysis\n");
972 if (UnderRuntimeAssumptions) {
973 const SCEVPredicate *Pred = SE->getComparePredicate(
975 Result.Assumptions =
Result.Assumptions.getUnionWith(Pred, *SE);
981 LLVM_DEBUG(
dbgs() <<
"\t Would need runtime assumption " << *Coeff
982 <<
" != 0, but not allowed. Failing this test.\n");
989 ++StrongSIVsuccesses;
991 if (Coeff->
isOne()) {
997 bool DeltaMaybeZero = !SE->isKnownNonZero(Delta);
998 bool DeltaMaybePositive = !SE->isKnownNonPositive(Delta);
999 bool DeltaMaybeNegative = !SE->isKnownNonNegative(Delta);
1000 bool CoeffMaybePositive = !SE->isKnownNonPositive(Coeff);
1001 bool CoeffMaybeNegative = !SE->isKnownNonNegative(Coeff);
1006 if ((DeltaMaybePositive && CoeffMaybePositive) ||
1007 (DeltaMaybeNegative && CoeffMaybeNegative))
1011 if ((DeltaMaybeNegative && CoeffMaybePositive) ||
1012 (DeltaMaybePositive && CoeffMaybeNegative))
1014 if (NewDirection <
Result.DV[Level].Direction)
1015 ++StrongSIVsuccesses;
1049bool DependenceInfo::weakCrossingSIVtest(
const SCEVAddRecExpr *Src,
1056 const SCEV *Coeff = Src->getStepRecurrence(*SE);
1057 const SCEV *SrcConst = Src->getStart();
1058 const SCEV *DstConst = Dst->getStart();
1060 assert(Coeff == SE->getNegativeSCEV(Dst->getStepRecurrence(*SE)) &&
1061 "Unexpected input for weakCrossingSIVtest");
1067 ++WeakCrossingSIVapplications;
1068 assert(0 < Level && Level <= CommonLevels &&
"Level out of range");
1083 ConstantRange SrcRange = SE->getSignedRange(Src);
1084 ConstantRange DstRange = SE->getSignedRange(Dst);
1089 Result.DV[
Level].Direction &= ~Dependence::DVEntry::LT;
1090 Result.DV[
Level].Direction &= ~Dependence::DVEntry::GT;
1091 ++WeakCrossingSIVsuccesses;
1092 if (!
Result.DV[Level].Direction) {
1093 ++WeakCrossingSIVindependence;
1101 APInt APDelta = ConstDelta->
getAPInt();
1102 APInt APCoeff = ConstCoeff->
getAPInt();
1103 APInt Distance = APDelta;
1104 APInt Remainder = APDelta;
1107 if (Remainder != 0) {
1109 ++WeakCrossingSIVindependence;
1110 ++WeakCrossingSIVsuccesses;
1118 Result.DV[
Level].Direction &= ~Dependence::DVEntry::EQ;
1119 ++WeakCrossingSIVsuccesses;
1143 APInt A0(Bits, 1,
true), A1(Bits, 0,
true);
1144 APInt B0(Bits, 0,
true), B1(Bits, 1,
true);
1148 return std::nullopt;
1157 APInt A2 = A0 - Q*A1; A0 = A1; A1 = A2;
1158 APInt B2 = B0 - Q*B1; B0 = B1; B1 = B2;
1165 X = AM.
slt(0) ? -A1 : A1;
1166 Y = BM.
slt(0) ? B1 : -B1;
1176static OverflowSafeSignedAPInt
1178 const OverflowSafeSignedAPInt &OB) {
1180 return OverflowSafeSignedAPInt();
1189 if ((
A.sgt(0) &&
B.sgt(0)) || (
A.slt(0) &&
B.slt(0)))
1191 return OverflowSafeSignedAPInt(Q) - 1;
1194static OverflowSafeSignedAPInt
1196 const OverflowSafeSignedAPInt &OB) {
1198 return OverflowSafeSignedAPInt();
1207 if ((
A.sgt(0) &&
B.sgt(0)) || (
A.slt(0) &&
B.slt(0)))
1208 return OverflowSafeSignedAPInt(Q) + 1;
1242static std::pair<OverflowSafeSignedAPInt, OverflowSafeSignedAPInt>
1244 OverflowSafeSignedAPInt UB) {
1245 assert(
A &&
B &&
"A and B must be available");
1246 assert(*
A != 0 &&
"A must be non-zero");
1247 assert((!UB || UB->isNonNegative()) &&
"UB must be non-negative");
1248 OverflowSafeSignedAPInt TL, TU;
1251 LLVM_DEBUG(
if (TL)
dbgs() <<
"\t Possible TL = " << *TL <<
"\n");
1255 LLVM_DEBUG(
if (TU)
dbgs() <<
"\t Possible TU = " << *TU <<
"\n");
1258 LLVM_DEBUG(
if (TU)
dbgs() <<
"\t Possible TU = " << *TU <<
"\n");
1262 LLVM_DEBUG(
if (TL)
dbgs() <<
"\t Possible TL = " << *TL <<
"\n");
1264 return std::make_pair(TL, TU);
1293 ++ExactSIVapplications;
1294 assert(0 < Level && Level <= CommonLevels &&
"Level out of range");
1296 bool Res = exactTestImpl(Src, Dst, Result, Level);
1298 ++ExactSIVsuccesses;
1299 ++ExactSIVindependence;
1309 return ConstDividend.
srem(ConstDivisor) == 0;
1312bool DependenceInfo::weakZeroSIVtestImpl(
const SCEVAddRecExpr *AR,
1313 const SCEV *Const,
unsigned Level,
1316 const SCEV *ARConst = AR->
getStart();
1318 if (Const == ARConst && SE->isKnownNonZero(ARCoeff)) {
1319 if (Level < CommonLevels) {
1321 ++WeakZeroSIVsuccesses;
1333 if (
const SCEV *UpperBound =
1336 bool OverlapAtLast = [&] {
1337 if (!SE->isKnownNonZero(ConstCoeff))
1342 if (OverlapAtLast) {
1344 if (Level < CommonLevels) {
1346 ++WeakZeroSIVsuccesses;
1355 ++WeakZeroSIVindependence;
1356 ++WeakZeroSIVsuccesses;
1391bool DependenceInfo::weakZeroSrcSIVtest(
const SCEV *SrcConst,
1401 [[maybe_unused]]
const SCEV *DstCoeff = Dst->getStepRecurrence(*SE);
1402 [[maybe_unused]]
const SCEV *DstConst = Dst->getStart();
1407 ++WeakZeroSIVapplications;
1408 assert(0 < Level && Level <= MaxLevels &&
"Level out of range");
1417 bool Res = weakZeroSIVtestImpl(Dst, SrcConst, Level, Result);
1451bool DependenceInfo::weakZeroDstSIVtest(
const SCEVAddRecExpr *Src,
1452 const SCEV *DstConst,
unsigned Level,
1459 [[maybe_unused]]
const SCEV *SrcCoeff = Src->getStepRecurrence(*SE);
1460 [[maybe_unused]]
const SCEV *SrcConst = Src->getStart();
1465 ++WeakZeroSIVapplications;
1466 assert(0 < Level && Level <= SrcLevels &&
"Level out of range");
1469 return weakZeroSIVtestImpl(Src, DstConst, Level, Result);
1485 ++ExactRDIVapplications;
1486 bool Res = exactTestImpl(Src, Dst, Result, std::nullopt);
1488 ++ExactRDIVindependence;
1495 std::optional<unsigned> Level)
const {
1496 const SCEV *SrcCoeff = Src->getStepRecurrence(*SE);
1497 const SCEV *SrcConst = Src->getStart();
1498 const SCEV *DstCoeff = Dst->getStepRecurrence(*SE);
1499 const SCEV *DstConst = Dst->getStart();
1512 if (!ConstDelta || !ConstSrcCoeff || !ConstDstCoeff)
1517 APInt AM = ConstSrcCoeff->
getAPInt();
1518 APInt BM = ConstDstCoeff->
getAPInt();
1521 std::optional<bool> GCDRes =
findGCD(Bits, AM, BM, CM,
G,
X,
Y);
1534 std::optional<APInt> SrcUM =
1535 collectNonNegativeConstantUpperBound(Src->getLoop(), Delta->
getType());
1539 std::optional<APInt> DstUM =
1540 collectNonNegativeConstantUpperBound(Dst->getLoop(), Delta->
getType());
1544 OverflowSafeSignedAPInt TC = CM.
sdiv(
G);
1545 OverflowSafeSignedAPInt TX = OverflowSafeSignedAPInt(
X) * TC;
1546 OverflowSafeSignedAPInt TY = OverflowSafeSignedAPInt(
Y) * TC;
1547 if (!TC || !TX || !TY)
1571 auto GetMaxOrMin = [](
const OverflowSafeSignedAPInt &
V0,
1572 const OverflowSafeSignedAPInt &
V1,
1573 bool IsMin) -> std::optional<APInt> {
1580 return std::nullopt;
1583 std::optional<APInt> OptTL = GetMaxOrMin(TL0, TL1,
false);
1584 std::optional<APInt> OptTU = GetMaxOrMin(TU0, TU1,
true);
1585 if (!OptTL || !OptTU)
1588 APInt TL = std::move(*OptTL);
1589 APInt TU = std::move(*OptTU);
1598 assert(SrcUM == DstUM &&
"Expecting same upper bound for Src and Dst");
1602 OverflowSafeSignedAPInt LowerDistance, UpperDistance;
1603 OverflowSafeSignedAPInt OTY(TY), OTX(TX), OTA(TA), OTB(TB), OTL(TL), OTU(TU);
1607 LowerDistance = (OTY - OTX) + (OTA - OTB) * OTL;
1608 UpperDistance = (OTY - OTX) + (OTA - OTB) * OTU;
1610 LowerDistance = (OTY - OTX) + (OTA - OTB) * OTU;
1611 UpperDistance = (OTY - OTX) + (OTA - OTB) * OTL;
1614 if (!LowerDistance || !UpperDistance)
1617 LLVM_DEBUG(
dbgs() <<
"\t LowerDistance = " << *LowerDistance <<
"\n");
1618 LLVM_DEBUG(
dbgs() <<
"\t UpperDistance = " << *UpperDistance <<
"\n");
1620 if (LowerDistance->sle(0) && UpperDistance->sge(0))
1622 if (LowerDistance->slt(0))
1624 if (UpperDistance->sgt(0))
1642bool DependenceInfo::testSIV(
const SCEV *Src,
const SCEV *Dst,
unsigned &Level,
1644 bool UnderRuntimeAssumptions) {
1649 if (SrcAddRec && DstAddRec) {
1653 [[maybe_unused]]
const Loop *CurDstLoop = DstAddRec->
getLoop();
1654 assert(haveSameSD(CurSrcLoop, CurDstLoop) &&
1655 "Loops in the SIV test should have the same iteration space and "
1657 Level = mapSrcLoop(CurSrcLoop);
1658 bool disproven =
false;
1659 if (SrcCoeff == DstCoeff)
1660 disproven = strongSIVtest(SrcAddRec, DstAddRec, Level, Result,
1661 UnderRuntimeAssumptions);
1662 else if (SrcCoeff == SE->getNegativeSCEV(DstCoeff))
1663 disproven = weakCrossingSIVtest(SrcAddRec, DstAddRec, Level, Result);
1664 return disproven || exactSIVtest(SrcAddRec, DstAddRec, Level, Result);
1668 Level = mapSrcLoop(CurSrcLoop);
1669 return weakZeroDstSIVtest(SrcAddRec, Dst, Level, Result);
1673 Level = mapDstLoop(CurDstLoop);
1674 return weakZeroSrcSIVtest(Src, DstAddRec, Level, Result);
1690bool DependenceInfo::testRDIV(
const SCEV *Src,
const SCEV *Dst,
1696 assert(SrcAddRec && DstAddRec &&
"Unexpected non-addrec input");
1697 return exactRDIVtest(SrcAddRec, DstAddRec, Result) ||
1698 gcdMIVtest(Src, Dst, Result);
1704bool DependenceInfo::testMIV(
const SCEV *Src,
const SCEV *Dst,
1709 return gcdMIVtest(Src, Dst, Result) ||
1710 banerjeeMIVtest(Src, Dst,
Loops, Result);
1723 if (Product->hasNoSignedWrap())
1725 return std::nullopt;
1728const SCEV *DependenceInfo::accumulateCoefficientsGCD(
const SCEV *Expr,
1729 const Loop *CurLoop,
1730 const SCEV *&CurLoopCoeff,
1731 APInt &RunningGCD)
const {
1734 assert(isLoopInvariant(Expr, CurLoop) &&
1735 "Expected loop invariant expression");
1742 if (AddRec->
getLoop() == CurLoop) {
1743 CurLoopCoeff = Step;
1757 return accumulateCoefficientsGCD(Start, CurLoop, CurLoopCoeff, RunningGCD);
1777bool DependenceInfo::gcdMIVtest(
const SCEV *Src,
const SCEV *Dst,
1784 unsigned BitWidth = SE->getTypeSizeInBits(Src->getType());
1787 const SCEV *Dummy =
nullptr;
1788 const SCEV *SrcConst =
1789 accumulateCoefficientsGCD(Src,
nullptr, Dummy, RunningGCD);
1792 const SCEV *DstConst =
1793 accumulateCoefficientsGCD(Dst,
nullptr, Dummy, RunningGCD);
1804 APInt ConstDelta =
Constant->getAPInt();
1806 if (ConstDelta == 0)
1809 APInt Remainder = ConstDelta.
srem(RunningGCD);
1810 if (Remainder != 0) {
1824 bool Improved =
false;
1825 const SCEV *Coefficients = Src;
1826 while (
const SCEVAddRecExpr *AddRec =
1832 const SCEV *DstCoeff = SE->getZero(SrcCoeff->
getType());
1834 if (!accumulateCoefficientsGCD(Src, CurLoop, SrcCoeff, RunningGCD) ||
1835 !accumulateCoefficientsGCD(Dst, CurLoop, DstCoeff, RunningGCD))
1850 if (RunningGCD != 0) {
1851 Remainder = ConstDelta.
srem(RunningGCD);
1853 if (Remainder != 0) {
1854 unsigned Level = mapSrcLoop(CurLoop);
1855 Result.DV[
Level - 1].Direction &= ~Dependence::DVEntry::EQ;
1874struct BanerjeeInterval {
1878 BanerjeeInterval(
const SCEV *
Lower,
const SCEV *
Upper)
1881 bool isEmpty(ScalarEvolution &SE)
const {
1891 const BanerjeeInterval &
B,
1895 if (
A.Lower &&
B.Lower)
1897 if (
A.Upper &&
B.Upper)
1906 const BanerjeeInterval &
B,
1919 return BanerjeeInterval(
C,
C);
1937 return BanerjeeInterval(SE.
getSMinExpr(LowerValue, UpperValue),
1950 return BanerjeeInterval(
nullptr, Zero);
1952 return BanerjeeInterval(Zero,
nullptr);
1953 return BanerjeeInterval(
nullptr,
nullptr);
2014 assert(!
Values.empty() &&
"expected at least one value");
2038 for (
const SCEV *Subscript : {Src, Dst}) {
2066bool DependenceInfo::banerjeeMIVtest(
const SCEV *Src,
const SCEV *Dst,
2073 ++BanerjeeApplications;
2076 unsigned BaseBits = SE->getTypeSizeInBits(
BaseType);
2086 unsigned WideBits = 2 * BaseBits + MaxLevels + 1;
2088 const SCEV *
Zero = SE->getZero(WideType);
2090 CoefficientInfo EmptyCoeff{
Zero,
Zero,
nullptr};
2092 assert(
Loops.size() > MaxLevels &&
"loop bit vector is too small");
2094 "direction vector is too small for common levels");
2096 const SCEV *A0 = collectCoeffInfo(Src,
true, WideType, CI);
2097 const SCEV *
B0 = collectCoeffInfo(Dst,
false, WideType, CI);
2098 const SCEV *Delta = SE->getMinusSCEV(B0, A0);
2102 for (
unsigned K = 0;
K <= MaxLevels; ++
K) {
2106 for (
unsigned K = 1;
K <= MaxLevels; ++
K) {
2107 findBoundsALL(CI, Bound, K);
2108 findBoundsLT(CI, Bound, K);
2109 findBoundsEQ(CI, Bound, K);
2110 findBoundsGT(CI, Bound, K);
2114 ++BanerjeeIndependence;
2118 unsigned NewDeps = exploreDirections(1, Bound,
Loops, Delta, Result);
2120 ++BanerjeeIndependence;
2124 bool Improved =
false;
2125 for (
unsigned K = 1;
K <= CommonLevels; ++
K) {
2128 unsigned Old =
Result.DV[
K - 1].Direction;
2129 Result.DV[
K - 1].Direction = Old & Bound[
K].DirSet;
2130 Improved |= Old !=
Result.DV[
K - 1].Direction;
2131 if (!
Result.DV[K - 1].Direction) {
2132 ++BanerjeeIndependence;
2138 ++BanerjeeSuccesses;
2147DependenceInfo::collectCoeffInfo(
const SCEV *Subscript,
bool SrcFlag,
2150 SmallBitVector SeenLevels(MaxLevels + 1);
2153 SrcFlag ? mapSrcLoop(AddRec->
getLoop()) : mapDstLoop(AddRec->getLoop());
2154 assert(K > 0 && K <= MaxLevels &&
"invalid mapped loop level");
2155 assert(!SeenLevels[K] &&
"duplicate recurrence for loop level");
2159 const SCEV *&Coeff = SrcFlag ? CI[
K].SrcCoeff : CI[
K].DstCoeff;
2160 Coeff = SE->getNoopOrSignExtend(Step, WideType);
2162 const SCEV *MaxIterIndex = SE->getBackedgeTakenCount(AddRec->
getLoop());
2168 CI[
K].MaxIterIndex =
2169 SE->isKnownNonNegative(MaxIterIndex)
2170 ? SE->getNoopOrSignExtend(MaxIterIndex, WideType)
2171 : SE->getNoopOrZeroExtend(MaxIterIndex, WideType);
2176 return SE->getNoopOrSignExtend(Subscript, WideType);
2181 const SCEV *Sum = Bound[1].Lower[Bound[1].Direction];
2182 for (
unsigned K = 2; Sum &&
K <= MaxLevels; ++
K) {
2192 const SCEV *Sum = Bound[1].Upper[Bound[1].Direction];
2193 for (
unsigned K = 2; Sum &&
K <= MaxLevels; ++
K) {
2203bool DependenceInfo::testBounds(
unsigned char DirKind,
unsigned Level,
2205 const SCEV *Delta)
const {
2206 Bound[
Level].Direction = DirKind;
2207 for (
unsigned K = 1;
K <= MaxLevels; ++
K) {
2208 unsigned char Direction = Bound[
K].Direction;
2214 if (
const SCEV *
Lower = getLowerBound(Bound))
2217 if (
const SCEV *
Upper = getUpperBound(Bound))
2224unsigned DependenceInfo::exploreDirections(
unsigned Level,
2229 if (CommonLevels > Opts.da_miv_max_level_threshold) {
2230 LLVM_DEBUG(
dbgs() <<
"Number of common levels exceeded the threshold. MIV "
2231 "direction exploration is terminated.\n");
2232 for (
unsigned K = 1;
K <= CommonLevels; ++
K)
2238 if (Level > CommonLevels) {
2239 for (
unsigned K = 1;
K <= CommonLevels; ++
K)
2241 Bound[
K].DirSet |= Bound[
K].Direction;
2246 return exploreDirections(Level + 1, Bound,
Loops, Delta, Result);
2248 unsigned NewDeps = 0;
2249 unsigned OldDirections =
Result.DV[
Level - 1].Direction;
2252 if (!(OldDirections & Dir))
2254 if (testBounds(Dir, Level, Bound, Delta))
2255 NewDeps += exploreDirections(Level + 1, Bound,
Loops, Delta, Result);
2279 BanerjeeInterval SrcInterval =
2282 SE->getNegativeSCEV(CI[K].DstCoeff), CI[K].MaxIterIndex, *SE);
2301 CI[K].MaxIterIndex, *SE);
2322 const SCEV *ACoeff = CI[
K].SrcCoeff;
2323 const SCEV *BCoeff = CI[
K].DstCoeff;
2324 const SCEV *MaxIterIndex = CI[
K].MaxIterIndex;
2328 if (MaxIterIndex && MaxIterIndex->
isZero()) {
2330 }
else if (MaxIterIndex) {
2331 const SCEV *
Zero = SE->getZero(ACoeff->
getType());
2332 const SCEV *One = SE->getOne(ACoeff->
getType());
2333 const SCEV *MaxMinusOne = SE->getMinusSCEV(MaxIterIndex, One);
2340 MaxIterIndex, *SE));
2364 const SCEV *ACoeff = CI[
K].SrcCoeff;
2365 const SCEV *BCoeff = CI[
K].DstCoeff;
2366 const SCEV *MaxIterIndex = CI[
K].MaxIterIndex;
2370 if (MaxIterIndex && MaxIterIndex->
isZero()) {
2372 }
else if (MaxIterIndex) {
2373 const SCEV *
Zero = SE->getZero(ACoeff->
getType());
2374 const SCEV *One = SE->getOne(ACoeff->
getType());
2375 const SCEV *MaxMinusOne = SE->getMinusSCEV(MaxIterIndex, One);
2400 Loop *SrcLoop = LI->getLoopFor(Src->getParent());
2401 Loop *DstLoop = LI->getLoopFor(Dst->getParent());
2402 const SCEV *SrcAccessFn = SE->getSCEVAtScope(SrcPtr, SrcLoop);
2403 const SCEV *DstAccessFn = SE->getSCEVAtScope(DstPtr, DstLoop);
2404 const SCEVUnknown *SrcBase =
2406 const SCEVUnknown *DstBase =
2409 if (!SrcBase || !DstBase || SrcBase != DstBase)
2414 if (!tryDelinearizeFixedSize(Src, Dst, SrcAccessFn, DstAccessFn,
2415 SrcSubscripts, DstSubscripts) &&
2416 !tryDelinearizeParametricSize(Src, Dst, SrcAccessFn, DstAccessFn,
2417 SrcSubscripts, DstSubscripts))
2420 assert(isLoopInvariant(SrcBase, SrcLoop) &&
2421 isLoopInvariant(DstBase, DstLoop) &&
2422 "Expected SrcBase and DstBase to be loop invariant");
2426 dbgs() <<
"\nSrcSubscripts: ";
2427 for (
int I = 0;
I <
Size;
I++)
2428 dbgs() << *SrcSubscripts[
I];
2429 dbgs() <<
"\nDstSubscripts: ";
2430 for (
int I = 0;
I <
Size;
I++)
2431 dbgs() << *DstSubscripts[
I];
2440 for (
int I = 0;
I <
Size; ++
I) {
2441 Pair[
I].Src = SrcSubscripts[
I];
2442 Pair[
I].Dst = DstSubscripts[
I];
2444 assert(Pair[
I].Src->getType() == Pair[
I].Dst->getType() &&
2445 "Unexpected different types for the subscripts");
2454bool DependenceInfo::tryDelinearizeFixedSize(
2459 const SCEVUnknown *SrcBase =
2461 const SCEVUnknown *DstBase =
2463 assert(SrcBase && DstBase && SrcBase == DstBase &&
2464 "expected src and dst scev unknowns to be equal");
2467 const SCEV *ElemSize = SE->getElementSize(Src);
2468 assert(ElemSize == SE->getElementSize(Dst) &&
"Different element sizes");
2471 SrcSubscripts, SrcSizes, ElemSize) ||
2473 DstSubscripts, DstSizes, ElemSize))
2478 if (SrcSizes.
size() != DstSizes.
size() ||
2479 !std::equal(SrcSizes.
begin(), SrcSizes.
end(), DstSizes.
begin())) {
2480 SrcSubscripts.
clear();
2481 DstSubscripts.
clear();
2486 "Expected equal number of entries in the list of SrcSubscripts and "
2495 if (Opts.da_delinearization_checks) {
2498 SrcSubscripts.
clear();
2499 DstSubscripts.
clear();
2504 dbgs() <<
"Delinearized subscripts of fixed-size array\n"
2511bool DependenceInfo::tryDelinearizeParametricSize(
2516 const SCEVUnknown *SrcBase =
2518 const SCEVUnknown *DstBase =
2520 assert(SrcBase && DstBase && SrcBase == DstBase &&
2521 "expected src and dst scev unknowns to be equal");
2523 const SCEV *ElementSize = SE->getElementSize(Src);
2524 if (ElementSize != SE->getElementSize(Dst))
2527 const SCEV *SrcSCEV = SE->getMinusSCEV(SrcAccessFn, SrcBase);
2528 const SCEV *DstSCEV = SE->getMinusSCEV(DstAccessFn, DstBase);
2549 if (SrcSubscripts.
size() < 2 || DstSubscripts.
size() < 2 ||
2550 SrcSubscripts.
size() != DstSubscripts.
size())
2559 if (Opts.da_delinearization_checks)
2573 for (
unsigned VI : BV.
set_bits()) {
2583 FunctionAnalysisManager::Invalidator &Inv) {
2590 return Inv.invalidate<
AAManager>(F, PA) ||
2604std::unique_ptr<Dependence>
2606 bool UnderRuntimeAssumptions) {
2608 bool PossiblyLoopIndependent =
true;
2610 PossiblyLoopIndependent =
false;
2612 if (!(Src->mayReadOrWriteMemory() && Dst->mayReadOrWriteMemory()))
2618 LLVM_DEBUG(
dbgs() <<
"can only handle simple loads and stores\n");
2619 return std::make_unique<Dependence>(Src, Dst,
2631 return std::make_unique<Dependence>(Src, Dst,
2645 LLVM_DEBUG(
dbgs() <<
"can't analyze must alias with different sizes\n");
2646 return std::make_unique<Dependence>(Src, Dst,
2652 const SCEV *SrcSCEV = SE->getSCEV(SrcPtr);
2653 const SCEV *DstSCEV = SE->getSCEV(DstPtr);
2656 const SCEV *SrcBase = SE->getPointerBase(SrcSCEV);
2657 const SCEV *DstBase = SE->getPointerBase(DstSCEV);
2658 if (SrcBase != DstBase) {
2665 LLVM_DEBUG(
dbgs() <<
"can't analyze SCEV with different pointer base\n");
2666 return std::make_unique<Dependence>(Src, Dst,
2674 Loop *SrcLoop = LI->getLoopFor(Src->getParent());
2675 Loop *DstLoop = LI->getLoopFor(Dst->getParent());
2676 if (!isLoopInvariant(SrcBase, SrcLoop) ||
2677 !isLoopInvariant(DstBase, DstLoop)) {
2678 LLVM_DEBUG(
dbgs() <<
"The base pointer is not loop invariant.\n");
2679 return std::make_unique<Dependence>(Src, Dst,
2684 const SCEV *SrcEv = SE->getMinusSCEV(SrcSCEV, SrcBase);
2685 const SCEV *DstEv = SE->getMinusSCEV(DstSCEV, DstBase);
2689 if (!SE->isKnownMultipleOf(SrcEv, EltSize,
2690 UnderRuntimeAssumptions ? &Assume :
nullptr) ||
2691 !SE->isKnownMultipleOf(DstEv, EltSize,
2692 UnderRuntimeAssumptions ? &Assume :
nullptr)) {
2693 LLVM_DEBUG(
dbgs() <<
"can't analyze SCEV with different offsets\n");
2694 return std::make_unique<Dependence>(Src, Dst,
2700 Pair[0].Src = SrcEv;
2701 Pair[0].Dst = DstEv;
2702 if (Opts.da_delinearize) {
2703 if (tryDelinearize(Src, Dst, Pair)) {
2705 Pairs = Pair.
size();
2710 establishNestingLevels(Src, Dst);
2712 LLVM_DEBUG(
dbgs() <<
" common nesting levels = " << CommonLevels <<
"\n");
2713 LLVM_DEBUG(
dbgs() <<
" maximum nesting levels = " << MaxLevels <<
"\n");
2714 LLVM_DEBUG(
dbgs() <<
" SameSD nesting levels = " << SameSDLevels <<
"\n");
2717 CommonLevels += SameSDLevels;
2718 MaxLevels -= SameSDLevels;
2719 if (SameSDLevels > 0) {
2722 for (
unsigned P = 0;
P < Pairs; ++
P) {
2724 Subscript::ClassificationKind TestClass =
2725 classifyPair(Pair[
P].Src, SrcLoop, Pair[
P].Dst, DstLoop,
Loops);
2727 if (TestClass != Subscript::ZIV && TestClass != Subscript::SIV &&
2728 TestClass != Subscript::RDIV) {
2730 CommonLevels -= SameSDLevels;
2731 MaxLevels += SameSDLevels;
2738 if (SameSDLevels > 0)
2742 PossiblyLoopIndependent, CommonLevels);
2745 for (
unsigned P = 0;
P < Pairs; ++
P) {
2746 assert(Pair[
P].Src->getType()->isIntegerTy() &&
"Src must be an integer");
2747 assert(Pair[
P].Dst->getType()->isIntegerTy() &&
"Dst must be an integer");
2748 Pair[
P].Loops.
resize(MaxLevels + 1);
2749 Pair[
P].Classification =
2750 classifyPair(Pair[
P].Src, SrcLoop, Pair[
P].Dst, DstLoop, Pair[
P].
Loops);
2760 for (
unsigned SI = 0;
SI < Pairs; ++
SI) {
2769 switch (Pair[
SI].Classification) {
2770 case Subscript::NonLinear:
2772 ++NonlinearSubscriptPairs;
2773 collectCommonLoops(Pair[
SI].Src, SrcLoop, Pair[
SI].
Loops);
2774 collectCommonLoops(Pair[
SI].Dst, DstLoop, Pair[
SI].
Loops);
2776 case Subscript::ZIV:
2778 if (testZIV(Pair[
SI].Src, Pair[
SI].Dst, Result))
2781 case Subscript::SIV: {
2784 if (testSIV(Pair[
SI].Src, Pair[
SI].Dst, Level, Result,
2785 UnderRuntimeAssumptions))
2789 case Subscript::RDIV:
2791 if (testRDIV(Pair[
SI].Src, Pair[
SI].Dst, Result))
2794 case Subscript::MIV:
2796 if (testMIV(Pair[
SI].Src, Pair[
SI].Dst, Pair[
SI].
Loops, Result))
2804 for (
unsigned SI = 0;
SI < Pairs; ++
SI)
2805 CompleteLoops |= Pair[
SI].
Loops;
2806 for (
unsigned II = 1;
II <= CommonLevels; ++
II)
2807 if (CompleteLoops[
II])
2808 Result.DV[
II - 1].Scalar =
false;
2813 for (
unsigned II = 1;
II <= Result.getLevels(); ++
II) {
2815 if (Result.DV[
II - 1].Distance ==
nullptr)
2816 Result.DV[
II - 1].Distance = SE->getZero(SrcSCEV->
getType());
2818 assert(Result.DV[
II - 1].Distance->isZero() &&
2819 "Inconsistency between distance and direction");
2825 const SCEV *Distance = Result.getDistance(
II);
2826 if (Distance && Distance->
isZero())
2828 "Distance is zero, but direction is not EQ");
2832 if (SameSDLevels > 0) {
2835 assert(CommonLevels >= SameSDLevels);
2836 CommonLevels -= SameSDLevels;
2837 MaxLevels += SameSDLevels;
2838 std::unique_ptr<FullDependence::DVEntry[]> DV, DVSameSD;
2839 DV = std::make_unique<FullDependence::DVEntry[]>(CommonLevels);
2840 DVSameSD = std::make_unique<FullDependence::DVEntry[]>(SameSDLevels);
2841 for (
unsigned Level = 0; Level < CommonLevels; ++Level)
2842 DV[Level] = Result.DV[Level];
2843 for (
unsigned Level = 0; Level < SameSDLevels; ++Level)
2844 DVSameSD[Level] = Result.DV[CommonLevels + Level];
2845 Result.DV = std::move(DV);
2846 Result.DVSameSD = std::move(DVSameSD);
2847 Result.Levels = CommonLevels;
2848 Result.SameSDLevels = SameSDLevels;
2851 if (PossiblyLoopIndependent) {
2855 for (
unsigned II = 1;
II <= CommonLevels; ++
II) {
2857 Result.LoopIndependent =
false;
2865 bool AllEqual =
true;
2866 for (
unsigned II = 1;
II <= CommonLevels; ++
II) {
2872 if (AllEqual && Result.Assumptions.getPredicates().empty())
2876 return std::make_unique<FullDependence>(std::move(Result));
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static bool isLoadOrStore(const Instruction *I)
static std::optional< bool > findGCD(unsigned Bits, const APInt &AM, const APInt &BM, const APInt &Delta, APInt &G, APInt &X, APInt &Y)
static OverflowSafeSignedAPInt floorOfQuotient(const OverflowSafeSignedAPInt &OA, const OverflowSafeSignedAPInt &OB)
static void dumpExampleDependence(raw_ostream &OS, DependenceInfo *DA, ScalarEvolution &SE, LoopInfo &LI, bool NormalizeResults)
static OverflowSafeSignedAPInt ceilingOfQuotient(const OverflowSafeSignedAPInt &OA, const OverflowSafeSignedAPInt &OB)
static void dumpSmallBitVector(SmallBitVector &BV)
static BanerjeeInterval emptyInterval(Type *Ty, ScalarEvolution &SE)
Return the canonical empty interval [1, 0].
static std::pair< OverflowSafeSignedAPInt, OverflowSafeSignedAPInt > inferDomainOfAffine(OverflowSafeSignedAPInt A, OverflowSafeSignedAPInt B, OverflowSafeSignedAPInt UB)
Given an affine expression of the form A*k + B, where k is an arbitrary integer, infer the possible r...
static const SCEV * minusSCEVNoSignedOverflow(const SCEV *A, const SCEV *B, ScalarEvolution &SE)
Returns A - B if it guaranteed not to signed wrap.
static AliasResult underlyingObjectsAlias(AAResults *AA, const DataLayout &DL, const MemoryLocation &LocA, const MemoryLocation &LocB)
static BanerjeeInterval constantInterval(const SCEV *C)
Return the singleton interval containing C.
static Type * getBanerjeeBaseType(const SCEV *Src, const SCEV *Dst, ScalarEvolution &SE)
Return the widest type used by a subscript or by an exact backedge-taken count of one of its recurren...
static BanerjeeInterval variableInterval(const SCEV *Coeff, const SCEV *Upper, ScalarEvolution &SE)
Compute the range of Coeff * X for 0 <= X <= Upper.
static std::optional< APInt > getConstantCoefficient(const SCEV *Expr)
Given a SCEVMulExpr, returns its first operand if its first operand is a constant and the product doe...
static BanerjeeInterval strictDirectionIntervalWithUnknownUpperBound(const SCEV *ACoeff, const SCEV *BCoeff, unsigned char Direction, ScalarEvolution &SE)
Compute any finite one-sided bound on.
static const SCEV * evaluateSubscriptDifference(const SCEV *A, const SCEV *SrcIndex, const SCEV *B, const SCEV *DstIndex, ScalarEvolution &SE)
Evaluate one loop level's contribution A * SrcIndex - B * DstIndex to the complete source-minus-desti...
static bool isRemainderZero(const SCEVConstant *Dividend, const SCEVConstant *Divisor)
static BanerjeeInterval signedRangeInterval(const SCEV *Coeff, const SCEV *Lower, const SCEV *Upper, ScalarEvolution &SE)
Compute the range of Coeff * X for Lower <=s X <=s Upper.
static BanerjeeInterval intervalFromValues(ArrayRef< const SCEV * > Values, ScalarEvolution &SE)
Return the smallest closed interval containing Values.
static bool isDependenceTestEnabled(const AnalysisOptions &Opts, DependenceTestType Test)
Returns true iff Test is enabled.
static BanerjeeInterval addIntervals(const BanerjeeInterval &A, const BanerjeeInterval &B, ScalarEvolution &SE)
Add two intervals.
static BanerjeeInterval intersectIntervals(const BanerjeeInterval &A, const BanerjeeInterval &B, ScalarEvolution &SE)
Intersect two intervals.
Module.h This file contains the declarations for the Module class.
Loop::LoopBounds::Direction Direction
std::pair< uint64_t, uint64_t > Interval
uint64_t IntrinsicInst * II
FunctionAnalysisManager FAM
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
BaseType
A given derived pointer can have multiple base pointers through phi/selects.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
A manager for alias analyses.
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object.
Class for arbitrary precision integers.
bool isMinSignedValue() const
Determine if this is the smallest signed value.
static LLVM_ABI void sdivrem(const APInt &LHS, const APInt &RHS, APInt &Quotient, APInt &Remainder)
APInt abs() const
Get the absolute value.
bool sgt(const APInt &RHS) const
Signed greater than comparison.
unsigned getBitWidth() const
Return the number of bits in the APInt.
LLVM_ABI APInt sdiv(const APInt &RHS) const
Signed division function for APInt.
LLVM_ABI APInt srem(const APInt &RHS) const
Function for signed remainder operation.
bool isNonNegative() const
Determine if this APInt Value is non-negative (>= 0)
bool slt(const APInt &RHS) const
Signed less than comparison.
static APInt getZero(unsigned numBits)
Get the '0' value for the specified bit-width.
The possible results of an alias query.
@ MayAlias
The two locations may or may not alias.
@ NoAlias
The two locations do not alias at all.
@ PartialAlias
The two locations alias, but only due to a partial overlap.
@ MustAlias
The two locations precisely alias each other.
This templated class represents "all analyses that operate over <aparticular IR unit>" (e....
Represent the analysis usage information of a pass.
void setPreservesAll()
Set by analyses that do not transform their input at all.
AnalysisUsage & addRequiredTransitive()
Represent a constant reference to an array (0 or more elements consecutively in memory),...
This class is a wrapper over an AAResults, and it is intended to be used only when there are no IR ch...
void enableCrossIterationMode()
Assume that values may come from different cycle iterations.
bool isNoAlias(const MemoryLocation &LocA, const MemoryLocation &LocB)
@ ICMP_SGT
signed greater than
This class represents a range of values.
LLVM_ABI bool isEmptySet() const
Return true if this set contains no members.
bool isSingleElement() const
Return true if this set contains exactly one member.
LLVM_ABI ConstantRange intersectWith(const ConstantRange &CR, PreferredRangeType Type=Smallest) const
Return the range that results from the intersection of this range with another range.
This is an important base class in LLVM.
A parsed version of the target data layout string in and methods for querying it.
Legacy pass manager pass to access dependence information.
void getAnalysisUsage(AnalysisUsage &) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
bool runOnFunction(Function &F) override
runOnFunction - Virtual method overriden by subclasses to do the per-function processing of the pass.
void print(raw_ostream &, const Module *=nullptr) const override
print - Print out the internal state of the pass.
DependenceInfo & getDI() const
DependenceAnalysisWrapperPass()
void releaseMemory() override
releaseMemory() - This member can be implemented by a pass if it wants to be able to release its memo...
AnalysisPass to compute dependence information in a function.
LLVM_ABI Result run(Function &F, FunctionAnalysisManager &FAM)
DependenceInfo - This class is the main dependence-analysis driver.
LLVM_ABI bool invalidate(Function &F, const PreservedAnalyses &PA, FunctionAnalysisManager::Invalidator &Inv)
Handle transitive invalidation when the cached analysis results go away.
LLVM_ABI DependenceInfo(Function *F, AAResults *AA, ScalarEvolution *SE, LoopInfo *LI)
LLVM_ABI std::unique_ptr< Dependence > depends(Instruction *Src, Instruction *Dst, bool UnderRuntimeAssumptions=false)
depends - Tests for a dependence between the Src and Dst instructions.
void dumpImp(raw_ostream &OS, bool IsSameSD=false) const
dumpImp - For debugging purposes.
Dependence(Dependence &&)=default
SCEVUnionPredicate getRuntimeAssumptions() const
getRuntimeAssumptions - Returns the runtime assumptions under which this Dependence relation is valid...
virtual bool isConfused() const
isConfused - Returns true if this dependence is confused (the compiler understands nothing and makes ...
virtual unsigned getSameSDLevels() const
getSameSDLevels - Returns the number of separate SameSD loops surrounding the source and destination ...
virtual const SCEV * getDistance(unsigned Level, bool SameSD=false) const
getDistance - Returns the distance (or NULL) associated with a particular common or SameSD level.
virtual unsigned getLevels() const
getLevels - Returns the number of common loops surrounding the source and destination of the dependen...
virtual unsigned getDirection(unsigned Level, bool SameSD=false) const
getDirection - Returns the direction associated with a particular common or SameSD level.
virtual bool isScalar(unsigned Level, bool SameSD=false) const
isScalar - Returns true if a particular regular or SameSD level is scalar; that is,...
bool isFlow() const
isFlow - Returns true if this is a flow (aka true) dependence.
bool isInput() const
isInput - Returns true if this is an input dependence.
bool isAnti() const
isAnti - Returns true if this is an anti dependence.
virtual bool isLoopIndependent() const
isLoopIndependent - Returns true if this is a loop-independent dependence.
bool isOutput() const
isOutput - Returns true if this is an output dependence.
void dump(raw_ostream &OS) const
dump - For debugging purposes, dumps a dependence to OS.
virtual bool inSameSDLoops(unsigned Level) const
inSameSDLoops - Returns true if this level is an SameSD level, i.e., performed across two separate lo...
Class representing an expression and its matching format.
FullDependence - This class represents a dependence between two memory references in a function.
FullDependence(Instruction *Source, Instruction *Destination, const SCEVUnionPredicate &Assumes, bool PossiblyLoopIndependent, unsigned Levels)
unsigned getDirection(unsigned Level, bool SameSD=false) const override
getDirection - Returns the direction associated with a particular common or SameSD level.
bool isScalar(unsigned Level, bool SameSD=false) const override
isScalar - Returns true if a particular regular or SameSD level is scalar; that is,...
bool isDirectionNegative() const override
Check if the direction vector is negative.
void negate(ScalarEvolution &SE) override
Negate the dependence by swapping the source and destination, and reversing the direction and distanc...
const SCEV * getDistance(unsigned Level, bool SameSD=false) const override
getDistance - Returns the distance (or NULL) associated with a particular common or SameSD level.
DVEntry getDVEntry(unsigned Level, bool IsSameSD) const
getDVEntry - Returns the DV entry associated with a regular or a SameSD level.
bool inSameSDLoops(unsigned Level) const override
inSameSDLoops - Returns true if this level is an SameSD level, i.e., performed across two separate lo...
bool normalize(ScalarEvolution *SE) override
If the direction vector is negative, normalize the direction vector to make it non-negative.
FunctionPass class - This class is used to implement most global optimizations.
static LLVM_ABI IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
An instruction for reading from memory.
Analysis pass that exposes the LoopInfo for a function.
BlockT * getLoopLatch() const
If there is a single latch block for this loop, return it.
const LoopT * getOutermostLoop() const
Get the outermost loop in which this loop is contained.
unsigned getLoopDepth() const
Return the nesting level of this loop.
LoopT * getParentLoop() const
Return the parent loop if it exists or nullptr for top level loops.
The legacy pass manager's analysis pass to compute loop information.
This class represents a loop nest and can be used to query its properties.
Represents a single loop in the control flow graph.
Representation for a specific memory location.
static LLVM_ABI MemoryLocation get(const LoadInst *LI)
Return a location with information about the memory reference by the given instruction.
LocationSize Size
The maximum size of the location, in address-units, or UnknownSize if the size is not known.
static MemoryLocation getBeforeOrAfter(const Value *Ptr, const AAMDNodes &AATags=AAMDNodes())
Return a location that may access any location before or after Ptr, while remaining within the underl...
AAMDNodes AATags
The metadata nodes which describes the aliasing of the location (each member is null if that kind of ...
const Value * Ptr
The address of the start of the location.
A Module instance is used to store all the information related to an LLVM module.
Represent a mutable reference to an array (0 or more elements consecutively in memory),...
AnalysisType & getAnalysis() const
getAnalysis<AnalysisType>() - This function is used by subclasses to get to the analysis information ...
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PreservedAnalysisChecker getChecker() const
Build a checker for this PreservedAnalyses and the specified analysis type.
This node represents a polynomial recurrence on the trip count of the specified loop.
LLVM_ABI const SCEV * evaluateAtIteration(const SCEV *It, ScalarEvolution &SE) const
Return the value of this chain of recurrences at the specified iteration number.
bool isAffine() const
Return true if this represents an expression A + B*x where A and B are loop invariant values.
const Loop * getLoop() const
SCEVUse getStepRecurrence(ScalarEvolution &SE) const
Constructs and returns the recurrence indicating how much this expression steps by.
This class represents a constant integer value.
const APInt & getAPInt() const
bool hasNoSignedWrap() const
This class represents a composition of other SCEV predicates, and is the class that most clients will...
This class represents an analyzed expression in the program.
LLVM_ABI bool isOne() const
Return true if the expression is a constant one.
LLVM_ABI bool isZero() const
Return true if the expression is a constant zero.
Type * getType() const
Return the LLVM type of this SCEV expression.
Analysis pass that exposes the ScalarEvolution for a function.
The main scalar evolution driver.
LLVM_ABI bool isKnownNonNegative(const SCEV *S)
Test if the given expression is known to be non-negative.
LLVM_ABI Type * getWiderType(Type *Ty1, Type *Ty2) const
LLVM_ABI bool isKnownNonPositive(const SCEV *S)
Test if the given expression is known to be non-positive.
LLVM_ABI bool isKnownNegative(const SCEV *S)
Test if the given expression is known to be negative.
LLVM_ABI const SCEV * getBackedgeTakenCount(const Loop *L, ExitCountKind Kind=Exact)
If the specified loop has a predictable backedge-taken count, return it, otherwise return a SCEVCould...
LLVM_ABI const SCEV * getSMinExpr(SCEVUse LHS, SCEVUse RHS)
const SCEV * getZero(Type *Ty)
Return a SCEV for the constant 0 of a specific type.
LLVM_ABI bool willNotOverflow(Instruction::BinaryOps BinOp, bool Signed, const SCEV *LHS, const SCEV *RHS, const Instruction *CtxI=nullptr)
Is operation BinOp between LHS and RHS provably does not have a signed/unsigned overflow (Signed)?
LLVM_ABI const SCEV * getMinusSCEV(SCEVUse LHS, SCEVUse RHS, SCEVFlags Flags=SCEV::FlagNone, unsigned Depth=0)
Return LHS-RHS.
const SCEV * getOne(Type *Ty)
Return a SCEV for the constant 1 of a specific type.
LLVM_ABI SCEVUse getAddExpr(SmallVectorImpl< SCEVUse > &Ops, SCEVFlagsPair Flags={}, unsigned Depth=0)
Get a canonical add expression, or something simpler if possible.
LLVM_ABI SCEVUse getMulExpr(SmallVectorImpl< SCEVUse > &Ops, SCEVFlagsPair Flags={}, unsigned Depth=0)
Get a canonical multiply expression, or something simpler if possible.
LLVM_ABI bool isKnownPredicate(CmpPredicate Pred, SCEVUse LHS, SCEVUse RHS)
Test if the given expression is known to satisfy the condition described by Pred, LHS,...
LLVM_ABI const SCEV * getSMaxExpr(SCEVUse LHS, SCEVUse RHS)
LLVM_ABI const SCEV * getNegativeSCEV(const SCEV *V, SCEVFlags Flags=SCEV::FlagNone)
Return the SCEV object corresponding to -V.
This is a 'bitvector' (really, a variable-sized bit array), optimized for the case when the array is ...
iterator_range< const_set_bits_iterator > set_bits() const
int find_next(unsigned Prev) const
Returns the index of the next set bit following the "Prev" bit.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
An instruction for storing to memory.
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM Value Representation.
LLVM_ABI Value(Type *Ty, unsigned scid)
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Abstract Attribute helper functions.
const APInt & smin(const APInt &A, const APInt &B)
Determine the smaller of two APInts considered to be signed.
const APInt & smax(const APInt &A, const APInt &B)
Determine the larger of two APInts considered to be signed.
LLVM_ABI APInt GreatestCommonDivisor(APInt A, APInt B, bool IsSigned=false)
Compute GCD of two APInt values.
constexpr bool operator!(E Val)
@ BasicBlock
Various leaf nodes.
@ TB
TB - TwoByte - Set if this instruction has a two byte opcode, which starts with a 0x0F byte before th...
This is an optimization pass for GlobalISel generic memory operations.
InstIterator< SymbolTableList< BasicBlock >, Function::iterator, BasicBlock::iterator, Instruction > inst_iterator
LLVM_ABI void collectParametricTerms(ScalarEvolution &SE, const SCEV *Expr, SmallVectorImpl< const SCEV * > &Terms)
Collect parametric terms occurring in step expressions (first step of delinearization).
LLVM_ABI void findArrayDimensions(ScalarEvolution &SE, SmallVectorImpl< const SCEV * > &Terms, SmallVectorImpl< const SCEV * > &Sizes, const SCEV *ElementSize)
Compute the array dimensions Sizes from the set of Terms extracted from the memory access function of...
RelativeUniformCounterPtr Values
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
APInt operator*(APInt a, uint64_t RHS)
const Value * getLoadStorePointerOperand(const Value *V)
A helper function that returns the pointer operand of a load or store instruction.
inst_iterator inst_begin(Function *F)
LLVM_ABI bool validateDelinearizationResult(ScalarEvolution &SE, ArrayRef< const SCEV * > Sizes, ArrayRef< const SCEV * > Subscripts)
Check that each subscript in Subscripts is within the corresponding size in Sizes.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
const AnalysisOptions & getAnalysisOptions(const LLVMContext &C)
LLVM_ABI void computeAccessFunctions(ScalarEvolution &SE, const SCEV *Expr, SmallVectorImpl< const SCEV * > &Subscripts, SmallVectorImpl< const SCEV * > &Sizes)
Return in Subscripts the access functions for each dimension in Sizes (third step of delinearization)...
LLVM_ABI bool delinearizeFixedSizeArray(ScalarEvolution &SE, const SCEV *Expr, SmallVectorImpl< const SCEV * > &Subscripts, SmallVectorImpl< const SCEV * > &Sizes, const SCEV *ElementSize)
Split this SCEVAddRecExpr into two vectors of SCEVs representing the subscripts and sizes of an acces...
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
LLVM_ABI const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=MaxLookupSearchDepth, bool MustPreserveProvenance=false)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
inst_iterator inst_end(Function *F)
constexpr unsigned BitWidth
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
APInt operator+(APInt a, const APInt &b)
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
LLVM_ABI bool isIdentifiedObject(const Value *V)
Return true if this pointer refers to a distinct and identifiable object.
LLVM_ABI FunctionPass * createDependenceAnalysisWrapperPass()
createDependenceAnalysisPass - This creates an instance of the DependenceAnalysis wrapper pass.
Implement std::hash so that hash_code can be used in STL containers.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
A special type used by analysis passes to provide an address that identifies that particular analysis...
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM)
Dependence::DVEntry - Each level in the distance/direction vector has a direction (or perhaps a union...