70#define DEBUG_TYPE "da"
76STATISTIC(SeparableSubscriptPairs,
"Separable subscript pairs");
77STATISTIC(CoupledSubscriptPairs,
"Coupled subscript pairs");
78STATISTIC(NonlinearSubscriptPairs,
"Nonlinear subscript pairs");
81STATISTIC(StrongSIVapplications,
"Strong SIV applications");
82STATISTIC(StrongSIVsuccesses,
"Strong SIV successes");
83STATISTIC(StrongSIVindependence,
"Strong SIV independence");
84STATISTIC(WeakCrossingSIVapplications,
"Weak-Crossing SIV applications");
85STATISTIC(WeakCrossingSIVsuccesses,
"Weak-Crossing SIV successes");
86STATISTIC(WeakCrossingSIVindependence,
"Weak-Crossing SIV independence");
87STATISTIC(ExactSIVapplications,
"Exact SIV applications");
89STATISTIC(ExactSIVindependence,
"Exact SIV independence");
90STATISTIC(WeakZeroSIVapplications,
"Weak-Zero SIV applications");
91STATISTIC(WeakZeroSIVsuccesses,
"Weak-Zero SIV successes");
92STATISTIC(WeakZeroSIVindependence,
"Weak-Zero SIV independence");
93STATISTIC(ExactRDIVapplications,
"Exact RDIV applications");
94STATISTIC(ExactRDIVindependence,
"Exact RDIV independence");
95STATISTIC(SymbolicRDIVapplications,
"Symbolic RDIV applications");
96STATISTIC(SymbolicRDIVindependence,
"Symbolic RDIV independence");
104STATISTIC(BanerjeeApplications,
"Banerjee applications");
105STATISTIC(BanerjeeIndependence,
"Banerjee independence");
107STATISTIC(SameSDLoopsCount,
"Loops with Same iteration Space and Depth");
111 cl::desc(
"Try to delinearize array references."));
113 "da-disable-delinearization-checks",
cl::Hidden,
115 "Disable checks that try to statically verify validity of "
116 "delinearized subscripts. Enabling this option may result in incorrect "
117 "dependence vectors for languages that allow the subscript of one "
118 "dimension to underflow or overflow into another dimension."));
122 cl::desc(
"Maximum depth allowed for the recursive algorithm used to "
123 "explore MIV direction vectors."));
127 cl::desc(
"Run only SIV routines and disable others (ZIV, RDIV, and MIV). "
128 "The purpose is mainly to exclude the influence of those routines "
129 "in regression tests for SIV routines."));
145 "Dependence Analysis",
true,
true)
186 auto *
F = DA->getFunction();
189 if (SrcI->mayReadOrWriteMemory()) {
192 if (DstI->mayReadOrWriteMemory()) {
193 OS <<
"Src:" << *SrcI <<
" --> Dst:" << *DstI <<
"\n";
194 OS <<
" da analyze - ";
195 if (
auto D = DA->depends(&*SrcI, &*DstI,
201 for (
unsigned Level = 1; Level <=
D->getLevels(); Level++) {
202 const SCEV *Distance =
D->getDistance(Level);
203 bool IsDistanceZero = Distance && Distance->
isZero();
206 assert(IsDistanceZero == IsDirectionEQ &&
207 "Inconsistent distance and direction.");
212 if (NormalizeResults &&
D->normalize(&SE))
213 OS <<
"normalized - ";
215 for (
unsigned Level = 1; Level <=
D->getLevels(); Level++) {
216 if (
D->isSplitable(Level)) {
217 OS <<
" da analyze - split level = " << Level;
218 OS <<
", iteration = " << *DA->getSplitIteration(*
D, Level);
230 OS <<
"Runtime Assumptions:\n";
231 Assumptions.
print(OS, 0);
243 OS <<
"Printing analysis 'Dependence Analysis' for function '" <<
F.getName()
256 return Src->mayReadFromMemory() &&
Dst->mayReadFromMemory();
261 return Src->mayWriteToMemory() &&
Dst->mayWriteToMemory();
266 return Src->mayWriteToMemory() &&
Dst->mayReadFromMemory();
271 return Src->mayReadFromMemory() &&
Dst->mayWriteToMemory();
285 bool PossiblyLoopIndependent,
286 unsigned CommonLevels)
287 :
Dependence(Source, Destination, Assumes), Levels(CommonLevels),
288 LoopIndependent(PossiblyLoopIndependent) {
292 DV = std::make_unique<
DVEntry[]>(CommonLevels);
311 for (
unsigned Level = 1; Level <= Levels; ++Level) {
312 unsigned char Direction = DV[Level - 1].Direction;
327 LLVM_DEBUG(
dbgs() <<
"Before normalizing negative direction vectors:\n";
330 for (
unsigned Level = 1; Level <= Levels; ++Level) {
331 unsigned char Direction = DV[Level - 1].Direction;
339 DV[Level - 1].Direction = RevDirection;
341 if (DV[Level - 1].Distance !=
nullptr)
345 LLVM_DEBUG(
dbgs() <<
"After normalizing negative direction vectors:\n";
392 assert(0 < Level && Level <= Levels + SameSDLevels &&
"Level out of range");
393 return Level > Levels;
401const SCEV *DependenceInfo::Constraint::getX()
const {
402 assert(Kind == Point &&
"Kind should be Point");
408const SCEV *DependenceInfo::Constraint::getY()
const {
409 assert(Kind == Point &&
"Kind should be Point");
415const SCEV *DependenceInfo::Constraint::getA()
const {
416 assert((Kind == Line || Kind == Distance) &&
417 "Kind should be Line (or Distance)");
423const SCEV *DependenceInfo::Constraint::getB()
const {
424 assert((Kind == Line || Kind == Distance) &&
425 "Kind should be Line (or Distance)");
431const SCEV *DependenceInfo::Constraint::getC()
const {
432 assert((Kind == Line || Kind == Distance) &&
433 "Kind should be Line (or Distance)");
439const SCEV *DependenceInfo::Constraint::getD()
const {
440 assert(Kind == Distance &&
"Kind should be Distance");
441 return SE->getNegativeSCEV(
C);
445const Loop *DependenceInfo::Constraint::getAssociatedSrcLoop()
const {
446 assert((Kind == Distance || Kind == Line || Kind == Point) &&
447 "Kind should be Distance, Line, or Point");
448 return AssociatedSrcLoop;
452const Loop *DependenceInfo::Constraint::getAssociatedDstLoop()
const {
453 assert((Kind == Distance || Kind == Line || Kind == Point) &&
454 "Kind should be Distance, Line, or Point");
455 return AssociatedDstLoop;
458void DependenceInfo::Constraint::setPoint(
const SCEV *
X,
const SCEV *
Y,
459 const Loop *CurSrcLoop,
460 const Loop *CurDstLoop) {
464 AssociatedSrcLoop = CurSrcLoop;
465 AssociatedDstLoop = CurDstLoop;
468void DependenceInfo::Constraint::setLine(
const SCEV *AA,
const SCEV *BB,
469 const SCEV *CC,
const Loop *CurSrcLoop,
470 const Loop *CurDstLoop) {
475 AssociatedSrcLoop = CurSrcLoop;
476 AssociatedDstLoop = CurDstLoop;
479void DependenceInfo::Constraint::setDistance(
const SCEV *
D,
480 const Loop *CurSrcLoop,
481 const Loop *CurDstLoop) {
483 A = SE->getOne(
D->getType());
484 B = SE->getNegativeSCEV(
A);
485 C = SE->getNegativeSCEV(
D);
486 AssociatedSrcLoop = CurSrcLoop;
487 AssociatedDstLoop = CurDstLoop;
490void DependenceInfo::Constraint::setEmpty() {
Kind =
Empty; }
492void DependenceInfo::Constraint::setAny(ScalarEvolution *NewSE) {
497#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
499LLVM_DUMP_METHOD void DependenceInfo::Constraint::dump(raw_ostream &OS)
const {
505 OS <<
" Point is <" << *getX() <<
", " << *getY() <<
">\n";
506 else if (isDistance())
507 OS <<
" Distance is " << *getD() <<
" (" << *getA() <<
"*X + " << *getB()
508 <<
"*Y = " << *getC() <<
")\n";
510 OS <<
" Line is " << *getA() <<
"*X + " << *getB() <<
"*Y = " << *getC()
524bool DependenceInfo::intersectConstraints(Constraint *
X,
const Constraint *
Y) {
529 assert(!
Y->isPoint() &&
"Y must not be a Point");
543 if (
X->isDistance() &&
Y->isDistance()) {
567 assert(!(
X->isPoint() &&
Y->isPoint()) &&
568 "We shouldn't ever see X->isPoint() && Y->isPoint()");
570 if (
X->isLine() &&
Y->isLine()) {
572 const SCEV *Prod1 = SE->getMulExpr(
X->getA(),
Y->getB());
573 const SCEV *Prod2 = SE->getMulExpr(
X->getB(),
Y->getA());
577 Prod1 = SE->getMulExpr(
X->getC(),
Y->getB());
578 Prod2 = SE->getMulExpr(
X->getB(),
Y->getC());
591 const SCEV *C1B2 = SE->getMulExpr(
X->getC(),
Y->getB());
592 const SCEV *C1A2 = SE->getMulExpr(
X->getC(),
Y->getA());
593 const SCEV *C2B1 = SE->getMulExpr(
Y->getC(),
X->getB());
594 const SCEV *C2A1 = SE->getMulExpr(
Y->getC(),
X->getA());
595 const SCEV *A1B2 = SE->getMulExpr(
X->getA(),
Y->getB());
596 const SCEV *A2B1 = SE->getMulExpr(
Y->getA(),
X->getB());
597 const SCEVConstant *C1A2_C2A1 =
599 const SCEVConstant *C1B2_C2B1 =
601 const SCEVConstant *A1B2_A2B1 =
603 const SCEVConstant *A2B1_A1B2 =
605 if (!C1B2_C2B1 || !C1A2_C2A1 || !A1B2_A2B1 || !A2B1_A1B2)
621 if (Xr != 0 || Yr != 0) {
627 if (Xq.
slt(0) || Yq.
slt(0)) {
632 if (
const SCEVConstant *CUB = collectConstantUpperBound(
633 X->getAssociatedSrcLoop(), Prod1->
getType())) {
634 const APInt &UpperBound = CUB->getAPInt();
636 if (Xq.
sgt(UpperBound) || Yq.
sgt(UpperBound)) {
642 X->setPoint(SE->getConstant(Xq), SE->getConstant(Yq),
643 X->getAssociatedSrcLoop(),
X->getAssociatedDstLoop());
651 assert(!(
X->isLine() &&
Y->isPoint()) &&
"This case should never occur");
653 if (
X->isPoint() &&
Y->isLine()) {
655 const SCEV *A1X1 = SE->getMulExpr(
Y->getA(),
X->getX());
656 const SCEV *B1Y1 = SE->getMulExpr(
Y->getB(),
X->getY());
657 const SCEV *Sum = SE->getAddExpr(A1X1, B1Y1);
692 if (SameSDLevels > 0) {
693 OS <<
"! / assuming " << SameSDLevels <<
" loop level(s) fused: ";
700 if (!Assumptions.isAlwaysTrue()) {
701 OS <<
" Runtime Assumptions:\n";
702 Assumptions.print(OS, 2);
709 bool Splitable =
false;
712 bool OnSameSD =
false;
713 unsigned LevelNum = Levels;
715 LevelNum += SameSDLevels;
717 for (
unsigned II = 1;
II <= LevelNum; ++
II) {
796 return LI->isUnordered();
798 return SI->isUnordered();
806bool DependenceInfo::haveSameSD(
const Loop *SrcLoop,
807 const Loop *DstLoop)
const {
808 if (SrcLoop == DstLoop)
818 const SCEV *SrcUB =
nullptr, *DstUP =
nullptr;
819 if (SE->hasLoopInvariantBackedgeTakenCount(SrcLoop))
820 SrcUB = SE->getBackedgeTakenCount(SrcLoop);
821 if (SE->hasLoopInvariantBackedgeTakenCount(DstLoop))
822 DstUP = SE->getBackedgeTakenCount(DstLoop);
824 if (SrcUB !=
nullptr && DstUP !=
nullptr &&
893void DependenceInfo::establishNestingLevels(
const Instruction *Src,
894 const Instruction *Dst) {
895 const BasicBlock *SrcBlock = Src->getParent();
896 const BasicBlock *DstBlock = Dst->getParent();
897 unsigned SrcLevel = LI->getLoopDepth(SrcBlock);
898 unsigned DstLevel = LI->getLoopDepth(DstBlock);
899 const Loop *SrcLoop = LI->getLoopFor(SrcBlock);
900 const Loop *DstLoop = LI->getLoopFor(DstBlock);
901 SrcLevels = SrcLevel;
902 MaxLevels = SrcLevel + DstLevel;
904 while (SrcLevel > DstLevel) {
908 while (DstLevel > SrcLevel) {
914 while (SrcLoop != DstLoop) {
916 if (!haveSameSD(SrcLoop, DstLoop))
922 CommonLevels = SrcLevel;
923 MaxLevels -= CommonLevels;
928unsigned DependenceInfo::mapSrcLoop(
const Loop *SrcLoop)
const {
934unsigned DependenceInfo::mapDstLoop(
const Loop *DstLoop)
const {
936 if (
D > CommonLevels)
939 return D - CommonLevels + SrcLevels;
945bool DependenceInfo::isLoopInvariant(
const SCEV *Expression,
946 const Loop *LoopNest)
const {
961void DependenceInfo::collectCommonLoops(
const SCEV *Expression,
962 const Loop *LoopNest,
963 SmallBitVector &
Loops)
const {
966 if (Level <= CommonLevels && !SE->isLoopInvariant(Expression, LoopNest))
974 unsigned widestWidthSeen = 0;
979 for (Subscript *Pair : Pairs) {
980 const SCEV *Src = Pair->Src;
981 const SCEV *Dst = Pair->Dst;
984 if (SrcTy ==
nullptr || DstTy ==
nullptr) {
986 "This function only unify integer types and "
987 "expect Src and Dst share the same type otherwise.");
1000 assert(widestWidthSeen > 0);
1003 for (Subscript *Pair : Pairs) {
1004 const SCEV *Src = Pair->Src;
1005 const SCEV *Dst = Pair->Dst;
1008 if (SrcTy ==
nullptr || DstTy ==
nullptr) {
1010 "This function only unify integer types and "
1011 "expect Src and Dst share the same type otherwise.");
1016 Pair->Src = SE->getSignExtendExpr(Src, widestType);
1019 Pair->Dst = SE->getSignExtendExpr(Dst, widestType);
1028void DependenceInfo::removeMatchingExtensions(Subscript *Pair) {
1029 const SCEV *Src = Pair->Src;
1030 const SCEV *Dst = Pair->Dst;
1035 const SCEV *SrcCastOp = SrcCast->
getOperand();
1036 const SCEV *DstCastOp = DstCast->
getOperand();
1038 Pair->Src = SrcCastOp;
1039 Pair->Dst = DstCastOp;
1046bool DependenceInfo::checkSubscript(
const SCEV *Expr,
const Loop *LoopNest,
1047 SmallBitVector &
Loops,
bool IsSrc) {
1050 return isLoopInvariant(Expr, LoopNest);
1057 const Loop *
L = LoopNest;
1058 while (L && AddRec->
getLoop() != L)
1059 L =
L->getParentLoop();
1065 if (!isLoopInvariant(Step, LoopNest))
1071 return checkSubscript(Start, LoopNest,
Loops, IsSrc);
1076bool DependenceInfo::checkSrcSubscript(
const SCEV *Src,
const Loop *LoopNest,
1077 SmallBitVector &
Loops) {
1078 return checkSubscript(Src, LoopNest,
Loops,
true);
1083bool DependenceInfo::checkDstSubscript(
const SCEV *Dst,
const Loop *LoopNest,
1084 SmallBitVector &
Loops) {
1085 return checkSubscript(Dst, LoopNest,
Loops,
false);
1091DependenceInfo::Subscript::ClassificationKind
1092DependenceInfo::classifyPair(
const SCEV *Src,
const Loop *SrcLoopNest,
1093 const SCEV *Dst,
const Loop *DstLoopNest,
1094 SmallBitVector &
Loops) {
1095 SmallBitVector SrcLoops(MaxLevels + 1);
1096 SmallBitVector DstLoops(MaxLevels + 1);
1097 if (!checkSrcSubscript(Src, SrcLoopNest, SrcLoops))
1098 return Subscript::NonLinear;
1099 if (!checkDstSubscript(Dst, DstLoopNest, DstLoops))
1100 return Subscript::NonLinear;
1103 unsigned N =
Loops.count();
1105 return Subscript::ZIV;
1107 return Subscript::SIV;
1108 if (
N == 2 && (SrcLoops.count() == 0 || DstLoops.count() == 0 ||
1109 (SrcLoops.count() == 1 && DstLoops.count() == 1)))
1110 return Subscript::RDIV;
1111 return Subscript::MIV;
1125 const SCEV *
Y)
const {
1139 if (SE->isKnownPredicate(Pred,
X,
Y))
1146 const SCEV *Delta = SE->getMinusSCEV(
X,
Y);
1151 return SE->isKnownNonZero(Delta);
1153 return SE->isKnownNonNegative(Delta);
1155 return SE->isKnownNonPositive(Delta);
1157 return SE->isKnownPositive(Delta);
1159 return SE->isKnownNegative(Delta);
1171bool DependenceInfo::isKnownLessThan(
const SCEV *S,
const SCEV *
Size)
const {
1175 if (!SType || !SizeType)
1178 (SType->getBitWidth() >= SizeType->getBitWidth()) ? SType : SizeType;
1179 S = SE->getTruncateOrZeroExtend(S, MaxType);
1180 Size = SE->getTruncateOrZeroExtend(
Size, MaxType);
1185 const SCEV *BECount = SE->getBackedgeTakenCount(AddRec->
getLoop());
1189 const SCEV *Diff0 = SE->getMinusSCEV(Start,
Size);
1190 const SCEV *Diff1 = SE->getMinusSCEV(End,
Size);
1195 if (SE->isKnownNonNegative(Step) && SE->isKnownNegative(Diff1))
1200 if (SE->isKnownNonPositive(Step) && SE->isKnownNegative(Diff0))
1205 if (SE->isKnownNegative(Diff0) && SE->isKnownNegative(Diff1))
1210 const SCEV *LimitedBound = SE->getMinusSCEV(S,
Size);
1211 return SE->isKnownNegative(LimitedBound);
1214bool DependenceInfo::isKnownNonNegative(
const SCEV *S,
const Value *
Ptr)
const {
1215 bool Inbounds =
false;
1217 Inbounds = SrcGEP->isInBounds();
1223 if (SE->isKnownNonNegative(AddRec->
getStart()) &&
1224 SE->isKnownNonNegative(AddRec->
getOperand(1)))
1230 return SE->isKnownNonNegative(S);
1240const SCEV *DependenceInfo::collectUpperBound(
const Loop *L,
Type *
T)
const {
1241 if (SE->hasLoopInvariantBackedgeTakenCount(L)) {
1242 const SCEV *UB = SE->getBackedgeTakenCount(L);
1243 return SE->getTruncateOrZeroExtend(UB,
T);
1250const SCEVConstant *DependenceInfo::collectConstantUpperBound(
const Loop *L,
1252 if (
const SCEV *UB = collectUpperBound(L,
T))
1276bool DependenceInfo::testZIV(
const SCEV *Src,
const SCEV *Dst,
1277 FullDependence &Result)
const {
1291 Result.Consistent =
false;
1322bool DependenceInfo::strongSIVtest(
const SCEV *Coeff,
const SCEV *SrcConst,
1323 const SCEV *DstConst,
const Loop *CurSrcLoop,
1324 const Loop *CurDstLoop,
unsigned Level,
1325 FullDependence &Result,
1326 Constraint &NewConstraint)
const {
1334 ++StrongSIVapplications;
1335 assert(0 < Level && Level <= CommonLevels &&
"level out of range");
1338 const SCEV *Delta = SE->getMinusSCEV(SrcConst, DstConst);
1343 if (
const SCEV *UpperBound =
1344 collectUpperBound(CurSrcLoop, Delta->
getType())) {
1347 const SCEV *AbsDelta =
1348 SE->isKnownNonNegative(Delta) ? Delta : SE->getNegativeSCEV(Delta);
1349 const SCEV *AbsCoeff =
1350 SE->isKnownNonNegative(Coeff) ? Coeff : SE->getNegativeSCEV(Coeff);
1351 const SCEV *Product = SE->getMulExpr(UpperBound, AbsCoeff);
1354 ++StrongSIVindependence;
1355 ++StrongSIVsuccesses;
1364 APInt Distance = ConstDelta;
1365 APInt Remainder = ConstDelta;
1370 if (Remainder != 0) {
1372 ++StrongSIVindependence;
1373 ++StrongSIVsuccesses;
1376 Result.DV[
Level].Distance = SE->getConstant(Distance);
1377 NewConstraint.setDistance(SE->getConstant(Distance), CurSrcLoop,
1379 if (Distance.
sgt(0))
1381 else if (Distance.
slt(0))
1385 ++StrongSIVsuccesses;
1386 }
else if (Delta->
isZero()) {
1389 NewConstraint.setDistance(Delta, CurSrcLoop, CurDstLoop);
1391 ++StrongSIVsuccesses;
1393 if (Coeff->
isOne()) {
1396 NewConstraint.setDistance(Delta, CurSrcLoop, CurDstLoop);
1398 Result.Consistent =
false;
1399 NewConstraint.setLine(Coeff, SE->getNegativeSCEV(Coeff),
1400 SE->getNegativeSCEV(Delta), CurSrcLoop, CurDstLoop);
1404 bool DeltaMaybeZero = !SE->isKnownNonZero(Delta);
1405 bool DeltaMaybePositive = !SE->isKnownNonPositive(Delta);
1406 bool DeltaMaybeNegative = !SE->isKnownNonNegative(Delta);
1407 bool CoeffMaybePositive = !SE->isKnownNonPositive(Coeff);
1408 bool CoeffMaybeNegative = !SE->isKnownNonNegative(Coeff);
1413 if ((DeltaMaybePositive && CoeffMaybePositive) ||
1414 (DeltaMaybeNegative && CoeffMaybeNegative))
1418 if ((DeltaMaybeNegative && CoeffMaybePositive) ||
1419 (DeltaMaybePositive && CoeffMaybeNegative))
1421 if (NewDirection <
Result.DV[Level].Direction)
1422 ++StrongSIVsuccesses;
1456bool DependenceInfo::weakCrossingSIVtest(
1457 const SCEV *Coeff,
const SCEV *SrcConst,
const SCEV *DstConst,
1458 const Loop *CurSrcLoop,
const Loop *CurDstLoop,
unsigned Level,
1459 FullDependence &Result, Constraint &NewConstraint,
1460 const SCEV *&SplitIter)
const {
1465 ++WeakCrossingSIVapplications;
1466 assert(0 < Level && Level <= CommonLevels &&
"Level out of range");
1468 Result.Consistent =
false;
1469 const SCEV *Delta = SE->getMinusSCEV(DstConst, SrcConst);
1471 NewConstraint.setLine(Coeff, Coeff, Delta, CurSrcLoop, CurDstLoop);
1473 Result.DV[
Level].Direction &= ~Dependence::DVEntry::LT;
1474 Result.DV[
Level].Direction &= ~Dependence::DVEntry::GT;
1475 ++WeakCrossingSIVsuccesses;
1476 if (!
Result.DV[Level].Direction) {
1477 ++WeakCrossingSIVindependence;
1488 if (SE->isKnownNegative(ConstCoeff)) {
1491 "dynamic cast of negative of ConstCoeff should yield constant");
1492 Delta = SE->getNegativeSCEV(Delta);
1494 assert(SE->isKnownPositive(ConstCoeff) &&
"ConstCoeff should be positive");
1497 SplitIter = SE->getUDivExpr(
1498 SE->getSMaxExpr(SE->getZero(Delta->
getType()), Delta),
1499 SE->getMulExpr(SE->getConstant(Delta->
getType(), 2), ConstCoeff));
1510 if (SE->isKnownNegative(Delta)) {
1512 ++WeakCrossingSIVindependence;
1513 ++WeakCrossingSIVsuccesses;
1519 if (
const SCEV *UpperBound =
1520 collectUpperBound(CurSrcLoop, Delta->
getType())) {
1522 const SCEV *ConstantTwo = SE->getConstant(UpperBound->getType(), 2);
1524 SE->getMulExpr(SE->getMulExpr(ConstCoeff, UpperBound), ConstantTwo);
1528 ++WeakCrossingSIVindependence;
1529 ++WeakCrossingSIVsuccesses;
1534 Result.DV[
Level].Direction &= ~Dependence::DVEntry::LT;
1535 Result.DV[
Level].Direction &= ~Dependence::DVEntry::GT;
1536 ++WeakCrossingSIVsuccesses;
1537 if (!
Result.DV[Level].Direction) {
1538 ++WeakCrossingSIVindependence;
1548 APInt APDelta = ConstDelta->
getAPInt();
1549 APInt APCoeff = ConstCoeff->
getAPInt();
1550 APInt Distance = APDelta;
1551 APInt Remainder = APDelta;
1554 if (Remainder != 0) {
1556 ++WeakCrossingSIVindependence;
1557 ++WeakCrossingSIVsuccesses;
1563 APInt Two = APInt(Distance.
getBitWidth(), 2,
true);
1564 Remainder = Distance.
srem(Two);
1566 if (Remainder != 0) {
1568 Result.DV[
Level].Direction &= ~Dependence::DVEntry::EQ;
1569 ++WeakCrossingSIVsuccesses;
1586 APInt A0(Bits, 1,
true), A1(Bits, 0,
true);
1587 APInt B0(Bits, 0,
true), B1(Bits, 1,
true);
1595 APInt A2 = A0 - Q*A1; A0 = A1; A1 = A2;
1596 APInt B2 = B0 - Q*B1; B0 = B1; B1 = B2;
1603 X = AM.
slt(0) ? -A1 : A1;
1604 Y = BM.
slt(0) ? B1 : -B1;
1620 if ((
A.sgt(0) &&
B.sgt(0)) || (
A.slt(0) &&
B.slt(0)))
1632 if ((
A.sgt(0) &&
B.sgt(0)) || (
A.slt(0) &&
B.slt(0)))
1667static std::pair<std::optional<APInt>, std::optional<APInt>>
1669 const std::optional<APInt> &UB) {
1670 assert(
A != 0 &&
"A must be non-zero");
1671 std::optional<APInt> TL, TU;
1691 return std::make_pair(TL, TU);
1713bool DependenceInfo::exactSIVtest(
const SCEV *SrcCoeff,
const SCEV *DstCoeff,
1714 const SCEV *SrcConst,
const SCEV *DstConst,
1715 const Loop *CurSrcLoop,
1716 const Loop *CurDstLoop,
unsigned Level,
1717 FullDependence &Result,
1718 Constraint &NewConstraint)
const {
1720 LLVM_DEBUG(
dbgs() <<
"\t SrcCoeff = " << *SrcCoeff <<
" = AM\n");
1721 LLVM_DEBUG(
dbgs() <<
"\t DstCoeff = " << *DstCoeff <<
" = BM\n");
1724 ++ExactSIVapplications;
1725 assert(0 < Level && Level <= CommonLevels &&
"Level out of range");
1727 Result.Consistent =
false;
1732 NewConstraint.setLine(SrcCoeff, SE->getNegativeSCEV(DstCoeff), Delta,
1733 CurSrcLoop, CurDstLoop);
1737 if (!ConstDelta || !ConstSrcCoeff || !ConstDstCoeff)
1742 APInt AM = ConstSrcCoeff->
getAPInt();
1743 APInt BM = ConstDstCoeff->
getAPInt();
1748 ++ExactSIVindependence;
1749 ++ExactSIVsuccesses;
1756 std::optional<APInt> UM;
1758 if (
const SCEVConstant *CUB =
1759 collectConstantUpperBound(CurSrcLoop, Delta->
getType())) {
1760 UM = CUB->getAPInt();
1766 APInt TC = CM.
sdiv(
G);
1788 auto CreateVec = [](
const std::optional<APInt> &V0,
1789 const std::optional<APInt> &V1) {
1812 ++ExactSIVindependence;
1813 ++ExactSIVsuccesses;
1819 APInt LowerDistance, UpperDistance;
1822 LowerDistance = (TY - TX) + (TA - TB) * TL;
1823 UpperDistance = (TY - TX) + (TA - TB) * TU;
1825 LowerDistance = (TY - TX) + (TA - TB) * TU;
1826 UpperDistance = (TY - TX) + (TA - TB) * TL;
1829 LLVM_DEBUG(
dbgs() <<
"\t LowerDistance = " << LowerDistance <<
"\n");
1830 LLVM_DEBUG(
dbgs() <<
"\t UpperDistance = " << UpperDistance <<
"\n");
1832 APInt
Zero(Bits, 0,
true);
1833 if (LowerDistance.
sle(Zero) && UpperDistance.
sge(Zero)) {
1835 ++ExactSIVsuccesses;
1837 if (LowerDistance.
slt(0)) {
1839 ++ExactSIVsuccesses;
1841 if (UpperDistance.
sgt(0)) {
1843 ++ExactSIVsuccesses;
1849 ++ExactSIVindependence;
1860 return ConstDividend.
srem(ConstDivisor) == 0;
1894bool DependenceInfo::weakZeroSrcSIVtest(
1895 const SCEV *DstCoeff,
const SCEV *SrcConst,
const SCEV *DstConst,
1896 const Loop *CurSrcLoop,
const Loop *CurDstLoop,
unsigned Level,
1897 FullDependence &Result, Constraint &NewConstraint)
const {
1905 ++WeakZeroSIVapplications;
1906 assert(0 < Level && Level <= MaxLevels &&
"Level out of range");
1908 Result.Consistent =
false;
1909 const SCEV *Delta = SE->getMinusSCEV(SrcConst, DstConst);
1910 NewConstraint.setLine(SE->getZero(Delta->
getType()), DstCoeff, Delta,
1911 CurSrcLoop, CurDstLoop);
1914 if (Level < CommonLevels) {
1917 ++WeakZeroSIVsuccesses;
1924 const SCEV *AbsCoeff = SE->isKnownNegative(ConstCoeff)
1925 ? SE->getNegativeSCEV(ConstCoeff)
1927 const SCEV *NewDelta =
1928 SE->isKnownNegative(ConstCoeff) ? SE->getNegativeSCEV(Delta) : Delta;
1932 if (
const SCEV *UpperBound =
1933 collectUpperBound(CurSrcLoop, Delta->
getType())) {
1935 const SCEV *Product = SE->getMulExpr(AbsCoeff, UpperBound);
1937 ++WeakZeroSIVindependence;
1938 ++WeakZeroSIVsuccesses;
1943 if (Level < CommonLevels) {
1946 ++WeakZeroSIVsuccesses;
1954 if (SE->isKnownNegative(NewDelta)) {
1956 ++WeakZeroSIVindependence;
1957 ++WeakZeroSIVsuccesses;
1964 ++WeakZeroSIVindependence;
1965 ++WeakZeroSIVsuccesses;
2002bool DependenceInfo::weakZeroDstSIVtest(
2003 const SCEV *SrcCoeff,
const SCEV *SrcConst,
const SCEV *DstConst,
2004 const Loop *CurSrcLoop,
const Loop *CurDstLoop,
unsigned Level,
2005 FullDependence &Result, Constraint &NewConstraint)
const {
2012 ++WeakZeroSIVapplications;
2013 assert(0 < Level && Level <= SrcLevels &&
"Level out of range");
2015 Result.Consistent =
false;
2016 const SCEV *Delta = SE->getMinusSCEV(DstConst, SrcConst);
2017 NewConstraint.setLine(SrcCoeff, SE->getZero(Delta->
getType()), Delta,
2018 CurSrcLoop, CurDstLoop);
2021 if (Level < CommonLevels) {
2024 ++WeakZeroSIVsuccesses;
2031 const SCEV *AbsCoeff = SE->isKnownNegative(ConstCoeff)
2032 ? SE->getNegativeSCEV(ConstCoeff)
2034 const SCEV *NewDelta =
2035 SE->isKnownNegative(ConstCoeff) ? SE->getNegativeSCEV(Delta) : Delta;
2039 if (
const SCEV *UpperBound =
2040 collectUpperBound(CurSrcLoop, Delta->
getType())) {
2042 const SCEV *Product = SE->getMulExpr(AbsCoeff, UpperBound);
2044 ++WeakZeroSIVindependence;
2045 ++WeakZeroSIVsuccesses;
2050 if (Level < CommonLevels) {
2053 ++WeakZeroSIVsuccesses;
2061 if (SE->isKnownNegative(NewDelta)) {
2063 ++WeakZeroSIVindependence;
2064 ++WeakZeroSIVsuccesses;
2071 ++WeakZeroSIVindependence;
2072 ++WeakZeroSIVsuccesses;
2085bool DependenceInfo::exactRDIVtest(
const SCEV *SrcCoeff,
const SCEV *DstCoeff,
2086 const SCEV *SrcConst,
const SCEV *DstConst,
2087 const Loop *SrcLoop,
const Loop *DstLoop,
2088 FullDependence &Result)
const {
2092 LLVM_DEBUG(
dbgs() <<
"\t SrcCoeff = " << *SrcCoeff <<
" = AM\n");
2093 LLVM_DEBUG(
dbgs() <<
"\t DstCoeff = " << *DstCoeff <<
" = BM\n");
2096 ++ExactRDIVapplications;
2097 Result.Consistent =
false;
2098 const SCEV *Delta = SE->getMinusSCEV(DstConst, SrcConst);
2103 if (!ConstDelta || !ConstSrcCoeff || !ConstDstCoeff)
2108 APInt AM = ConstSrcCoeff->
getAPInt();
2109 APInt BM = ConstDstCoeff->
getAPInt();
2114 ++ExactRDIVindependence;
2121 std::optional<APInt> SrcUM;
2123 if (
const SCEVConstant *UpperBound =
2124 collectConstantUpperBound(SrcLoop, Delta->
getType())) {
2125 SrcUM = UpperBound->getAPInt();
2129 std::optional<APInt> DstUM;
2131 if (
const SCEVConstant *UpperBound =
2132 collectConstantUpperBound(DstLoop, Delta->
getType())) {
2133 DstUM = UpperBound->getAPInt();
2139 APInt TC = CM.
sdiv(
G);
2164 auto CreateVec = [](
const std::optional<APInt> &V0,
2165 const std::optional<APInt> &V1) {
2185 ++ExactRDIVindependence;
2231bool DependenceInfo::symbolicRDIVtest(
const SCEV *A1,
const SCEV *A2,
2232 const SCEV *C1,
const SCEV *C2,
2234 const Loop *Loop2)
const {
2237 ++SymbolicRDIVapplications;
2244 const SCEV *N1 = collectUpperBound(Loop1, A1->
getType());
2245 const SCEV *N2 = collectUpperBound(Loop2, A1->
getType());
2248 const SCEV *C2_C1 = SE->getMinusSCEV(C2, C1);
2249 const SCEV *C1_C2 = SE->getMinusSCEV(C1, C2);
2252 if (SE->isKnownNonNegative(A1)) {
2253 if (SE->isKnownNonNegative(A2)) {
2257 const SCEV *A1N1 = SE->getMulExpr(A1, N1);
2260 ++SymbolicRDIVindependence;
2266 const SCEV *A2N2 = SE->getMulExpr(A2, N2);
2269 ++SymbolicRDIVindependence;
2273 }
else if (SE->isKnownNonPositive(A2)) {
2277 const SCEV *A1N1 = SE->getMulExpr(A1, N1);
2278 const SCEV *A2N2 = SE->getMulExpr(A2, N2);
2279 const SCEV *A1N1_A2N2 = SE->getMinusSCEV(A1N1, A2N2);
2280 LLVM_DEBUG(
dbgs() <<
"\t A1*N1 - A2*N2 = " << *A1N1_A2N2 <<
"\n");
2282 ++SymbolicRDIVindependence;
2287 if (SE->isKnownNegative(C2_C1)) {
2288 ++SymbolicRDIVindependence;
2292 }
else if (SE->isKnownNonPositive(A1)) {
2293 if (SE->isKnownNonNegative(A2)) {
2297 const SCEV *A1N1 = SE->getMulExpr(A1, N1);
2298 const SCEV *A2N2 = SE->getMulExpr(A2, N2);
2299 const SCEV *A1N1_A2N2 = SE->getMinusSCEV(A1N1, A2N2);
2300 LLVM_DEBUG(
dbgs() <<
"\t A1*N1 - A2*N2 = " << *A1N1_A2N2 <<
"\n");
2302 ++SymbolicRDIVindependence;
2307 if (SE->isKnownPositive(C2_C1)) {
2308 ++SymbolicRDIVindependence;
2311 }
else if (SE->isKnownNonPositive(A2)) {
2315 const SCEV *A1N1 = SE->getMulExpr(A1, N1);
2318 ++SymbolicRDIVindependence;
2324 const SCEV *A2N2 = SE->getMulExpr(A2, N2);
2327 ++SymbolicRDIVindependence;
2344bool DependenceInfo::testSIV(
const SCEV *Src,
const SCEV *Dst,
unsigned &Level,
2345 FullDependence &Result, Constraint &NewConstraint,
2346 const SCEV *&SplitIter)
const {
2351 if (SrcAddRec && DstAddRec) {
2352 const SCEV *SrcConst = SrcAddRec->
getStart();
2353 const SCEV *DstConst = DstAddRec->
getStart();
2356 const Loop *CurSrcLoop = SrcAddRec->
getLoop();
2357 const Loop *CurDstLoop = DstAddRec->
getLoop();
2358 assert(haveSameSD(CurSrcLoop, CurDstLoop) &&
2359 "Loops in the SIV test should have the same iteration space and "
2361 Level = mapSrcLoop(CurSrcLoop);
2363 if (SrcCoeff == DstCoeff)
2364 disproven = strongSIVtest(SrcCoeff, SrcConst, DstConst, CurSrcLoop,
2365 CurDstLoop, Level, Result, NewConstraint);
2366 else if (SrcCoeff == SE->getNegativeSCEV(DstCoeff))
2367 disproven = weakCrossingSIVtest(SrcCoeff, SrcConst, DstConst, CurSrcLoop,
2368 CurDstLoop, Level, Result, NewConstraint,
2372 exactSIVtest(SrcCoeff, DstCoeff, SrcConst, DstConst, CurSrcLoop,
2373 CurDstLoop, Level, Result, NewConstraint);
2374 return disproven || gcdMIVtest(Src, Dst, Result) ||
2375 symbolicRDIVtest(SrcCoeff, DstCoeff, SrcConst, DstConst, CurSrcLoop,
2379 const SCEV *SrcConst = SrcAddRec->
getStart();
2381 const SCEV *DstConst = Dst;
2382 const Loop *CurSrcLoop = SrcAddRec->
getLoop();
2383 Level = mapSrcLoop(CurSrcLoop);
2384 return weakZeroDstSIVtest(SrcCoeff, SrcConst, DstConst, CurSrcLoop,
2385 CurSrcLoop, Level, Result, NewConstraint) ||
2386 gcdMIVtest(Src, Dst, Result);
2389 const SCEV *DstConst = DstAddRec->
getStart();
2391 const SCEV *SrcConst = Src;
2392 const Loop *CurDstLoop = DstAddRec->
getLoop();
2393 Level = mapDstLoop(CurDstLoop);
2394 return weakZeroSrcSIVtest(DstCoeff, SrcConst, DstConst, CurDstLoop,
2395 CurDstLoop, Level, Result, NewConstraint) ||
2396 gcdMIVtest(Src, Dst, Result);
2415bool DependenceInfo::testRDIV(
const SCEV *Src,
const SCEV *Dst,
2416 FullDependence &Result)
const {
2423 const SCEV *SrcConst, *DstConst;
2424 const SCEV *SrcCoeff, *DstCoeff;
2425 const Loop *SrcLoop, *DstLoop;
2431 if (SrcAddRec && DstAddRec) {
2434 SrcLoop = SrcAddRec->
getLoop();
2437 DstLoop = DstAddRec->
getLoop();
2438 }
else if (SrcAddRec) {
2439 if (
const SCEVAddRecExpr *tmpAddRec =
2441 SrcConst = tmpAddRec->getStart();
2442 SrcCoeff = tmpAddRec->getStepRecurrence(*SE);
2443 SrcLoop = tmpAddRec->getLoop();
2446 DstLoop = SrcAddRec->
getLoop();
2449 }
else if (DstAddRec) {
2450 if (
const SCEVAddRecExpr *tmpAddRec =
2452 DstConst = tmpAddRec->getStart();
2453 DstCoeff = tmpAddRec->getStepRecurrence(*SE);
2454 DstLoop = tmpAddRec->getLoop();
2457 SrcLoop = DstAddRec->
getLoop();
2462 return exactRDIVtest(SrcCoeff, DstCoeff, SrcConst, DstConst, SrcLoop, DstLoop,
2464 gcdMIVtest(Src, Dst, Result) ||
2465 symbolicRDIVtest(SrcCoeff, DstCoeff, SrcConst, DstConst, SrcLoop,
2472bool DependenceInfo::testMIV(
const SCEV *Src,
const SCEV *Dst,
2473 const SmallBitVector &
Loops,
2474 FullDependence &Result)
const {
2477 Result.Consistent =
false;
2478 return gcdMIVtest(Src, Dst, Result) ||
2479 banerjeeMIVtest(Src, Dst,
Loops, Result);
2490 return std::nullopt;
2493bool DependenceInfo::accumulateCoefficientsGCD(
const SCEV *Expr,
2494 const Loop *CurLoop,
2495 const SCEV *&CurLoopCoeff,
2496 APInt &RunningGCD)
const {
2499 if (RunningGCD == 1)
2504 assert(isLoopInvariant(Expr, CurLoop) &&
2505 "Expected loop invariant expression");
2512 if (AddRec->
getLoop() == CurLoop) {
2513 CurLoopCoeff = Step;
2527 return accumulateCoefficientsGCD(Start, CurLoop, CurLoopCoeff, RunningGCD);
2548bool DependenceInfo::gcdMIVtest(
const SCEV *Src,
const SCEV *Dst,
2549 FullDependence &Result)
const {
2554 unsigned BitWidth = SE->getTypeSizeInBits(Src->getType());
2561 const SCEV *Coefficients = Src;
2562 while (
const SCEVAddRecExpr *AddRec =
2573 const SCEV *SrcConst = Coefficients;
2580 while (
const SCEVAddRecExpr *AddRec =
2591 const SCEV *DstConst = Coefficients;
2594 const SCEV *Delta = SE->getMinusSCEV(DstConst, SrcConst);
2599 for (
const SCEV *Operand : Sum->
operands()) {
2601 assert(!Constant &&
"Surprised to find multiple constants");
2618 if (ConstDelta == 0)
2622 APInt Remainder = ConstDelta.
srem(RunningGCD);
2623 if (Remainder != 0) {
2642 bool Improved =
false;
2644 while (
const SCEVAddRecExpr *AddRec =
2647 const Loop *CurLoop = AddRec->
getLoop();
2648 RunningGCD = ExtraGCD;
2650 const SCEV *DstCoeff = SE->getMinusSCEV(SrcCoeff, SrcCoeff);
2652 if (!accumulateCoefficientsGCD(Src, CurLoop, SrcCoeff, RunningGCD) ||
2653 !accumulateCoefficientsGCD(Dst, CurLoop, DstCoeff, RunningGCD))
2656 Delta = SE->getMinusSCEV(SrcCoeff, DstCoeff);
2666 if (RunningGCD != 0) {
2667 Remainder = ConstDelta.
srem(RunningGCD);
2669 if (Remainder != 0) {
2670 unsigned Level = mapSrcLoop(CurLoop);
2671 Result.DV[
Level - 1].Direction &= ~Dependence::DVEntry::EQ;
2715bool DependenceInfo::banerjeeMIVtest(
const SCEV *Src,
const SCEV *Dst,
2716 const SmallBitVector &
Loops,
2717 FullDependence &Result)
const {
2721 ++BanerjeeApplications;
2724 CoefficientInfo *
A = collectCoeffInfo(Src,
true, A0);
2727 CoefficientInfo *
B = collectCoeffInfo(Dst,
false, B0);
2728 BoundInfo *Bound =
new BoundInfo[MaxLevels + 1];
2729 const SCEV *Delta = SE->getMinusSCEV(B0, A0);
2734 for (
unsigned K = 1;
K <= MaxLevels; ++
K) {
2735 Bound[
K].Iterations =
A[
K].Iterations ?
A[
K].Iterations :
B[
K].Iterations;
2738 findBoundsALL(
A,
B, Bound, K);
2753 bool Disproved =
false;
2756 unsigned DepthExpanded = 0;
2758 exploreDirections(1,
A,
B, Bound,
Loops, DepthExpanded, Delta);
2760 bool Improved =
false;
2761 for (
unsigned K = 1;
K <= CommonLevels; ++
K) {
2763 unsigned Old =
Result.DV[
K - 1].Direction;
2764 Result.DV[
K - 1].Direction = Old & Bound[
K].DirSet;
2765 Improved |= Old !=
Result.DV[
K - 1].Direction;
2766 if (!
Result.DV[K - 1].Direction) {
2774 ++BanerjeeSuccesses;
2776 ++BanerjeeIndependence;
2780 ++BanerjeeIndependence;
2794unsigned DependenceInfo::exploreDirections(
unsigned Level, CoefficientInfo *
A,
2795 CoefficientInfo *
B, BoundInfo *Bound,
2796 const SmallBitVector &
Loops,
2797 unsigned &DepthExpanded,
2798 const SCEV *Delta)
const {
2804 LLVM_DEBUG(
dbgs() <<
"Number of common levels exceeded the threshold. MIV "
2805 "direction exploration is terminated.\n");
2806 for (
unsigned K = 1;
K <= CommonLevels; ++
K)
2812 if (Level > CommonLevels) {
2815 for (
unsigned K = 1;
K <= CommonLevels; ++
K) {
2817 Bound[
K].DirSet |= Bound[
K].Direction;
2842 if (Level > DepthExpanded) {
2843 DepthExpanded =
Level;
2845 findBoundsLT(
A,
B, Bound, Level);
2846 findBoundsGT(
A,
B, Bound, Level);
2847 findBoundsEQ(
A,
B, Bound, Level);
2886 unsigned NewDeps = 0;
2890 NewDeps += exploreDirections(Level + 1,
A,
B, Bound,
Loops, DepthExpanded,
2895 NewDeps += exploreDirections(Level + 1,
A,
B, Bound,
Loops, DepthExpanded,
2900 NewDeps += exploreDirections(Level + 1,
A,
B, Bound,
Loops, DepthExpanded,
2906 return exploreDirections(Level + 1,
A,
B, Bound,
Loops, DepthExpanded,
2911bool DependenceInfo::testBounds(
unsigned char DirKind,
unsigned Level,
2912 BoundInfo *Bound,
const SCEV *Delta)
const {
2913 Bound[
Level].Direction = DirKind;
2914 if (
const SCEV *LowerBound = getLowerBound(Bound))
2917 if (
const SCEV *UpperBound = getUpperBound(Bound))
2938void DependenceInfo::findBoundsALL(CoefficientInfo *
A, CoefficientInfo *
B,
2939 BoundInfo *Bound,
unsigned K)
const {
2944 if (Bound[K].Iterations) {
2946 SE->getMinusSCEV(
A[K].NegPart,
B[K].PosPart), Bound[K].Iterations);
2948 SE->getMinusSCEV(
A[K].PosPart,
B[K].NegPart), Bound[K].Iterations);
2953 SE->getZero(
A[K].Coeff->
getType());
2956 SE->getZero(
A[K].Coeff->
getType());
2975void DependenceInfo::findBoundsEQ(CoefficientInfo *
A, CoefficientInfo *
B,
2976 BoundInfo *Bound,
unsigned K)
const {
2981 if (Bound[K].Iterations) {
2982 const SCEV *Delta = SE->getMinusSCEV(
A[K].Coeff,
B[K].Coeff);
2983 const SCEV *NegativePart = getNegativePart(Delta);
2985 SE->getMulExpr(NegativePart, Bound[K].Iterations);
2986 const SCEV *PositivePart = getPositivePart(Delta);
2988 SE->getMulExpr(PositivePart, Bound[K].Iterations);
2992 const SCEV *Delta = SE->getMinusSCEV(
A[K].Coeff,
B[K].Coeff);
2993 const SCEV *NegativePart = getNegativePart(Delta);
2994 if (NegativePart->
isZero())
2996 const SCEV *PositivePart = getPositivePart(Delta);
2997 if (PositivePart->
isZero())
3015void DependenceInfo::findBoundsLT(CoefficientInfo *
A, CoefficientInfo *
B,
3016 BoundInfo *Bound,
unsigned K)
const {
3021 if (Bound[K].Iterations) {
3022 const SCEV *Iter_1 = SE->getMinusSCEV(
3023 Bound[K].Iterations, SE->getOne(Bound[K].Iterations->getType()));
3024 const SCEV *NegPart =
3025 getNegativePart(SE->getMinusSCEV(
A[K].NegPart,
B[K].Coeff));
3027 SE->getMinusSCEV(SE->getMulExpr(NegPart, Iter_1),
B[K].Coeff);
3028 const SCEV *PosPart =
3029 getPositivePart(SE->getMinusSCEV(
A[K].PosPart,
B[K].Coeff));
3031 SE->getMinusSCEV(SE->getMulExpr(PosPart, Iter_1),
B[K].Coeff);
3035 const SCEV *NegPart =
3036 getNegativePart(SE->getMinusSCEV(
A[K].NegPart,
B[K].Coeff));
3039 const SCEV *PosPart =
3040 getPositivePart(SE->getMinusSCEV(
A[K].PosPart,
B[K].Coeff));
3059void DependenceInfo::findBoundsGT(CoefficientInfo *
A, CoefficientInfo *
B,
3060 BoundInfo *Bound,
unsigned K)
const {
3065 if (Bound[K].Iterations) {
3066 const SCEV *Iter_1 = SE->getMinusSCEV(
3067 Bound[K].Iterations, SE->getOne(Bound[K].Iterations->getType()));
3068 const SCEV *NegPart =
3069 getNegativePart(SE->getMinusSCEV(
A[K].Coeff,
B[K].PosPart));
3071 SE->getAddExpr(SE->getMulExpr(NegPart, Iter_1),
A[K].Coeff);
3072 const SCEV *PosPart =
3073 getPositivePart(SE->getMinusSCEV(
A[K].Coeff,
B[K].NegPart));
3075 SE->getAddExpr(SE->getMulExpr(PosPart, Iter_1),
A[K].Coeff);
3079 const SCEV *NegPart =
3080 getNegativePart(SE->getMinusSCEV(
A[K].Coeff,
B[K].PosPart));
3083 const SCEV *PosPart =
3084 getPositivePart(SE->getMinusSCEV(
A[K].Coeff,
B[K].NegPart));
3091const SCEV *DependenceInfo::getPositivePart(
const SCEV *
X)
const {
3092 return SE->getSMaxExpr(
X, SE->getZero(
X->getType()));
3096const SCEV *DependenceInfo::getNegativePart(
const SCEV *
X)
const {
3097 return SE->getSMinExpr(
X, SE->getZero(
X->getType()));
3103DependenceInfo::CoefficientInfo *
3104DependenceInfo::collectCoeffInfo(
const SCEV *Subscript,
bool SrcFlag,
3105 const SCEV *&Constant)
const {
3106 const SCEV *
Zero = SE->getZero(Subscript->getType());
3107 CoefficientInfo *CI =
new CoefficientInfo[MaxLevels + 1];
3108 for (
unsigned K = 1;
K <= MaxLevels; ++
K) {
3110 CI[
K].PosPart =
Zero;
3111 CI[
K].NegPart =
Zero;
3112 CI[
K].Iterations =
nullptr;
3116 unsigned K = SrcFlag ? mapSrcLoop(L) : mapDstLoop(
L);
3118 CI[
K].PosPart = getPositivePart(CI[K].Coeff);
3119 CI[
K].NegPart = getNegativePart(CI[K].Coeff);
3120 CI[
K].Iterations = collectUpperBound(L, Subscript->getType());
3126 for (
unsigned K = 1;
K <= MaxLevels; ++
K) {
3133 if (CI[K].Iterations)
3148const SCEV *DependenceInfo::getLowerBound(BoundInfo *Bound)
const {
3149 const SCEV *Sum = Bound[1].Lower[Bound[1].Direction];
3150 for (
unsigned K = 2; Sum &&
K <= MaxLevels; ++
K) {
3163const SCEV *DependenceInfo::getUpperBound(BoundInfo *Bound)
const {
3164 const SCEV *Sum = Bound[1].Upper[Bound[1].Direction];
3165 for (
unsigned K = 2; Sum &&
K <= MaxLevels; ++
K) {
3183const SCEV *DependenceInfo::findCoefficient(
const SCEV *Expr,
3184 const Loop *TargetLoop)
const {
3187 return SE->getZero(Expr->
getType());
3188 if (AddRec->
getLoop() == TargetLoop)
3190 return findCoefficient(AddRec->
getStart(), TargetLoop);
3198const SCEV *DependenceInfo::zeroCoefficient(
const SCEV *Expr,
3199 const Loop *TargetLoop)
const {
3203 if (AddRec->
getLoop() == TargetLoop)
3205 return SE->getAddRecExpr(zeroCoefficient(AddRec->
getStart(), TargetLoop),
3215const SCEV *DependenceInfo::addToCoefficient(
const SCEV *Expr,
3216 const Loop *TargetLoop,
3217 const SCEV *
Value)
const {
3220 return SE->getAddRecExpr(Expr,
Value, TargetLoop,
3222 if (AddRec->
getLoop() == TargetLoop) {
3229 if (SE->isLoopInvariant(AddRec, TargetLoop))
3231 return SE->getAddRecExpr(
3247bool DependenceInfo::propagate(
const SCEV *&Src,
const SCEV *&Dst,
3248 SmallBitVector &
Loops,
3249 SmallVectorImpl<Constraint> &Constraints,
3252 for (
unsigned LI :
Loops.set_bits()) {
3255 if (Constraints[LI].isDistance())
3256 Result |= propagateDistance(Src, Dst, Constraints[LI], Consistent);
3257 else if (Constraints[LI].isLine())
3258 Result |= propagateLine(Src, Dst, Constraints[LI], Consistent);
3259 else if (Constraints[LI].isPoint())
3260 Result |= propagatePoint(Src, Dst, Constraints[LI]);
3270bool DependenceInfo::propagateDistance(
const SCEV *&Src,
const SCEV *&Dst,
3271 Constraint &CurConstraint,
3273 const Loop *CurSrcLoop = CurConstraint.getAssociatedSrcLoop();
3274 const Loop *CurDstLoop = CurConstraint.getAssociatedDstLoop();
3276 const SCEV *A_K = findCoefficient(Src, CurSrcLoop);
3279 const SCEV *DA_K = SE->getMulExpr(A_K, CurConstraint.getD());
3280 Src = SE->getMinusSCEV(Src, DA_K);
3281 Src = zeroCoefficient(Src, CurSrcLoop);
3284 Dst = addToCoefficient(Dst, CurDstLoop, SE->getNegativeSCEV(A_K));
3286 if (!findCoefficient(Dst, CurDstLoop)->
isZero())
3296bool DependenceInfo::propagateLine(
const SCEV *&Src,
const SCEV *&Dst,
3297 Constraint &CurConstraint,
3299 const Loop *CurSrcLoop = CurConstraint.getAssociatedSrcLoop();
3300 const Loop *CurDstLoop = CurConstraint.getAssociatedDstLoop();
3301 const SCEV *
A = CurConstraint.getA();
3302 const SCEV *
B = CurConstraint.getB();
3303 const SCEV *
C = CurConstraint.getC();
3311 if (!Bconst || !Cconst)
3314 APInt Charlie = Cconst->
getAPInt();
3315 APInt CdivB = Charlie.
sdiv(Beta);
3316 assert(Charlie.
srem(Beta) == 0 &&
"C should be evenly divisible by B");
3317 const SCEV *AP_K = findCoefficient(Dst, CurDstLoop);
3318 Src = SE->getMinusSCEV(Src, SE->getMulExpr(AP_K, SE->getConstant(CdivB)));
3319 Dst = zeroCoefficient(Dst, CurDstLoop);
3320 if (!findCoefficient(Src, CurSrcLoop)->
isZero())
3322 }
else if (
B->isZero()) {
3325 if (!Aconst || !Cconst)
3328 APInt Charlie = Cconst->
getAPInt();
3329 APInt CdivA = Charlie.
sdiv(Alpha);
3330 assert(Charlie.
srem(Alpha) == 0 &&
"C should be evenly divisible by A");
3331 const SCEV *A_K = findCoefficient(Src, CurSrcLoop);
3332 Src = SE->getAddExpr(Src, SE->getMulExpr(A_K, SE->getConstant(CdivA)));
3333 Src = zeroCoefficient(Src, CurSrcLoop);
3334 if (!findCoefficient(Dst, CurDstLoop)->
isZero())
3339 if (!Aconst || !Cconst)
3342 APInt Charlie = Cconst->
getAPInt();
3343 APInt CdivA = Charlie.
sdiv(Alpha);
3344 assert(Charlie.
srem(Alpha) == 0 &&
"C should be evenly divisible by A");
3345 const SCEV *A_K = findCoefficient(Src, CurSrcLoop);
3346 Src = SE->getAddExpr(Src, SE->getMulExpr(A_K, SE->getConstant(CdivA)));
3347 Src = zeroCoefficient(Src, CurSrcLoop);
3348 Dst = addToCoefficient(Dst, CurDstLoop, A_K);
3349 if (!findCoefficient(Dst, CurDstLoop)->
isZero())
3353 const SCEV *A_K = findCoefficient(Src, CurSrcLoop);
3354 Src = SE->getMulExpr(Src,
A);
3355 Dst = SE->getMulExpr(Dst,
A);
3356 Src = SE->getAddExpr(Src, SE->getMulExpr(A_K,
C));
3357 Src = zeroCoefficient(Src, CurSrcLoop);
3358 Dst = addToCoefficient(Dst, CurDstLoop, SE->getMulExpr(A_K,
B));
3359 if (!findCoefficient(Dst, CurDstLoop)->
isZero())
3370bool DependenceInfo::propagatePoint(
const SCEV *&Src,
const SCEV *&Dst,
3371 Constraint &CurConstraint) {
3372 const Loop *CurSrcLoop = CurConstraint.getAssociatedSrcLoop();
3373 const Loop *CurDstLoop = CurConstraint.getAssociatedDstLoop();
3374 const SCEV *A_K = findCoefficient(Src, CurSrcLoop);
3375 const SCEV *AP_K = findCoefficient(Dst, CurDstLoop);
3376 const SCEV *XA_K = SE->getMulExpr(A_K, CurConstraint.getX());
3377 const SCEV *YAP_K = SE->getMulExpr(AP_K, CurConstraint.getY());
3379 Src = SE->getAddExpr(Src, SE->getMinusSCEV(XA_K, YAP_K));
3380 Src = zeroCoefficient(Src, CurSrcLoop);
3383 Dst = zeroCoefficient(Dst, CurDstLoop);
3389void DependenceInfo::updateDirection(Dependence::DVEntry &Level,
3390 const Constraint &CurConstraint)
const {
3393 if (CurConstraint.isAny())
3395 else if (CurConstraint.isDistance()) {
3397 Level.Scalar =
false;
3398 Level.Distance = CurConstraint.getD();
3400 if (!SE->isKnownNonZero(
Level.Distance))
3402 if (!SE->isKnownNonPositive(
Level.Distance))
3404 if (!SE->isKnownNonNegative(
Level.Distance))
3406 Level.Direction &= NewDirection;
3407 }
else if (CurConstraint.isLine()) {
3408 Level.Scalar =
false;
3409 Level.Distance =
nullptr;
3411 }
else if (CurConstraint.isPoint()) {
3412 Level.Scalar =
false;
3413 Level.Distance =
nullptr;
3416 CurConstraint.getX()))
3420 CurConstraint.getX()))
3424 CurConstraint.getX()))
3427 Level.Direction &= NewDirection;
3436bool DependenceInfo::tryDelinearize(Instruction *Src, Instruction *Dst,
3437 SmallVectorImpl<Subscript> &Pair) {
3442 Loop *SrcLoop = LI->getLoopFor(Src->getParent());
3443 Loop *DstLoop = LI->getLoopFor(Dst->getParent());
3444 const SCEV *SrcAccessFn = SE->getSCEVAtScope(SrcPtr, SrcLoop);
3445 const SCEV *DstAccessFn = SE->getSCEVAtScope(DstPtr, DstLoop);
3446 const SCEVUnknown *SrcBase =
3448 const SCEVUnknown *DstBase =
3451 if (!SrcBase || !DstBase || SrcBase != DstBase)
3456 if (!tryDelinearizeFixedSize(Src, Dst, SrcAccessFn, DstAccessFn,
3457 SrcSubscripts, DstSubscripts) &&
3458 !tryDelinearizeParametricSize(Src, Dst, SrcAccessFn, DstAccessFn,
3459 SrcSubscripts, DstSubscripts))
3462 assert(isLoopInvariant(SrcBase, SrcLoop) &&
3463 isLoopInvariant(DstBase, DstLoop) &&
3464 "Expected SrcBase and DstBase to be loop invariant");
3468 dbgs() <<
"\nSrcSubscripts: ";
3469 for (
int I = 0;
I <
Size;
I++)
3470 dbgs() << *SrcSubscripts[
I];
3471 dbgs() <<
"\nDstSubscripts: ";
3472 for (
int I = 0;
I <
Size;
I++)
3473 dbgs() << *DstSubscripts[
I];
3481 for (
int I = 0;
I <
Size; ++
I) {
3482 Pair[
I].Src = SrcSubscripts[
I];
3483 Pair[
I].Dst = DstSubscripts[
I];
3484 unifySubscriptType(&Pair[
I]);
3493bool DependenceInfo::tryDelinearizeFixedSize(
3494 Instruction *Src, Instruction *Dst,
const SCEV *SrcAccessFn,
3495 const SCEV *DstAccessFn, SmallVectorImpl<const SCEV *> &SrcSubscripts,
3496 SmallVectorImpl<const SCEV *> &DstSubscripts) {
3498 const SCEVUnknown *SrcBase =
3500 const SCEVUnknown *DstBase =
3502 assert(SrcBase && DstBase && SrcBase == DstBase &&
3503 "expected src and dst scev unknowns to be equal");
3506 SmallVector<int, 4> SrcSizes;
3507 SmallVector<int, 4> DstSizes;
3516 if (SrcSizes.size() != DstSizes.
size() ||
3517 !std::equal(SrcSizes.begin(), SrcSizes.end(), DstSizes.
begin())) {
3518 SrcSubscripts.
clear();
3519 DstSubscripts.
clear();
3524 "Expected equal number of entries in the list of SrcSubscripts and "
3537 auto AllIndicesInRange = [&](SmallVector<int, 4> &DimensionSizes,
3538 SmallVectorImpl<const SCEV *> &Subscripts,
3540 size_t SSize = Subscripts.
size();
3541 for (
size_t I = 1;
I < SSize; ++
I) {
3542 const SCEV *S = Subscripts[
I];
3543 if (!isKnownNonNegative(S,
Ptr)) {
3545 dbgs() <<
"Check failed: !isKnownNonNegative(S, Ptr)\n";
3546 dbgs() <<
" S: " << *S <<
"\n" <<
" Ptr: " << *
Ptr <<
"\n";
3551 const SCEV *
Range = SE->getConstant(
3552 ConstantInt::get(SType, DimensionSizes[
I - 1],
false));
3553 if (!isKnownLessThan(S,
Range)) {
3555 dbgs() <<
"Check failed: !isKnownLessThan(S, Range)\n";
3556 dbgs() <<
" S: " << *S <<
"\n"
3557 <<
" Range: " << *
Range <<
"\n";
3566 if (!AllIndicesInRange(SrcSizes, SrcSubscripts, SrcPtr) ||
3567 !AllIndicesInRange(DstSizes, DstSubscripts, DstPtr)) {
3569 SrcSubscripts.
clear();
3570 DstSubscripts.
clear();
3575 dbgs() <<
"Delinearized subscripts of fixed-size array\n"
3576 <<
"SrcGEP:" << *SrcPtr <<
"\n"
3577 <<
"DstGEP:" << *DstPtr <<
"\n";
3582bool DependenceInfo::tryDelinearizeParametricSize(
3583 Instruction *Src, Instruction *Dst,
const SCEV *SrcAccessFn,
3584 const SCEV *DstAccessFn, SmallVectorImpl<const SCEV *> &SrcSubscripts,
3585 SmallVectorImpl<const SCEV *> &DstSubscripts) {
3589 const SCEVUnknown *SrcBase =
3591 const SCEVUnknown *DstBase =
3593 assert(SrcBase && DstBase && SrcBase == DstBase &&
3594 "expected src and dst scev unknowns to be equal");
3596 const SCEV *ElementSize = SE->getElementSize(Src);
3597 if (ElementSize != SE->getElementSize(Dst))
3600 const SCEV *SrcSCEV = SE->getMinusSCEV(SrcAccessFn, SrcBase);
3601 const SCEV *DstSCEV = SE->getMinusSCEV(DstAccessFn, DstBase);
3622 if (SrcSubscripts.
size() < 2 || DstSubscripts.
size() < 2 ||
3623 SrcSubscripts.
size() != DstSubscripts.
size())
3626 size_t Size = SrcSubscripts.
size();
3635 for (
size_t I = 1;
I <
Size; ++
I) {
3636 bool SNN = isKnownNonNegative(SrcSubscripts[
I], SrcPtr);
3637 bool DNN = isKnownNonNegative(DstSubscripts[
I], DstPtr);
3638 bool SLT = isKnownLessThan(SrcSubscripts[
I], Sizes[
I - 1]);
3639 bool DLT = isKnownLessThan(DstSubscripts[
I], Sizes[
I - 1]);
3640 if (SNN && DNN && SLT && DLT)
3644 dbgs() <<
"Delinearization checks failed: can't prove the following\n";
3646 dbgs() <<
" isKnownNonNegative(" << *SrcSubscripts[
I] <<
")\n";
3648 dbgs() <<
" isKnownNonNegative(" << *DstSubscripts[
I] <<
")\n";
3650 dbgs() <<
" isKnownLessThan(" << *SrcSubscripts[
I] <<
", "
3651 << *
Sizes[
I - 1] <<
")\n";
3653 dbgs() <<
" isKnownLessThan(" << *DstSubscripts[
I] <<
", "
3654 << *
Sizes[
I - 1] <<
")\n";
3668 for (
unsigned VI : BV.
set_bits()) {
3678 FunctionAnalysisManager::Invalidator &Inv) {
3685 return Inv.invalidate<
AAManager>(F, PA) ||
3705std::unique_ptr<Dependence>
3707 bool UnderRuntimeAssumptions) {
3709 bool PossiblyLoopIndependent =
true;
3711 PossiblyLoopIndependent =
false;
3713 if (!(Src->mayReadOrWriteMemory() && Dst->mayReadOrWriteMemory()))
3719 LLVM_DEBUG(
dbgs() <<
"can only handle simple loads and stores\n");
3720 return std::make_unique<Dependence>(Src, Dst,
3732 return std::make_unique<Dependence>(Src, Dst,
3746 LLVM_DEBUG(
dbgs() <<
"can't analyze must alias with different sizes\n");
3747 return std::make_unique<Dependence>(Src, Dst,
3753 const SCEV *SrcSCEV = SE->getSCEV(SrcPtr);
3754 const SCEV *DstSCEV = SE->getSCEV(DstPtr);
3757 const SCEV *SrcBase = SE->getPointerBase(SrcSCEV);
3758 const SCEV *DstBase = SE->getPointerBase(DstSCEV);
3759 if (SrcBase != DstBase) {
3766 LLVM_DEBUG(
dbgs() <<
"can't analyze SCEV with different pointer base\n");
3767 return std::make_unique<Dependence>(Src, Dst,
3775 Loop *SrcLoop = LI->getLoopFor(Src->getParent());
3776 Loop *DstLoop = LI->getLoopFor(Dst->getParent());
3777 if (!isLoopInvariant(SrcBase, SrcLoop) ||
3778 !isLoopInvariant(DstBase, DstLoop)) {
3779 LLVM_DEBUG(
dbgs() <<
"The base pointer is not loop invariant.\n");
3780 return std::make_unique<Dependence>(Src, Dst,
3785 const SCEV *SrcEv = SE->getMinusSCEV(SrcSCEV, SrcBase);
3786 const SCEV *DstEv = SE->getMinusSCEV(DstSCEV, DstBase);
3789 if (!SE->isKnownMultipleOf(SrcEv, EltSize, Assume) ||
3790 !SE->isKnownMultipleOf(DstEv, EltSize, Assume)) {
3791 LLVM_DEBUG(
dbgs() <<
"can't analyze SCEV with different offsets\n");
3792 return std::make_unique<Dependence>(Src, Dst,
3796 if (!Assume.empty()) {
3797 if (!UnderRuntimeAssumptions)
3798 return std::make_unique<Dependence>(Src, Dst,
3801 unsigned N = Assumptions.size();
3803 bool Implied =
false;
3804 for (
unsigned I = 0;
I !=
N && !Implied;
I++)
3805 if (Assumptions[
I]->implies(
P, *SE))
3808 Assumptions.push_back(
P);
3814 Pair[0].Src = SrcEv;
3815 Pair[0].Dst = DstEv;
3818 if (tryDelinearize(Src, Dst, Pair)) {
3820 Pairs = Pair.
size();
3825 establishNestingLevels(Src, Dst);
3827 LLVM_DEBUG(
dbgs() <<
" common nesting levels = " << CommonLevels <<
"\n");
3828 LLVM_DEBUG(
dbgs() <<
" maximum nesting levels = " << MaxLevels <<
"\n");
3829 LLVM_DEBUG(
dbgs() <<
" SameSD nesting levels = " << SameSDLevels <<
"\n");
3832 CommonLevels += SameSDLevels;
3833 MaxLevels -= SameSDLevels;
3834 if (SameSDLevels > 0) {
3837 for (
unsigned P = 0;
P < Pairs; ++
P) {
3839 Subscript::ClassificationKind TestClass =
3840 classifyPair(Pair[
P].Src, LI->getLoopFor(Src->getParent()),
3841 Pair[
P].Dst, LI->getLoopFor(Dst->getParent()),
Loops);
3843 if (TestClass != Subscript::ZIV && TestClass != Subscript::SIV &&
3844 TestClass != Subscript::RDIV) {
3846 CommonLevels -= SameSDLevels;
3847 MaxLevels += SameSDLevels;
3854 if (SameSDLevels > 0)
3858 PossiblyLoopIndependent, CommonLevels);
3861 for (
unsigned P = 0;
P < Pairs; ++
P) {
3862 assert(Pair[
P].Src->getType()->isIntegerTy() &&
"Src must be an integer");
3863 assert(Pair[
P].Dst->getType()->isIntegerTy() &&
"Dst must be an integer");
3864 Pair[
P].Loops.
resize(MaxLevels + 1);
3865 Pair[
P].GroupLoops.
resize(MaxLevels + 1);
3867 removeMatchingExtensions(&Pair[
P]);
3868 Pair[
P].Classification =
3869 classifyPair(Pair[
P].Src, LI->getLoopFor(Src->getParent()), Pair[
P].Dst,
3870 LI->getLoopFor(Dst->getParent()), Pair[
P].Loops);
3871 Pair[
P].GroupLoops = Pair[
P].Loops;
3872 Pair[
P].Group.set(
P);
3941 for (
unsigned SI = 0;
SI < Pairs; ++
SI) {
3942 if (Pair[
SI].Classification == Subscript::NonLinear) {
3944 ++NonlinearSubscriptPairs;
3945 collectCommonLoops(Pair[
SI].Src, LI->getLoopFor(Src->getParent()),
3947 collectCommonLoops(Pair[
SI].Dst, LI->getLoopFor(Dst->getParent()),
3949 Result.Consistent =
false;
3950 }
else if (Pair[
SI].Classification == Subscript::ZIV) {
3956 for (
unsigned SJ =
SI + 1; SJ < Pairs; ++SJ) {
3958 Intersection &= Pair[SJ].GroupLoops;
3959 if (Intersection.
any()) {
3961 Pair[SJ].GroupLoops |= Pair[
SI].GroupLoops;
3963 Pair[SJ].Group |= Pair[
SI].Group;
3968 if (Pair[
SI].Group.count() == 1) {
3970 ++SeparableSubscriptPairs;
3973 ++CoupledSubscriptPairs;
3984 Constraint NewConstraint;
3985 NewConstraint.setAny(SE);
3990 switch (Pair[
SI].Classification) {
3991 case Subscript::ZIV:
3993 if (testZIV(Pair[
SI].Src, Pair[
SI].Dst, Result))
3996 case Subscript::SIV: {
3999 const SCEV *SplitIter =
nullptr;
4000 if (testSIV(Pair[
SI].Src, Pair[
SI].Dst, Level, Result, NewConstraint,
4005 case Subscript::RDIV:
4007 if (testRDIV(Pair[
SI].Src, Pair[
SI].Dst, Result))
4010 case Subscript::MIV:
4012 if (testMIV(Pair[
SI].Src, Pair[
SI].Dst, Pair[
SI].
Loops, Result))
4020 if (Coupled.
count()) {
4023 LLVM_DEBUG(
dbgs() <<
"MaxLevels + 1 = " << MaxLevels + 1 <<
"\n");
4025 for (
unsigned II = 0;
II <= MaxLevels; ++
II)
4026 Constraints[
II].setAny(SE);
4034 for (
unsigned SJ : Group.set_bits()) {
4036 if (Pair[SJ].Classification == Subscript::SIV)
4042 unifySubscriptType(PairsInGroup);
4044 while (Sivs.
any()) {
4046 for (
unsigned SJ : Sivs.
set_bits()) {
4050 const SCEV *SplitIter =
nullptr;
4052 if (testSIV(Pair[SJ].Src, Pair[SJ].Dst, Level, Result, NewConstraint,
4055 ConstrainedLevels.
set(Level);
4056 if (intersectConstraints(&Constraints[Level], &NewConstraint)) {
4057 if (Constraints[Level].isEmpty()) {
4058 ++DeltaIndependence;
4070 for (
unsigned SJ : Mivs.
set_bits()) {
4073 if (propagate(Pair[SJ].Src, Pair[SJ].Dst, Pair[SJ].
Loops,
4074 Constraints, Result.Consistent)) {
4076 ++DeltaPropagations;
4077 Pair[SJ].Classification = classifyPair(
4078 Pair[SJ].Src, LI->getLoopFor(Src->getParent()), Pair[SJ].Dst,
4079 LI->getLoopFor(Dst->getParent()), Pair[SJ].Loops);
4080 switch (Pair[SJ].Classification) {
4081 case Subscript::ZIV:
4083 if (testZIV(Pair[SJ].Src, Pair[SJ].Dst, Result))
4087 case Subscript::SIV:
4091 case Subscript::RDIV:
4092 case Subscript::MIV:
4103 for (
unsigned SJ : Mivs.
set_bits()) {
4104 if (Pair[SJ].Classification == Subscript::RDIV) {
4106 if (testRDIV(Pair[SJ].Src, Pair[SJ].Dst, Result))
4116 for (
unsigned SJ : Mivs.
set_bits()) {
4117 if (Pair[SJ].Classification == Subscript::MIV) {
4119 if (testMIV(Pair[SJ].Src, Pair[SJ].Dst, Pair[SJ].
Loops, Result))
4127 for (
unsigned SJ : ConstrainedLevels.
set_bits()) {
4128 if (SJ > CommonLevels)
4130 updateDirection(Result.DV[SJ - 1], Constraints[SJ]);
4139 for (
unsigned SI = 0;
SI < Pairs; ++
SI)
4140 CompleteLoops |= Pair[
SI].
Loops;
4141 for (
unsigned II = 1;
II <= CommonLevels; ++
II)
4142 if (CompleteLoops[
II])
4143 Result.DV[
II - 1].Scalar =
false;
4148 for (
unsigned II = 1;
II <= Result.getLevels(); ++
II) {
4150 if (Result.DV[
II - 1].Distance ==
nullptr)
4151 Result.DV[
II - 1].Distance = SE->getZero(SrcSCEV->
getType());
4153 assert(Result.DV[
II - 1].Distance->isZero() &&
4154 "Inconsistency between distance and direction");
4160 const SCEV *Distance = Result.getDistance(
II);
4161 if (Distance && Distance->
isZero())
4163 "Distance is zero, but direction is not EQ");
4167 if (SameSDLevels > 0) {
4170 assert(CommonLevels >= SameSDLevels);
4171 CommonLevels -= SameSDLevels;
4172 MaxLevels += SameSDLevels;
4173 std::unique_ptr<FullDependence::DVEntry[]> DV, DVSameSD;
4174 DV = std::make_unique<FullDependence::DVEntry[]>(CommonLevels);
4175 DVSameSD = std::make_unique<FullDependence::DVEntry[]>(SameSDLevels);
4176 for (
unsigned Level = 0; Level < CommonLevels; ++Level)
4177 DV[Level] = Result.DV[Level];
4178 for (
unsigned Level = 0; Level < SameSDLevels; ++Level)
4179 DVSameSD[Level] = Result.DV[CommonLevels + Level];
4180 Result.DV = std::move(DV);
4181 Result.DVSameSD = std::move(DVSameSD);
4182 Result.Levels = CommonLevels;
4183 Result.SameSDLevels = SameSDLevels;
4185 Result.Consistent =
false;
4188 if (PossiblyLoopIndependent) {
4192 for (
unsigned II = 1;
II <= CommonLevels; ++
II) {
4194 Result.LoopIndependent =
false;
4201 bool AllEqual =
true;
4202 for (
unsigned II = 1;
II <= CommonLevels; ++
II) {
4212 return std::make_unique<FullDependence>(std::move(Result));
4263 unsigned SplitLevel) {
4265 "Dep should be splitable at SplitLevel");
4268 assert(Src->mayReadFromMemory() || Src->mayWriteToMemory());
4269 assert(Dst->mayReadFromMemory() || Dst->mayWriteToMemory());
4279 establishNestingLevels(Src, Dst);
4281 FullDependence Result(Src, Dst, Dep.Assumptions,
false, CommonLevels);
4285 const SCEV *SrcSCEV = SE->getSCEV(SrcPtr);
4286 const SCEV *DstSCEV = SE->getSCEV(DstPtr);
4287 Pair[0].Src = SE->removePointerBase(SrcSCEV);
4288 Pair[0].Dst = SE->removePointerBase(DstSCEV);
4291 if (tryDelinearize(Src, Dst, Pair)) {
4293 Pairs = Pair.
size();
4297 for (
unsigned P = 0;
P < Pairs; ++
P) {
4298 assert(Pair[
P].Src->getType()->isIntegerTy() &&
"Src must be an integer");
4299 assert(Pair[
P].Dst->getType()->isIntegerTy() &&
"Dst must be an integer");
4300 Pair[
P].Loops.
resize(MaxLevels + 1);
4301 Pair[
P].GroupLoops.
resize(MaxLevels + 1);
4303 removeMatchingExtensions(&Pair[
P]);
4304 Pair[
P].Classification =
4305 classifyPair(Pair[
P].Src, LI->getLoopFor(Src->getParent()), Pair[
P].Dst,
4306 LI->getLoopFor(Dst->getParent()), Pair[
P].Loops);
4307 Pair[
P].GroupLoops = Pair[
P].Loops;
4308 Pair[
P].Group.set(
P);
4315 for (
unsigned SI = 0;
SI < Pairs; ++
SI) {
4316 if (Pair[
SI].Classification == Subscript::NonLinear) {
4318 collectCommonLoops(Pair[
SI].Src, LI->getLoopFor(Src->getParent()),
4320 collectCommonLoops(Pair[
SI].Dst, LI->getLoopFor(Dst->getParent()),
4322 Result.Consistent =
false;
4323 }
else if (Pair[
SI].Classification == Subscript::ZIV)
4328 for (
unsigned SJ =
SI + 1; SJ < Pairs; ++SJ) {
4330 Intersection &= Pair[SJ].GroupLoops;
4331 if (Intersection.
any()) {
4333 Pair[SJ].GroupLoops |= Pair[
SI].GroupLoops;
4335 Pair[SJ].Group |= Pair[
SI].Group;
4340 if (Pair[
SI].Group.count() == 1)
4348 Constraint NewConstraint;
4349 NewConstraint.setAny(SE);
4353 switch (Pair[
SI].Classification) {
4354 case Subscript::SIV: {
4356 const SCEV *SplitIter =
nullptr;
4357 (void)testSIV(Pair[
SI].Src, Pair[
SI].Dst, Level, Result, NewConstraint,
4359 if (Level == SplitLevel) {
4360 assert(SplitIter !=
nullptr);
4365 case Subscript::ZIV:
4366 case Subscript::RDIV:
4367 case Subscript::MIV:
4374 assert(!Coupled.
empty() &&
"coupled expected non-empty");
4378 for (
unsigned II = 0;
II <= MaxLevels; ++
II)
4379 Constraints[
II].setAny(SE);
4385 for (
unsigned SJ : Group.set_bits()) {
4386 if (Pair[SJ].Classification == Subscript::SIV)
4391 while (Sivs.
any()) {
4393 for (
unsigned SJ : Sivs.
set_bits()) {
4396 const SCEV *SplitIter =
nullptr;
4397 (void)testSIV(Pair[SJ].Src, Pair[SJ].Dst, Level, Result, NewConstraint,
4399 if (Level == SplitLevel && SplitIter)
4401 ConstrainedLevels.
set(Level);
4402 if (intersectConstraints(&Constraints[Level], &NewConstraint))
4409 for (
unsigned SJ : Mivs.
set_bits()) {
4411 if (!propagate(Pair[SJ].Src, Pair[SJ].Dst, Pair[SJ].
Loops, Constraints,
4414 Pair[SJ].Classification = classifyPair(
4415 Pair[SJ].Src, LI->getLoopFor(Src->getParent()), Pair[SJ].Dst,
4416 LI->getLoopFor(Dst->getParent()), Pair[SJ].Loops);
4417 switch (Pair[SJ].Classification) {
4418 case Subscript::ZIV:
4421 case Subscript::SIV:
4425 case Subscript::RDIV:
4426 case Subscript::MIV:
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
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")
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
static bool isLoadOrStore(const Instruction *I)
static bool findGCD(unsigned Bits, const APInt &AM, const APInt &BM, const APInt &Delta, APInt &G, APInt &X, APInt &Y)
static void dumpSmallBitVector(SmallBitVector &BV)
static APInt ceilingOfQuotient(const APInt &A, const APInt &B)
static APInt floorOfQuotient(const APInt &A, const APInt &B)
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 cl::opt< bool > RunSIVRoutinesOnly("da-run-siv-routines-only", cl::init(false), cl::ReallyHidden, cl::desc("Run only SIV routines and disable others (ZIV, RDIV, and MIV). " "The purpose is mainly to exclude the influence of those routines " "in regression tests for SIV routines."))
static std::pair< std::optional< APInt >, std::optional< APInt > > inferDomainOfAffine(const APInt &A, const APInt &B, const std::optional< APInt > &UB)
Given an affine expression of the form A*k + B, where k is an arbitrary integer, infer the possible r...
static std::optional< APInt > getConstantPart(const SCEV *Expr)
static bool isRemainderZero(const SCEVConstant *Dividend, const SCEVConstant *Divisor)
static cl::opt< bool > Delinearize("da-delinearize", cl::init(true), cl::Hidden, cl::desc("Try to delinearize array references."))
static void dumpExampleDependence(raw_ostream &OS, DependenceInfo *DA, ScalarEvolution &SE, bool NormalizeResults)
static cl::opt< unsigned > MIVMaxLevelThreshold("da-miv-max-level-threshold", cl::init(7), cl::Hidden, cl::desc("Maximum depth allowed for the recursive algorithm used to " "explore MIV direction vectors."))
static cl::opt< bool > DisableDelinearizationChecks("da-disable-delinearization-checks", cl::Hidden, cl::desc("Disable checks that try to statically verify validity of " "delinearized subscripts. Enabling this option may result in incorrect " "dependence vectors for languages that allow the subscript of one " "dimension to underflow or overflow into another dimension."))
Module.h This file contains the declarations for the Module class.
static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT, AssumptionCache *AC)
Loop::LoopBounds::Direction Direction
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
uint64_t IntrinsicInst * II
static bool isInput(const ArrayRef< StringRef > &Prefixes, StringRef Arg)
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)
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")
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
LocallyHashedType DenseMapInfo< LocallyHashedType >::Empty
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.
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.
static APInt getSignedMaxValue(unsigned numBits)
Gets maximum signed value of APInt for a specific bit width.
LLVM_ABI APInt sdiv(const APInt &RHS) const
Signed division function for APInt.
bool sle(const APInt &RHS) const
Signed less or equal comparison.
static APInt getSignedMinValue(unsigned numBits)
Gets minimum signed value of APInt for a specific bit width.
LLVM_ABI APInt srem(const APInt &RHS) const
Function for signed remainder operation.
bool slt(const APInt &RHS) const
Signed less than comparison.
static APInt getZero(unsigned numBits)
Get the '0' value for the specified bit-width.
bool sge(const APInt &RHS) const
Signed greater or equal comparison.
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()
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)
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ ICMP_SLT
signed less than
@ ICMP_SLE
signed less or equal
@ ICMP_SGT
signed greater than
@ ICMP_SGE
signed greater or equal
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 const SCEV * getSplitIteration(const Dependence &Dep, unsigned Level)
getSplitIteration - Give a dependence that's splittable at some particular level, return the iteratio...
LLVM_ABI SCEVUnionPredicate getRuntimeAssumptions() const
getRuntimeAssumptions - Returns all the runtime assumptions under which the dependence test is valid.
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.
Dependence - This class represents a dependence between two memory memory references in a function.
Instruction * getDst() const
getDst - Returns the destination instruction for this dependence.
Dependence(Dependence &&)=default
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 bool isPeelLast(unsigned Level, bool SameSD=false) const
isPeelLast - Returns true if peeling the last iteration from this regular or SameSD loop level will b...
virtual bool isConsistent() const
isConsistent - Returns true if this dependence is consistent (occurs every time the source and destin...
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.
virtual bool isPeelFirst(unsigned Level, bool SameSD=false) const
isPeelFirst - Returns true if peeling the first iteration from this regular or SameSD loop level will...
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 isSplitable(unsigned Level, bool SameSD=false) const
isSplitable - Returns true if splitting the loop will break the dependence.
Instruction * getSrc() const
getSrc - Returns the source instruction for this 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 dumpImp(raw_ostream &OS, bool SameSD=false) const
dumpImp - For debugging purposes.
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...
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.
const SCEV * getDistance(unsigned Level, bool SameSD=false) const override
getDistance - Returns the distance (or NULL) associated with a particular common or SameSD level.
bool isSplitable(unsigned Level, bool SameSD=false) const override
isSplitable - Returns true if splitting the loop will break the dependence.
bool isPeelLast(unsigned Level, bool SameSD=false) const override
isPeelLast - Returns true if peeling the last iteration from this regular or SameSD loop level will b...
bool isPeelFirst(unsigned Level, bool SameSD=false) const override
isPeelFirst - Returns true if peeling the first iteration from this regular or SameSD loop level will...
bool inSameSDLoops(unsigned Level) const override
inSameSDLoops - Returns true if this level is an SameSD level, i.e., performed across two separate lo...
DVEntry getDVEntry(unsigned Level, bool isSameSD) const
getDVEntry - Returns the DV entry associated with a regular or a SameSD level.
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.
unsigned getBitWidth() const
Get the number of bits in this 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.
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.
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.
const SCEV * getStart() const
LLVM_ABI const SCEV * evaluateAtIteration(const SCEV *It, ScalarEvolution &SE) const
Return the value of this chain of recurrences at the specified iteration number.
const SCEV * getStepRecurrence(ScalarEvolution &SE) const
Constructs and returns the recurrence indicating how much this expression steps by.
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
const SCEV * getOperand() const
This class represents a constant integer value.
const APInt & getAPInt() const
bool hasNoSignedWrap() const
NoWrapFlags getNoWrapFlags(NoWrapFlags Mask=NoWrapMask) const
const SCEV * getOperand(unsigned i) const
This class represents an assumption made using SCEV expressions which can be checked at run-time.
This class represents a composition of other SCEV predicates, and is the class that most clients will...
void print(raw_ostream &OS, unsigned Depth) const override
Prints a textual representation of this predicate with an indentation of Depth.
bool isAlwaysTrue() const override
Implementation of the SCEVPredicate interface.
This class represents an analyzed expression in the program.
LLVM_ABI ArrayRef< const SCEV * > operands() const
Return operands of this SCEV expression.
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.
LLVM_ABI 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 const SCEV * getNegativeSCEV(const SCEV *V, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap)
Return the SCEV object corresponding to -V.
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(const SCEV *LHS, const SCEV *RHS, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap, unsigned Depth=0)
Return LHS-RHS.
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.
bool any() const
Returns true if any bit is set.
bool empty() const
Tests whether there are no bits in this bitvector.
size_type count() const
Returns the number of bits which are set.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
An instruction for storing to memory.
LLVM Value Representation.
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)
Compute GCD of two unsigned APInt values.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
@ BasicBlock
Various leaf nodes.
@ TB
TB - TwoByte - Set if this instruction has a two byte opcode, which starts with a 0x0F byte before th...
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
FunctionAddr VTableAddr Value
InstIterator< SymbolTableList< BasicBlock >, Function::iterator, BasicBlock::iterator, Instruction > inst_iterator
void collectParametricTerms(ScalarEvolution &SE, const SCEV *Expr, SmallVectorImpl< const SCEV * > &Terms)
Collect parametric terms occurring in step expressions (first step of delinearization).
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...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
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)
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 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...
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)
bool tryDelinearizeFixedSizeImpl(ScalarEvolution *SE, Instruction *Inst, const SCEV *AccessFn, SmallVectorImpl< const SCEV * > &Subscripts, SmallVectorImpl< int > &Sizes)
Implementation of fixed size array delinearization.
ArrayRef(const T &OneElt) -> ArrayRef< T >
constexpr unsigned BitWidth
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
LLVM_ABI const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=MaxLookupSearchDepth)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
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.
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...