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 <=
static_cast<unsigned>(Levels) + SameSDLevels &&
393 "Level out of range");
394 return Level > Levels;
402const SCEV *DependenceInfo::Constraint::getX()
const {
403 assert(Kind == Point &&
"Kind should be Point");
409const SCEV *DependenceInfo::Constraint::getY()
const {
410 assert(Kind == Point &&
"Kind should be Point");
416const SCEV *DependenceInfo::Constraint::getA()
const {
417 assert((Kind == Line || Kind == Distance) &&
418 "Kind should be Line (or Distance)");
424const SCEV *DependenceInfo::Constraint::getB()
const {
425 assert((Kind == Line || Kind == Distance) &&
426 "Kind should be Line (or Distance)");
432const SCEV *DependenceInfo::Constraint::getC()
const {
433 assert((Kind == Line || Kind == Distance) &&
434 "Kind should be Line (or Distance)");
440const SCEV *DependenceInfo::Constraint::getD()
const {
441 assert(Kind == Distance &&
"Kind should be Distance");
442 return SE->getNegativeSCEV(
C);
446const Loop *DependenceInfo::Constraint::getAssociatedSrcLoop()
const {
447 assert((Kind == Distance || Kind == Line || Kind == Point) &&
448 "Kind should be Distance, Line, or Point");
449 return AssociatedSrcLoop;
453const Loop *DependenceInfo::Constraint::getAssociatedDstLoop()
const {
454 assert((Kind == Distance || Kind == Line || Kind == Point) &&
455 "Kind should be Distance, Line, or Point");
456 return AssociatedDstLoop;
459void DependenceInfo::Constraint::setPoint(
const SCEV *
X,
const SCEV *
Y,
460 const Loop *CurSrcLoop,
461 const Loop *CurDstLoop) {
465 AssociatedSrcLoop = CurSrcLoop;
466 AssociatedDstLoop = CurDstLoop;
469void DependenceInfo::Constraint::setLine(
const SCEV *AA,
const SCEV *BB,
470 const SCEV *CC,
const Loop *CurSrcLoop,
471 const Loop *CurDstLoop) {
476 AssociatedSrcLoop = CurSrcLoop;
477 AssociatedDstLoop = CurDstLoop;
480void DependenceInfo::Constraint::setDistance(
const SCEV *
D,
481 const Loop *CurSrcLoop,
482 const Loop *CurDstLoop) {
484 A = SE->getOne(
D->getType());
485 B = SE->getNegativeSCEV(
A);
486 C = SE->getNegativeSCEV(
D);
487 AssociatedSrcLoop = CurSrcLoop;
488 AssociatedDstLoop = CurDstLoop;
491void DependenceInfo::Constraint::setEmpty() {
Kind =
Empty; }
493void DependenceInfo::Constraint::setAny(ScalarEvolution *NewSE) {
498#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
500LLVM_DUMP_METHOD void DependenceInfo::Constraint::dump(raw_ostream &OS)
const {
506 OS <<
" Point is <" << *getX() <<
", " << *getY() <<
">\n";
507 else if (isDistance())
508 OS <<
" Distance is " << *getD() <<
" (" << *getA() <<
"*X + " << *getB()
509 <<
"*Y = " << *getC() <<
")\n";
511 OS <<
" Line is " << *getA() <<
"*X + " << *getB() <<
"*Y = " << *getC()
525bool DependenceInfo::intersectConstraints(Constraint *
X,
const Constraint *
Y) {
530 assert(!
Y->isPoint() &&
"Y must not be a Point");
544 if (
X->isDistance() &&
Y->isDistance()) {
568 assert(!(
X->isPoint() &&
Y->isPoint()) &&
569 "We shouldn't ever see X->isPoint() && Y->isPoint()");
571 if (
X->isLine() &&
Y->isLine()) {
573 const SCEV *Prod1 = SE->getMulExpr(
X->getA(),
Y->getB());
574 const SCEV *Prod2 = SE->getMulExpr(
X->getB(),
Y->getA());
578 Prod1 = SE->getMulExpr(
X->getC(),
Y->getB());
579 Prod2 = SE->getMulExpr(
X->getB(),
Y->getC());
592 const SCEV *C1B2 = SE->getMulExpr(
X->getC(),
Y->getB());
593 const SCEV *C1A2 = SE->getMulExpr(
X->getC(),
Y->getA());
594 const SCEV *C2B1 = SE->getMulExpr(
Y->getC(),
X->getB());
595 const SCEV *C2A1 = SE->getMulExpr(
Y->getC(),
X->getA());
596 const SCEV *A1B2 = SE->getMulExpr(
X->getA(),
Y->getB());
597 const SCEV *A2B1 = SE->getMulExpr(
Y->getA(),
X->getB());
598 const SCEVConstant *C1A2_C2A1 =
600 const SCEVConstant *C1B2_C2B1 =
602 const SCEVConstant *A1B2_A2B1 =
604 const SCEVConstant *A2B1_A1B2 =
606 if (!C1B2_C2B1 || !C1A2_C2A1 || !A1B2_A2B1 || !A2B1_A1B2)
622 if (Xr != 0 || Yr != 0) {
628 if (Xq.
slt(0) || Yq.
slt(0)) {
633 if (
const SCEVConstant *CUB = collectConstantUpperBound(
634 X->getAssociatedSrcLoop(), Prod1->
getType())) {
635 const APInt &UpperBound = CUB->getAPInt();
637 if (Xq.
sgt(UpperBound) || Yq.
sgt(UpperBound)) {
643 X->setPoint(SE->getConstant(Xq), SE->getConstant(Yq),
644 X->getAssociatedSrcLoop(),
X->getAssociatedDstLoop());
652 assert(!(
X->isLine() &&
Y->isPoint()) &&
"This case should never occur");
654 if (
X->isPoint() &&
Y->isLine()) {
656 const SCEV *A1X1 = SE->getMulExpr(
Y->getA(),
X->getX());
657 const SCEV *B1Y1 = SE->getMulExpr(
Y->getB(),
X->getY());
658 const SCEV *Sum = SE->getAddExpr(A1X1, B1Y1);
693 if (SameSDLevels > 0) {
694 OS <<
"! / assuming " << SameSDLevels <<
" loop level(s) fused: ";
701 if (!Assumptions.isAlwaysTrue()) {
702 OS <<
" Runtime Assumptions:\n";
703 Assumptions.print(OS, 2);
710 bool Splitable =
false;
713 bool OnSameSD =
false;
714 unsigned LevelNum = Levels;
716 LevelNum += SameSDLevels;
718 for (
unsigned II = 1;
II <= LevelNum; ++
II) {
797 return LI->isUnordered();
799 return SI->isUnordered();
807bool DependenceInfo::haveSameSD(
const Loop *SrcLoop,
808 const Loop *DstLoop)
const {
809 if (SrcLoop == DstLoop)
819 const SCEV *SrcUB =
nullptr, *DstUP =
nullptr;
820 if (SE->hasLoopInvariantBackedgeTakenCount(SrcLoop))
821 SrcUB = SE->getBackedgeTakenCount(SrcLoop);
822 if (SE->hasLoopInvariantBackedgeTakenCount(DstLoop))
823 DstUP = SE->getBackedgeTakenCount(DstLoop);
825 if (SrcUB !=
nullptr && DstUP !=
nullptr &&
894void DependenceInfo::establishNestingLevels(
const Instruction *Src,
895 const Instruction *Dst) {
896 const BasicBlock *SrcBlock = Src->getParent();
897 const BasicBlock *DstBlock = Dst->getParent();
898 unsigned SrcLevel = LI->getLoopDepth(SrcBlock);
899 unsigned DstLevel = LI->getLoopDepth(DstBlock);
900 const Loop *SrcLoop = LI->getLoopFor(SrcBlock);
901 const Loop *DstLoop = LI->getLoopFor(DstBlock);
902 SrcLevels = SrcLevel;
903 MaxLevels = SrcLevel + DstLevel;
905 while (SrcLevel > DstLevel) {
909 while (DstLevel > SrcLevel) {
915 while (SrcLoop != DstLoop) {
917 if (!haveSameSD(SrcLoop, DstLoop))
923 CommonLevels = SrcLevel;
924 MaxLevels -= CommonLevels;
929unsigned DependenceInfo::mapSrcLoop(
const Loop *SrcLoop)
const {
935unsigned DependenceInfo::mapDstLoop(
const Loop *DstLoop)
const {
937 if (
D > CommonLevels)
940 return D - CommonLevels + SrcLevels;
946bool DependenceInfo::isLoopInvariant(
const SCEV *Expression,
947 const Loop *LoopNest)
const {
962void DependenceInfo::collectCommonLoops(
const SCEV *Expression,
963 const Loop *LoopNest,
964 SmallBitVector &
Loops)
const {
967 if (Level <= CommonLevels && !SE->isLoopInvariant(Expression, LoopNest))
975 unsigned widestWidthSeen = 0;
980 for (Subscript *Pair : Pairs) {
981 const SCEV *Src = Pair->Src;
982 const SCEV *Dst = Pair->Dst;
985 if (SrcTy ==
nullptr || DstTy ==
nullptr) {
987 "This function only unify integer types and "
988 "expect Src and Dst share the same type otherwise.");
1001 assert(widestWidthSeen > 0);
1004 for (Subscript *Pair : Pairs) {
1005 const SCEV *Src = Pair->Src;
1006 const SCEV *Dst = Pair->Dst;
1009 if (SrcTy ==
nullptr || DstTy ==
nullptr) {
1011 "This function only unify integer types and "
1012 "expect Src and Dst share the same type otherwise.");
1017 Pair->Src = SE->getSignExtendExpr(Src, widestType);
1020 Pair->Dst = SE->getSignExtendExpr(Dst, widestType);
1029void DependenceInfo::removeMatchingExtensions(Subscript *Pair) {
1030 const SCEV *Src = Pair->Src;
1031 const SCEV *Dst = Pair->Dst;
1036 const SCEV *SrcCastOp = SrcCast->
getOperand();
1037 const SCEV *DstCastOp = DstCast->
getOperand();
1039 Pair->Src = SrcCastOp;
1040 Pair->Dst = DstCastOp;
1047bool DependenceInfo::checkSubscript(
const SCEV *Expr,
const Loop *LoopNest,
1048 SmallBitVector &
Loops,
bool IsSrc) {
1051 return isLoopInvariant(Expr, LoopNest);
1058 const Loop *
L = LoopNest;
1059 while (L && AddRec->
getLoop() != L)
1060 L =
L->getParentLoop();
1066 if (!isLoopInvariant(Step, LoopNest))
1072 return checkSubscript(Start, LoopNest,
Loops, IsSrc);
1077bool DependenceInfo::checkSrcSubscript(
const SCEV *Src,
const Loop *LoopNest,
1078 SmallBitVector &
Loops) {
1079 return checkSubscript(Src, LoopNest,
Loops,
true);
1084bool DependenceInfo::checkDstSubscript(
const SCEV *Dst,
const Loop *LoopNest,
1085 SmallBitVector &
Loops) {
1086 return checkSubscript(Dst, LoopNest,
Loops,
false);
1092DependenceInfo::Subscript::ClassificationKind
1093DependenceInfo::classifyPair(
const SCEV *Src,
const Loop *SrcLoopNest,
1094 const SCEV *Dst,
const Loop *DstLoopNest,
1095 SmallBitVector &
Loops) {
1096 SmallBitVector SrcLoops(MaxLevels + 1);
1097 SmallBitVector DstLoops(MaxLevels + 1);
1098 if (!checkSrcSubscript(Src, SrcLoopNest, SrcLoops))
1099 return Subscript::NonLinear;
1100 if (!checkDstSubscript(Dst, DstLoopNest, DstLoops))
1101 return Subscript::NonLinear;
1104 unsigned N =
Loops.count();
1106 return Subscript::ZIV;
1108 return Subscript::SIV;
1109 if (
N == 2 && (SrcLoops.count() == 0 || DstLoops.count() == 0 ||
1110 (SrcLoops.count() == 1 && DstLoops.count() == 1)))
1111 return Subscript::RDIV;
1112 return Subscript::MIV;
1126 const SCEV *
Y)
const {
1140 if (SE->isKnownPredicate(Pred,
X,
Y))
1147 const SCEV *Delta = SE->getMinusSCEV(
X,
Y);
1152 return SE->isKnownNonZero(Delta);
1154 return SE->isKnownNonNegative(Delta);
1156 return SE->isKnownNonPositive(Delta);
1158 return SE->isKnownPositive(Delta);
1160 return SE->isKnownNegative(Delta);
1172bool DependenceInfo::isKnownLessThan(
const SCEV *S,
const SCEV *
Size)
const {
1176 if (!SType || !SizeType)
1179 (SType->getBitWidth() >= SizeType->getBitWidth()) ? SType : SizeType;
1180 S = SE->getTruncateOrZeroExtend(S, MaxType);
1181 Size = SE->getTruncateOrZeroExtend(
Size, MaxType);
1186 const SCEV *BECount = SE->getBackedgeTakenCount(AddRec->
getLoop());
1190 const SCEV *Diff0 = SE->getMinusSCEV(Start,
Size);
1191 const SCEV *Diff1 = SE->getMinusSCEV(End,
Size);
1196 if (SE->isKnownNonNegative(Step) && SE->isKnownNegative(Diff1))
1201 if (SE->isKnownNonPositive(Step) && SE->isKnownNegative(Diff0))
1206 if (SE->isKnownNegative(Diff0) && SE->isKnownNegative(Diff1))
1211 const SCEV *LimitedBound = SE->getMinusSCEV(S,
Size);
1212 return SE->isKnownNegative(LimitedBound);
1215bool DependenceInfo::isKnownNonNegative(
const SCEV *S,
const Value *
Ptr)
const {
1216 bool Inbounds =
false;
1218 Inbounds = SrcGEP->isInBounds();
1224 if (SE->isKnownNonNegative(AddRec->
getStart()) &&
1225 SE->isKnownNonNegative(AddRec->
getOperand(1)))
1231 return SE->isKnownNonNegative(S);
1241const SCEV *DependenceInfo::collectUpperBound(
const Loop *L,
Type *
T)
const {
1242 if (SE->hasLoopInvariantBackedgeTakenCount(L)) {
1243 const SCEV *UB = SE->getBackedgeTakenCount(L);
1244 return SE->getTruncateOrZeroExtend(UB,
T);
1251const SCEVConstant *DependenceInfo::collectConstantUpperBound(
const Loop *L,
1253 if (
const SCEV *UB = collectUpperBound(L,
T))
1277bool DependenceInfo::testZIV(
const SCEV *Src,
const SCEV *Dst,
1278 FullDependence &Result)
const {
1292 Result.Consistent =
false;
1323bool DependenceInfo::strongSIVtest(
const SCEV *Coeff,
const SCEV *SrcConst,
1324 const SCEV *DstConst,
const Loop *CurSrcLoop,
1325 const Loop *CurDstLoop,
unsigned Level,
1326 FullDependence &Result,
1327 Constraint &NewConstraint)
const {
1335 ++StrongSIVapplications;
1336 assert(0 < Level && Level <= CommonLevels &&
"level out of range");
1339 const SCEV *Delta = SE->getMinusSCEV(SrcConst, DstConst);
1344 if (
const SCEV *UpperBound =
1345 collectUpperBound(CurSrcLoop, Delta->
getType())) {
1348 const SCEV *AbsDelta =
1349 SE->isKnownNonNegative(Delta) ? Delta : SE->getNegativeSCEV(Delta);
1350 const SCEV *AbsCoeff =
1351 SE->isKnownNonNegative(Coeff) ? Coeff : SE->getNegativeSCEV(Coeff);
1352 const SCEV *Product = SE->getMulExpr(UpperBound, AbsCoeff);
1355 ++StrongSIVindependence;
1356 ++StrongSIVsuccesses;
1365 APInt Distance = ConstDelta;
1366 APInt Remainder = ConstDelta;
1371 if (Remainder != 0) {
1373 ++StrongSIVindependence;
1374 ++StrongSIVsuccesses;
1377 Result.DV[
Level].Distance = SE->getConstant(Distance);
1378 NewConstraint.setDistance(SE->getConstant(Distance), CurSrcLoop,
1380 if (Distance.
sgt(0))
1382 else if (Distance.
slt(0))
1386 ++StrongSIVsuccesses;
1387 }
else if (Delta->
isZero()) {
1390 NewConstraint.setDistance(Delta, CurSrcLoop, CurDstLoop);
1392 ++StrongSIVsuccesses;
1394 if (Coeff->
isOne()) {
1397 NewConstraint.setDistance(Delta, CurSrcLoop, CurDstLoop);
1399 Result.Consistent =
false;
1400 NewConstraint.setLine(Coeff, SE->getNegativeSCEV(Coeff),
1401 SE->getNegativeSCEV(Delta), CurSrcLoop, CurDstLoop);
1405 bool DeltaMaybeZero = !SE->isKnownNonZero(Delta);
1406 bool DeltaMaybePositive = !SE->isKnownNonPositive(Delta);
1407 bool DeltaMaybeNegative = !SE->isKnownNonNegative(Delta);
1408 bool CoeffMaybePositive = !SE->isKnownNonPositive(Coeff);
1409 bool CoeffMaybeNegative = !SE->isKnownNonNegative(Coeff);
1414 if ((DeltaMaybePositive && CoeffMaybePositive) ||
1415 (DeltaMaybeNegative && CoeffMaybeNegative))
1419 if ((DeltaMaybeNegative && CoeffMaybePositive) ||
1420 (DeltaMaybePositive && CoeffMaybeNegative))
1422 if (NewDirection <
Result.DV[Level].Direction)
1423 ++StrongSIVsuccesses;
1457bool DependenceInfo::weakCrossingSIVtest(
1458 const SCEV *Coeff,
const SCEV *SrcConst,
const SCEV *DstConst,
1459 const Loop *CurSrcLoop,
const Loop *CurDstLoop,
unsigned Level,
1460 FullDependence &Result, Constraint &NewConstraint,
1461 const SCEV *&SplitIter)
const {
1466 ++WeakCrossingSIVapplications;
1467 assert(0 < Level && Level <= CommonLevels &&
"Level out of range");
1469 Result.Consistent =
false;
1470 const SCEV *Delta = SE->getMinusSCEV(DstConst, SrcConst);
1472 NewConstraint.setLine(Coeff, Coeff, Delta, CurSrcLoop, CurDstLoop);
1474 Result.DV[
Level].Direction &= ~Dependence::DVEntry::LT;
1475 Result.DV[
Level].Direction &= ~Dependence::DVEntry::GT;
1476 ++WeakCrossingSIVsuccesses;
1477 if (!
Result.DV[Level].Direction) {
1478 ++WeakCrossingSIVindependence;
1489 if (SE->isKnownNegative(ConstCoeff)) {
1492 "dynamic cast of negative of ConstCoeff should yield constant");
1493 Delta = SE->getNegativeSCEV(Delta);
1495 assert(SE->isKnownPositive(ConstCoeff) &&
"ConstCoeff should be positive");
1498 SplitIter = SE->getUDivExpr(
1499 SE->getSMaxExpr(SE->getZero(Delta->
getType()), Delta),
1500 SE->getMulExpr(SE->getConstant(Delta->
getType(), 2), ConstCoeff));
1511 if (SE->isKnownNegative(Delta)) {
1513 ++WeakCrossingSIVindependence;
1514 ++WeakCrossingSIVsuccesses;
1520 if (
const SCEV *UpperBound =
1521 collectUpperBound(CurSrcLoop, Delta->
getType())) {
1523 const SCEV *ConstantTwo = SE->getConstant(UpperBound->getType(), 2);
1525 SE->getMulExpr(SE->getMulExpr(ConstCoeff, UpperBound), ConstantTwo);
1529 ++WeakCrossingSIVindependence;
1530 ++WeakCrossingSIVsuccesses;
1535 Result.DV[
Level].Direction &= ~Dependence::DVEntry::LT;
1536 Result.DV[
Level].Direction &= ~Dependence::DVEntry::GT;
1537 ++WeakCrossingSIVsuccesses;
1538 if (!
Result.DV[Level].Direction) {
1539 ++WeakCrossingSIVindependence;
1549 APInt APDelta = ConstDelta->
getAPInt();
1550 APInt APCoeff = ConstCoeff->
getAPInt();
1551 APInt Distance = APDelta;
1552 APInt Remainder = APDelta;
1555 if (Remainder != 0) {
1557 ++WeakCrossingSIVindependence;
1558 ++WeakCrossingSIVsuccesses;
1564 APInt Two = APInt(Distance.
getBitWidth(), 2,
true);
1565 Remainder = Distance.
srem(Two);
1567 if (Remainder != 0) {
1569 Result.DV[
Level].Direction &= ~Dependence::DVEntry::EQ;
1570 ++WeakCrossingSIVsuccesses;
1587 APInt A0(Bits, 1,
true), A1(Bits, 0,
true);
1588 APInt B0(Bits, 0,
true), B1(Bits, 1,
true);
1596 APInt A2 = A0 - Q*A1; A0 = A1; A1 = A2;
1597 APInt B2 = B0 - Q*B1; B0 = B1; B1 = B2;
1604 X = AM.
slt(0) ? -A1 : A1;
1605 Y = BM.
slt(0) ? B1 : -B1;
1621 if ((
A.sgt(0) &&
B.sgt(0)) || (
A.slt(0) &&
B.slt(0)))
1633 if ((
A.sgt(0) &&
B.sgt(0)) || (
A.slt(0) &&
B.slt(0)))
1668static std::pair<std::optional<APInt>, std::optional<APInt>>
1670 const std::optional<APInt> &UB) {
1671 assert(
A != 0 &&
"A must be non-zero");
1672 std::optional<APInt> TL, TU;
1692 return std::make_pair(TL, TU);
1714bool DependenceInfo::exactSIVtest(
const SCEV *SrcCoeff,
const SCEV *DstCoeff,
1715 const SCEV *SrcConst,
const SCEV *DstConst,
1716 const Loop *CurSrcLoop,
1717 const Loop *CurDstLoop,
unsigned Level,
1718 FullDependence &Result,
1719 Constraint &NewConstraint)
const {
1721 LLVM_DEBUG(
dbgs() <<
"\t SrcCoeff = " << *SrcCoeff <<
" = AM\n");
1722 LLVM_DEBUG(
dbgs() <<
"\t DstCoeff = " << *DstCoeff <<
" = BM\n");
1725 ++ExactSIVapplications;
1726 assert(0 < Level && Level <= CommonLevels &&
"Level out of range");
1728 Result.Consistent =
false;
1733 NewConstraint.setLine(SrcCoeff, SE->getNegativeSCEV(DstCoeff), Delta,
1734 CurSrcLoop, CurDstLoop);
1738 if (!ConstDelta || !ConstSrcCoeff || !ConstDstCoeff)
1743 APInt AM = ConstSrcCoeff->
getAPInt();
1744 APInt BM = ConstDstCoeff->
getAPInt();
1749 ++ExactSIVindependence;
1750 ++ExactSIVsuccesses;
1757 std::optional<APInt> UM;
1759 if (
const SCEVConstant *CUB =
1760 collectConstantUpperBound(CurSrcLoop, Delta->
getType())) {
1761 UM = CUB->getAPInt();
1767 APInt TC = CM.
sdiv(
G);
1789 auto CreateVec = [](
const std::optional<APInt> &V0,
1790 const std::optional<APInt> &V1) {
1813 ++ExactSIVindependence;
1814 ++ExactSIVsuccesses;
1820 APInt LowerDistance, UpperDistance;
1823 LowerDistance = (TY - TX) + (TA - TB) * TL;
1824 UpperDistance = (TY - TX) + (TA - TB) * TU;
1826 LowerDistance = (TY - TX) + (TA - TB) * TU;
1827 UpperDistance = (TY - TX) + (TA - TB) * TL;
1830 LLVM_DEBUG(
dbgs() <<
"\t LowerDistance = " << LowerDistance <<
"\n");
1831 LLVM_DEBUG(
dbgs() <<
"\t UpperDistance = " << UpperDistance <<
"\n");
1833 APInt
Zero(Bits, 0,
true);
1834 if (LowerDistance.
sle(Zero) && UpperDistance.
sge(Zero)) {
1836 ++ExactSIVsuccesses;
1838 if (LowerDistance.
slt(0)) {
1840 ++ExactSIVsuccesses;
1842 if (UpperDistance.
sgt(0)) {
1844 ++ExactSIVsuccesses;
1850 ++ExactSIVindependence;
1861 return ConstDividend.
srem(ConstDivisor) == 0;
1895bool DependenceInfo::weakZeroSrcSIVtest(
1896 const SCEV *DstCoeff,
const SCEV *SrcConst,
const SCEV *DstConst,
1897 const Loop *CurSrcLoop,
const Loop *CurDstLoop,
unsigned Level,
1898 FullDependence &Result, Constraint &NewConstraint)
const {
1906 ++WeakZeroSIVapplications;
1907 assert(0 < Level && Level <= MaxLevels &&
"Level out of range");
1909 Result.Consistent =
false;
1910 const SCEV *Delta = SE->getMinusSCEV(SrcConst, DstConst);
1911 NewConstraint.setLine(SE->getZero(Delta->
getType()), DstCoeff, Delta,
1912 CurSrcLoop, CurDstLoop);
1915 if (Level < CommonLevels) {
1918 ++WeakZeroSIVsuccesses;
1925 const SCEV *AbsCoeff = SE->isKnownNegative(ConstCoeff)
1926 ? SE->getNegativeSCEV(ConstCoeff)
1928 const SCEV *NewDelta =
1929 SE->isKnownNegative(ConstCoeff) ? SE->getNegativeSCEV(Delta) : Delta;
1933 if (
const SCEV *UpperBound =
1934 collectUpperBound(CurSrcLoop, Delta->
getType())) {
1936 const SCEV *Product = SE->getMulExpr(AbsCoeff, UpperBound);
1938 ++WeakZeroSIVindependence;
1939 ++WeakZeroSIVsuccesses;
1944 if (Level < CommonLevels) {
1947 ++WeakZeroSIVsuccesses;
1955 if (SE->isKnownNegative(NewDelta)) {
1957 ++WeakZeroSIVindependence;
1958 ++WeakZeroSIVsuccesses;
1965 ++WeakZeroSIVindependence;
1966 ++WeakZeroSIVsuccesses;
2003bool DependenceInfo::weakZeroDstSIVtest(
2004 const SCEV *SrcCoeff,
const SCEV *SrcConst,
const SCEV *DstConst,
2005 const Loop *CurSrcLoop,
const Loop *CurDstLoop,
unsigned Level,
2006 FullDependence &Result, Constraint &NewConstraint)
const {
2013 ++WeakZeroSIVapplications;
2014 assert(0 < Level && Level <= SrcLevels &&
"Level out of range");
2016 Result.Consistent =
false;
2017 const SCEV *Delta = SE->getMinusSCEV(DstConst, SrcConst);
2018 NewConstraint.setLine(SrcCoeff, SE->getZero(Delta->
getType()), Delta,
2019 CurSrcLoop, CurDstLoop);
2022 if (Level < CommonLevels) {
2025 ++WeakZeroSIVsuccesses;
2032 const SCEV *AbsCoeff = SE->isKnownNegative(ConstCoeff)
2033 ? SE->getNegativeSCEV(ConstCoeff)
2035 const SCEV *NewDelta =
2036 SE->isKnownNegative(ConstCoeff) ? SE->getNegativeSCEV(Delta) : Delta;
2040 if (
const SCEV *UpperBound =
2041 collectUpperBound(CurSrcLoop, Delta->
getType())) {
2043 const SCEV *Product = SE->getMulExpr(AbsCoeff, UpperBound);
2045 ++WeakZeroSIVindependence;
2046 ++WeakZeroSIVsuccesses;
2051 if (Level < CommonLevels) {
2054 ++WeakZeroSIVsuccesses;
2062 if (SE->isKnownNegative(NewDelta)) {
2064 ++WeakZeroSIVindependence;
2065 ++WeakZeroSIVsuccesses;
2072 ++WeakZeroSIVindependence;
2073 ++WeakZeroSIVsuccesses;
2086bool DependenceInfo::exactRDIVtest(
const SCEV *SrcCoeff,
const SCEV *DstCoeff,
2087 const SCEV *SrcConst,
const SCEV *DstConst,
2088 const Loop *SrcLoop,
const Loop *DstLoop,
2089 FullDependence &Result)
const {
2093 LLVM_DEBUG(
dbgs() <<
"\t SrcCoeff = " << *SrcCoeff <<
" = AM\n");
2094 LLVM_DEBUG(
dbgs() <<
"\t DstCoeff = " << *DstCoeff <<
" = BM\n");
2097 ++ExactRDIVapplications;
2098 Result.Consistent =
false;
2099 const SCEV *Delta = SE->getMinusSCEV(DstConst, SrcConst);
2104 if (!ConstDelta || !ConstSrcCoeff || !ConstDstCoeff)
2109 APInt AM = ConstSrcCoeff->
getAPInt();
2110 APInt BM = ConstDstCoeff->
getAPInt();
2115 ++ExactRDIVindependence;
2122 std::optional<APInt> SrcUM;
2124 if (
const SCEVConstant *UpperBound =
2125 collectConstantUpperBound(SrcLoop, Delta->
getType())) {
2126 SrcUM = UpperBound->getAPInt();
2130 std::optional<APInt> DstUM;
2132 if (
const SCEVConstant *UpperBound =
2133 collectConstantUpperBound(DstLoop, Delta->
getType())) {
2134 DstUM = UpperBound->getAPInt();
2140 APInt TC = CM.
sdiv(
G);
2165 auto CreateVec = [](
const std::optional<APInt> &V0,
2166 const std::optional<APInt> &V1) {
2186 ++ExactRDIVindependence;
2232bool DependenceInfo::symbolicRDIVtest(
const SCEV *A1,
const SCEV *A2,
2233 const SCEV *C1,
const SCEV *C2,
2235 const Loop *Loop2)
const {
2238 ++SymbolicRDIVapplications;
2245 const SCEV *N1 = collectUpperBound(Loop1, A1->
getType());
2246 const SCEV *N2 = collectUpperBound(Loop2, A1->
getType());
2249 const SCEV *C2_C1 = SE->getMinusSCEV(C2, C1);
2250 const SCEV *C1_C2 = SE->getMinusSCEV(C1, C2);
2253 if (SE->isKnownNonNegative(A1)) {
2254 if (SE->isKnownNonNegative(A2)) {
2258 const SCEV *A1N1 = SE->getMulExpr(A1, N1);
2261 ++SymbolicRDIVindependence;
2267 const SCEV *A2N2 = SE->getMulExpr(A2, N2);
2270 ++SymbolicRDIVindependence;
2274 }
else if (SE->isKnownNonPositive(A2)) {
2278 const SCEV *A1N1 = SE->getMulExpr(A1, N1);
2279 const SCEV *A2N2 = SE->getMulExpr(A2, N2);
2280 const SCEV *A1N1_A2N2 = SE->getMinusSCEV(A1N1, A2N2);
2281 LLVM_DEBUG(
dbgs() <<
"\t A1*N1 - A2*N2 = " << *A1N1_A2N2 <<
"\n");
2283 ++SymbolicRDIVindependence;
2288 if (SE->isKnownNegative(C2_C1)) {
2289 ++SymbolicRDIVindependence;
2293 }
else if (SE->isKnownNonPositive(A1)) {
2294 if (SE->isKnownNonNegative(A2)) {
2298 const SCEV *A1N1 = SE->getMulExpr(A1, N1);
2299 const SCEV *A2N2 = SE->getMulExpr(A2, N2);
2300 const SCEV *A1N1_A2N2 = SE->getMinusSCEV(A1N1, A2N2);
2301 LLVM_DEBUG(
dbgs() <<
"\t A1*N1 - A2*N2 = " << *A1N1_A2N2 <<
"\n");
2303 ++SymbolicRDIVindependence;
2308 if (SE->isKnownPositive(C2_C1)) {
2309 ++SymbolicRDIVindependence;
2312 }
else if (SE->isKnownNonPositive(A2)) {
2316 const SCEV *A1N1 = SE->getMulExpr(A1, N1);
2319 ++SymbolicRDIVindependence;
2325 const SCEV *A2N2 = SE->getMulExpr(A2, N2);
2328 ++SymbolicRDIVindependence;
2345bool DependenceInfo::testSIV(
const SCEV *Src,
const SCEV *Dst,
unsigned &Level,
2346 FullDependence &Result, Constraint &NewConstraint,
2347 const SCEV *&SplitIter)
const {
2352 if (SrcAddRec && DstAddRec) {
2353 const SCEV *SrcConst = SrcAddRec->
getStart();
2354 const SCEV *DstConst = DstAddRec->
getStart();
2357 const Loop *CurSrcLoop = SrcAddRec->
getLoop();
2358 const Loop *CurDstLoop = DstAddRec->
getLoop();
2359 assert(haveSameSD(CurSrcLoop, CurDstLoop) &&
2360 "Loops in the SIV test should have the same iteration space and "
2362 Level = mapSrcLoop(CurSrcLoop);
2364 if (SrcCoeff == DstCoeff)
2365 disproven = strongSIVtest(SrcCoeff, SrcConst, DstConst, CurSrcLoop,
2366 CurDstLoop, Level, Result, NewConstraint);
2367 else if (SrcCoeff == SE->getNegativeSCEV(DstCoeff))
2368 disproven = weakCrossingSIVtest(SrcCoeff, SrcConst, DstConst, CurSrcLoop,
2369 CurDstLoop, Level, Result, NewConstraint,
2373 exactSIVtest(SrcCoeff, DstCoeff, SrcConst, DstConst, CurSrcLoop,
2374 CurDstLoop, Level, Result, NewConstraint);
2375 return disproven || gcdMIVtest(Src, Dst, Result) ||
2376 symbolicRDIVtest(SrcCoeff, DstCoeff, SrcConst, DstConst, CurSrcLoop,
2380 const SCEV *SrcConst = SrcAddRec->
getStart();
2382 const SCEV *DstConst = Dst;
2383 const Loop *CurSrcLoop = SrcAddRec->
getLoop();
2384 Level = mapSrcLoop(CurSrcLoop);
2385 return weakZeroDstSIVtest(SrcCoeff, SrcConst, DstConst, CurSrcLoop,
2386 CurSrcLoop, Level, Result, NewConstraint) ||
2387 gcdMIVtest(Src, Dst, Result);
2390 const SCEV *DstConst = DstAddRec->
getStart();
2392 const SCEV *SrcConst = Src;
2393 const Loop *CurDstLoop = DstAddRec->
getLoop();
2394 Level = mapDstLoop(CurDstLoop);
2395 return weakZeroSrcSIVtest(DstCoeff, SrcConst, DstConst, CurDstLoop,
2396 CurDstLoop, Level, Result, NewConstraint) ||
2397 gcdMIVtest(Src, Dst, Result);
2416bool DependenceInfo::testRDIV(
const SCEV *Src,
const SCEV *Dst,
2417 FullDependence &Result)
const {
2424 const SCEV *SrcConst, *DstConst;
2425 const SCEV *SrcCoeff, *DstCoeff;
2426 const Loop *SrcLoop, *DstLoop;
2432 if (SrcAddRec && DstAddRec) {
2435 SrcLoop = SrcAddRec->
getLoop();
2438 DstLoop = DstAddRec->
getLoop();
2439 }
else if (SrcAddRec) {
2440 if (
const SCEVAddRecExpr *tmpAddRec =
2442 SrcConst = tmpAddRec->getStart();
2443 SrcCoeff = tmpAddRec->getStepRecurrence(*SE);
2444 SrcLoop = tmpAddRec->getLoop();
2447 DstLoop = SrcAddRec->
getLoop();
2450 }
else if (DstAddRec) {
2451 if (
const SCEVAddRecExpr *tmpAddRec =
2453 DstConst = tmpAddRec->getStart();
2454 DstCoeff = tmpAddRec->getStepRecurrence(*SE);
2455 DstLoop = tmpAddRec->getLoop();
2458 SrcLoop = DstAddRec->
getLoop();
2463 return exactRDIVtest(SrcCoeff, DstCoeff, SrcConst, DstConst, SrcLoop, DstLoop,
2465 gcdMIVtest(Src, Dst, Result) ||
2466 symbolicRDIVtest(SrcCoeff, DstCoeff, SrcConst, DstConst, SrcLoop,
2473bool DependenceInfo::testMIV(
const SCEV *Src,
const SCEV *Dst,
2474 const SmallBitVector &
Loops,
2475 FullDependence &Result)
const {
2478 Result.Consistent =
false;
2479 return gcdMIVtest(Src, Dst, Result) ||
2480 banerjeeMIVtest(Src, Dst,
Loops, Result);
2491 return std::nullopt;
2494bool DependenceInfo::accumulateCoefficientsGCD(
const SCEV *Expr,
2495 const Loop *CurLoop,
2496 const SCEV *&CurLoopCoeff,
2497 APInt &RunningGCD)
const {
2500 if (RunningGCD == 1)
2505 assert(isLoopInvariant(Expr, CurLoop) &&
2506 "Expected loop invariant expression");
2513 if (AddRec->
getLoop() == CurLoop) {
2514 CurLoopCoeff = Step;
2528 return accumulateCoefficientsGCD(Start, CurLoop, CurLoopCoeff, RunningGCD);
2549bool DependenceInfo::gcdMIVtest(
const SCEV *Src,
const SCEV *Dst,
2550 FullDependence &Result)
const {
2555 unsigned BitWidth = SE->getTypeSizeInBits(Src->getType());
2562 const SCEV *Coefficients = Src;
2563 while (
const SCEVAddRecExpr *AddRec =
2574 const SCEV *SrcConst = Coefficients;
2581 while (
const SCEVAddRecExpr *AddRec =
2592 const SCEV *DstConst = Coefficients;
2595 const SCEV *Delta = SE->getMinusSCEV(DstConst, SrcConst);
2600 for (
const SCEV *Operand : Sum->
operands()) {
2602 assert(!Constant &&
"Surprised to find multiple constants");
2619 if (ConstDelta == 0)
2623 APInt Remainder = ConstDelta.
srem(RunningGCD);
2624 if (Remainder != 0) {
2643 bool Improved =
false;
2645 while (
const SCEVAddRecExpr *AddRec =
2648 const Loop *CurLoop = AddRec->
getLoop();
2649 RunningGCD = ExtraGCD;
2651 const SCEV *DstCoeff = SE->getMinusSCEV(SrcCoeff, SrcCoeff);
2653 if (!accumulateCoefficientsGCD(Src, CurLoop, SrcCoeff, RunningGCD) ||
2654 !accumulateCoefficientsGCD(Dst, CurLoop, DstCoeff, RunningGCD))
2657 Delta = SE->getMinusSCEV(SrcCoeff, DstCoeff);
2667 if (RunningGCD != 0) {
2668 Remainder = ConstDelta.
srem(RunningGCD);
2670 if (Remainder != 0) {
2671 unsigned Level = mapSrcLoop(CurLoop);
2672 Result.DV[
Level - 1].Direction &= ~Dependence::DVEntry::EQ;
2716bool DependenceInfo::banerjeeMIVtest(
const SCEV *Src,
const SCEV *Dst,
2717 const SmallBitVector &
Loops,
2718 FullDependence &Result)
const {
2722 ++BanerjeeApplications;
2725 CoefficientInfo *
A = collectCoeffInfo(Src,
true, A0);
2728 CoefficientInfo *
B = collectCoeffInfo(Dst,
false, B0);
2729 BoundInfo *Bound =
new BoundInfo[MaxLevels + 1];
2730 const SCEV *Delta = SE->getMinusSCEV(B0, A0);
2735 for (
unsigned K = 1;
K <= MaxLevels; ++
K) {
2736 Bound[
K].Iterations =
A[
K].Iterations ?
A[
K].Iterations :
B[
K].Iterations;
2739 findBoundsALL(
A,
B, Bound, K);
2754 bool Disproved =
false;
2757 unsigned DepthExpanded = 0;
2759 exploreDirections(1,
A,
B, Bound,
Loops, DepthExpanded, Delta);
2761 bool Improved =
false;
2762 for (
unsigned K = 1;
K <= CommonLevels; ++
K) {
2764 unsigned Old =
Result.DV[
K - 1].Direction;
2765 Result.DV[
K - 1].Direction = Old & Bound[
K].DirSet;
2766 Improved |= Old !=
Result.DV[
K - 1].Direction;
2767 if (!
Result.DV[K - 1].Direction) {
2775 ++BanerjeeSuccesses;
2777 ++BanerjeeIndependence;
2781 ++BanerjeeIndependence;
2795unsigned DependenceInfo::exploreDirections(
unsigned Level, CoefficientInfo *
A,
2796 CoefficientInfo *
B, BoundInfo *Bound,
2797 const SmallBitVector &
Loops,
2798 unsigned &DepthExpanded,
2799 const SCEV *Delta)
const {
2805 LLVM_DEBUG(
dbgs() <<
"Number of common levels exceeded the threshold. MIV "
2806 "direction exploration is terminated.\n");
2807 for (
unsigned K = 1;
K <= CommonLevels; ++
K)
2813 if (Level > CommonLevels) {
2816 for (
unsigned K = 1;
K <= CommonLevels; ++
K) {
2818 Bound[
K].DirSet |= Bound[
K].Direction;
2843 if (Level > DepthExpanded) {
2844 DepthExpanded =
Level;
2846 findBoundsLT(
A,
B, Bound, Level);
2847 findBoundsGT(
A,
B, Bound, Level);
2848 findBoundsEQ(
A,
B, Bound, Level);
2887 unsigned NewDeps = 0;
2891 NewDeps += exploreDirections(Level + 1,
A,
B, Bound,
Loops, DepthExpanded,
2896 NewDeps += exploreDirections(Level + 1,
A,
B, Bound,
Loops, DepthExpanded,
2901 NewDeps += exploreDirections(Level + 1,
A,
B, Bound,
Loops, DepthExpanded,
2907 return exploreDirections(Level + 1,
A,
B, Bound,
Loops, DepthExpanded,
2912bool DependenceInfo::testBounds(
unsigned char DirKind,
unsigned Level,
2913 BoundInfo *Bound,
const SCEV *Delta)
const {
2914 Bound[
Level].Direction = DirKind;
2915 if (
const SCEV *LowerBound = getLowerBound(Bound))
2918 if (
const SCEV *UpperBound = getUpperBound(Bound))
2939void DependenceInfo::findBoundsALL(CoefficientInfo *
A, CoefficientInfo *
B,
2940 BoundInfo *Bound,
unsigned K)
const {
2945 if (Bound[K].Iterations) {
2947 SE->getMinusSCEV(
A[K].NegPart,
B[K].PosPart), Bound[K].Iterations);
2949 SE->getMinusSCEV(
A[K].PosPart,
B[K].NegPart), Bound[K].Iterations);
2954 SE->getZero(
A[K].Coeff->
getType());
2957 SE->getZero(
A[K].Coeff->
getType());
2976void DependenceInfo::findBoundsEQ(CoefficientInfo *
A, CoefficientInfo *
B,
2977 BoundInfo *Bound,
unsigned K)
const {
2982 if (Bound[K].Iterations) {
2983 const SCEV *Delta = SE->getMinusSCEV(
A[K].Coeff,
B[K].Coeff);
2984 const SCEV *NegativePart = getNegativePart(Delta);
2986 SE->getMulExpr(NegativePart, Bound[K].Iterations);
2987 const SCEV *PositivePart = getPositivePart(Delta);
2989 SE->getMulExpr(PositivePart, Bound[K].Iterations);
2993 const SCEV *Delta = SE->getMinusSCEV(
A[K].Coeff,
B[K].Coeff);
2994 const SCEV *NegativePart = getNegativePart(Delta);
2995 if (NegativePart->
isZero())
2997 const SCEV *PositivePart = getPositivePart(Delta);
2998 if (PositivePart->
isZero())
3016void DependenceInfo::findBoundsLT(CoefficientInfo *
A, CoefficientInfo *
B,
3017 BoundInfo *Bound,
unsigned K)
const {
3022 if (Bound[K].Iterations) {
3023 const SCEV *Iter_1 = SE->getMinusSCEV(
3024 Bound[K].Iterations, SE->getOne(Bound[K].Iterations->getType()));
3025 const SCEV *NegPart =
3026 getNegativePart(SE->getMinusSCEV(
A[K].NegPart,
B[K].Coeff));
3028 SE->getMinusSCEV(SE->getMulExpr(NegPart, Iter_1),
B[K].Coeff);
3029 const SCEV *PosPart =
3030 getPositivePart(SE->getMinusSCEV(
A[K].PosPart,
B[K].Coeff));
3032 SE->getMinusSCEV(SE->getMulExpr(PosPart, Iter_1),
B[K].Coeff);
3036 const SCEV *NegPart =
3037 getNegativePart(SE->getMinusSCEV(
A[K].NegPart,
B[K].Coeff));
3040 const SCEV *PosPart =
3041 getPositivePart(SE->getMinusSCEV(
A[K].PosPart,
B[K].Coeff));
3060void DependenceInfo::findBoundsGT(CoefficientInfo *
A, CoefficientInfo *
B,
3061 BoundInfo *Bound,
unsigned K)
const {
3066 if (Bound[K].Iterations) {
3067 const SCEV *Iter_1 = SE->getMinusSCEV(
3068 Bound[K].Iterations, SE->getOne(Bound[K].Iterations->getType()));
3069 const SCEV *NegPart =
3070 getNegativePart(SE->getMinusSCEV(
A[K].Coeff,
B[K].PosPart));
3072 SE->getAddExpr(SE->getMulExpr(NegPart, Iter_1),
A[K].Coeff);
3073 const SCEV *PosPart =
3074 getPositivePart(SE->getMinusSCEV(
A[K].Coeff,
B[K].NegPart));
3076 SE->getAddExpr(SE->getMulExpr(PosPart, Iter_1),
A[K].Coeff);
3080 const SCEV *NegPart =
3081 getNegativePart(SE->getMinusSCEV(
A[K].Coeff,
B[K].PosPart));
3084 const SCEV *PosPart =
3085 getPositivePart(SE->getMinusSCEV(
A[K].Coeff,
B[K].NegPart));
3092const SCEV *DependenceInfo::getPositivePart(
const SCEV *
X)
const {
3093 return SE->getSMaxExpr(
X, SE->getZero(
X->getType()));
3097const SCEV *DependenceInfo::getNegativePart(
const SCEV *
X)
const {
3098 return SE->getSMinExpr(
X, SE->getZero(
X->getType()));
3104DependenceInfo::CoefficientInfo *
3105DependenceInfo::collectCoeffInfo(
const SCEV *Subscript,
bool SrcFlag,
3106 const SCEV *&Constant)
const {
3107 const SCEV *
Zero = SE->getZero(Subscript->getType());
3108 CoefficientInfo *CI =
new CoefficientInfo[MaxLevels + 1];
3109 for (
unsigned K = 1;
K <= MaxLevels; ++
K) {
3111 CI[
K].PosPart =
Zero;
3112 CI[
K].NegPart =
Zero;
3113 CI[
K].Iterations =
nullptr;
3117 unsigned K = SrcFlag ? mapSrcLoop(L) : mapDstLoop(
L);
3119 CI[
K].PosPart = getPositivePart(CI[K].Coeff);
3120 CI[
K].NegPart = getNegativePart(CI[K].Coeff);
3121 CI[
K].Iterations = collectUpperBound(L, Subscript->getType());
3127 for (
unsigned K = 1;
K <= MaxLevels; ++
K) {
3134 if (CI[K].Iterations)
3149const SCEV *DependenceInfo::getLowerBound(BoundInfo *Bound)
const {
3150 const SCEV *Sum = Bound[1].Lower[Bound[1].Direction];
3151 for (
unsigned K = 2; Sum &&
K <= MaxLevels; ++
K) {
3164const SCEV *DependenceInfo::getUpperBound(BoundInfo *Bound)
const {
3165 const SCEV *Sum = Bound[1].Upper[Bound[1].Direction];
3166 for (
unsigned K = 2; Sum &&
K <= MaxLevels; ++
K) {
3184const SCEV *DependenceInfo::findCoefficient(
const SCEV *Expr,
3185 const Loop *TargetLoop)
const {
3188 return SE->getZero(Expr->
getType());
3189 if (AddRec->
getLoop() == TargetLoop)
3191 return findCoefficient(AddRec->
getStart(), TargetLoop);
3199const SCEV *DependenceInfo::zeroCoefficient(
const SCEV *Expr,
3200 const Loop *TargetLoop)
const {
3204 if (AddRec->
getLoop() == TargetLoop)
3206 return SE->getAddRecExpr(zeroCoefficient(AddRec->
getStart(), TargetLoop),
3216const SCEV *DependenceInfo::addToCoefficient(
const SCEV *Expr,
3217 const Loop *TargetLoop,
3218 const SCEV *
Value)
const {
3221 return SE->getAddRecExpr(Expr,
Value, TargetLoop,
3223 if (AddRec->
getLoop() == TargetLoop) {
3230 if (SE->isLoopInvariant(AddRec, TargetLoop))
3232 return SE->getAddRecExpr(
3248bool DependenceInfo::propagate(
const SCEV *&Src,
const SCEV *&Dst,
3249 SmallBitVector &
Loops,
3250 SmallVectorImpl<Constraint> &Constraints,
3253 for (
unsigned LI :
Loops.set_bits()) {
3256 if (Constraints[LI].isDistance())
3257 Result |= propagateDistance(Src, Dst, Constraints[LI], Consistent);
3258 else if (Constraints[LI].isLine())
3259 Result |= propagateLine(Src, Dst, Constraints[LI], Consistent);
3260 else if (Constraints[LI].isPoint())
3261 Result |= propagatePoint(Src, Dst, Constraints[LI]);
3271bool DependenceInfo::propagateDistance(
const SCEV *&Src,
const SCEV *&Dst,
3272 Constraint &CurConstraint,
3274 const Loop *CurSrcLoop = CurConstraint.getAssociatedSrcLoop();
3275 const Loop *CurDstLoop = CurConstraint.getAssociatedDstLoop();
3277 const SCEV *A_K = findCoefficient(Src, CurSrcLoop);
3280 const SCEV *DA_K = SE->getMulExpr(A_K, CurConstraint.getD());
3281 Src = SE->getMinusSCEV(Src, DA_K);
3282 Src = zeroCoefficient(Src, CurSrcLoop);
3285 Dst = addToCoefficient(Dst, CurDstLoop, SE->getNegativeSCEV(A_K));
3287 if (!findCoefficient(Dst, CurDstLoop)->
isZero())
3297bool DependenceInfo::propagateLine(
const SCEV *&Src,
const SCEV *&Dst,
3298 Constraint &CurConstraint,
3300 const Loop *CurSrcLoop = CurConstraint.getAssociatedSrcLoop();
3301 const Loop *CurDstLoop = CurConstraint.getAssociatedDstLoop();
3302 const SCEV *
A = CurConstraint.getA();
3303 const SCEV *
B = CurConstraint.getB();
3304 const SCEV *
C = CurConstraint.getC();
3312 if (!Bconst || !Cconst)
3315 APInt Charlie = Cconst->
getAPInt();
3316 APInt CdivB = Charlie.
sdiv(Beta);
3317 assert(Charlie.
srem(Beta) == 0 &&
"C should be evenly divisible by B");
3318 const SCEV *AP_K = findCoefficient(Dst, CurDstLoop);
3319 Src = SE->getMinusSCEV(Src, SE->getMulExpr(AP_K, SE->getConstant(CdivB)));
3320 Dst = zeroCoefficient(Dst, CurDstLoop);
3321 if (!findCoefficient(Src, CurSrcLoop)->
isZero())
3323 }
else if (
B->isZero()) {
3326 if (!Aconst || !Cconst)
3329 APInt Charlie = Cconst->
getAPInt();
3330 APInt CdivA = Charlie.
sdiv(Alpha);
3331 assert(Charlie.
srem(Alpha) == 0 &&
"C should be evenly divisible by A");
3332 const SCEV *A_K = findCoefficient(Src, CurSrcLoop);
3333 Src = SE->getAddExpr(Src, SE->getMulExpr(A_K, SE->getConstant(CdivA)));
3334 Src = zeroCoefficient(Src, CurSrcLoop);
3335 if (!findCoefficient(Dst, CurDstLoop)->
isZero())
3340 if (!Aconst || !Cconst)
3343 APInt Charlie = Cconst->
getAPInt();
3344 APInt CdivA = Charlie.
sdiv(Alpha);
3345 assert(Charlie.
srem(Alpha) == 0 &&
"C should be evenly divisible by A");
3346 const SCEV *A_K = findCoefficient(Src, CurSrcLoop);
3347 Src = SE->getAddExpr(Src, SE->getMulExpr(A_K, SE->getConstant(CdivA)));
3348 Src = zeroCoefficient(Src, CurSrcLoop);
3349 Dst = addToCoefficient(Dst, CurDstLoop, A_K);
3350 if (!findCoefficient(Dst, CurDstLoop)->
isZero())
3354 const SCEV *A_K = findCoefficient(Src, CurSrcLoop);
3355 Src = SE->getMulExpr(Src,
A);
3356 Dst = SE->getMulExpr(Dst,
A);
3357 Src = SE->getAddExpr(Src, SE->getMulExpr(A_K,
C));
3358 Src = zeroCoefficient(Src, CurSrcLoop);
3359 Dst = addToCoefficient(Dst, CurDstLoop, SE->getMulExpr(A_K,
B));
3360 if (!findCoefficient(Dst, CurDstLoop)->
isZero())
3371bool DependenceInfo::propagatePoint(
const SCEV *&Src,
const SCEV *&Dst,
3372 Constraint &CurConstraint) {
3373 const Loop *CurSrcLoop = CurConstraint.getAssociatedSrcLoop();
3374 const Loop *CurDstLoop = CurConstraint.getAssociatedDstLoop();
3375 const SCEV *A_K = findCoefficient(Src, CurSrcLoop);
3376 const SCEV *AP_K = findCoefficient(Dst, CurDstLoop);
3377 const SCEV *XA_K = SE->getMulExpr(A_K, CurConstraint.getX());
3378 const SCEV *YAP_K = SE->getMulExpr(AP_K, CurConstraint.getY());
3380 Src = SE->getAddExpr(Src, SE->getMinusSCEV(XA_K, YAP_K));
3381 Src = zeroCoefficient(Src, CurSrcLoop);
3384 Dst = zeroCoefficient(Dst, CurDstLoop);
3390void DependenceInfo::updateDirection(Dependence::DVEntry &Level,
3391 const Constraint &CurConstraint)
const {
3394 if (CurConstraint.isAny())
3396 else if (CurConstraint.isDistance()) {
3398 Level.Scalar =
false;
3399 Level.Distance = CurConstraint.getD();
3401 if (!SE->isKnownNonZero(
Level.Distance))
3403 if (!SE->isKnownNonPositive(
Level.Distance))
3405 if (!SE->isKnownNonNegative(
Level.Distance))
3407 Level.Direction &= NewDirection;
3408 }
else if (CurConstraint.isLine()) {
3409 Level.Scalar =
false;
3410 Level.Distance =
nullptr;
3412 }
else if (CurConstraint.isPoint()) {
3413 Level.Scalar =
false;
3414 Level.Distance =
nullptr;
3417 CurConstraint.getX()))
3421 CurConstraint.getX()))
3425 CurConstraint.getX()))
3428 Level.Direction &= NewDirection;
3437bool DependenceInfo::tryDelinearize(Instruction *Src, Instruction *Dst,
3438 SmallVectorImpl<Subscript> &Pair) {
3443 Loop *SrcLoop = LI->getLoopFor(Src->getParent());
3444 Loop *DstLoop = LI->getLoopFor(Dst->getParent());
3445 const SCEV *SrcAccessFn = SE->getSCEVAtScope(SrcPtr, SrcLoop);
3446 const SCEV *DstAccessFn = SE->getSCEVAtScope(DstPtr, DstLoop);
3447 const SCEVUnknown *SrcBase =
3449 const SCEVUnknown *DstBase =
3452 if (!SrcBase || !DstBase || SrcBase != DstBase)
3457 if (!tryDelinearizeFixedSize(Src, Dst, SrcAccessFn, DstAccessFn,
3458 SrcSubscripts, DstSubscripts) &&
3459 !tryDelinearizeParametricSize(Src, Dst, SrcAccessFn, DstAccessFn,
3460 SrcSubscripts, DstSubscripts))
3463 assert(isLoopInvariant(SrcBase, SrcLoop) &&
3464 isLoopInvariant(DstBase, DstLoop) &&
3465 "Expected SrcBase and DstBase to be loop invariant");
3469 dbgs() <<
"\nSrcSubscripts: ";
3470 for (
int I = 0;
I <
Size;
I++)
3471 dbgs() << *SrcSubscripts[
I];
3472 dbgs() <<
"\nDstSubscripts: ";
3473 for (
int I = 0;
I <
Size;
I++)
3474 dbgs() << *DstSubscripts[
I];
3482 for (
int I = 0;
I <
Size; ++
I) {
3483 Pair[
I].Src = SrcSubscripts[
I];
3484 Pair[
I].Dst = DstSubscripts[
I];
3485 unifySubscriptType(&Pair[
I]);
3494bool DependenceInfo::tryDelinearizeFixedSize(
3495 Instruction *Src, Instruction *Dst,
const SCEV *SrcAccessFn,
3496 const SCEV *DstAccessFn, SmallVectorImpl<const SCEV *> &SrcSubscripts,
3497 SmallVectorImpl<const SCEV *> &DstSubscripts) {
3499 const SCEVUnknown *SrcBase =
3501 const SCEVUnknown *DstBase =
3503 assert(SrcBase && DstBase && SrcBase == DstBase &&
3504 "expected src and dst scev unknowns to be equal");
3507 SmallVector<int, 4> SrcSizes;
3508 SmallVector<int, 4> DstSizes;
3517 if (SrcSizes.size() != DstSizes.
size() ||
3518 !std::equal(SrcSizes.begin(), SrcSizes.end(), DstSizes.
begin())) {
3519 SrcSubscripts.
clear();
3520 DstSubscripts.
clear();
3525 "Expected equal number of entries in the list of SrcSubscripts and "
3538 auto AllIndicesInRange = [&](SmallVector<int, 4> &DimensionSizes,
3539 SmallVectorImpl<const SCEV *> &Subscripts,
3541 size_t SSize = Subscripts.
size();
3542 for (
size_t I = 1;
I < SSize; ++
I) {
3543 const SCEV *S = Subscripts[
I];
3544 if (!isKnownNonNegative(S,
Ptr)) {
3546 dbgs() <<
"Check failed: !isKnownNonNegative(S, Ptr)\n";
3547 dbgs() <<
" S: " << *S <<
"\n" <<
" Ptr: " << *
Ptr <<
"\n";
3552 const SCEV *
Range = SE->getConstant(
3553 ConstantInt::get(SType, DimensionSizes[
I - 1],
false));
3554 if (!isKnownLessThan(S,
Range)) {
3556 dbgs() <<
"Check failed: !isKnownLessThan(S, Range)\n";
3557 dbgs() <<
" S: " << *S <<
"\n"
3558 <<
" Range: " << *
Range <<
"\n";
3567 if (!AllIndicesInRange(SrcSizes, SrcSubscripts, SrcPtr) ||
3568 !AllIndicesInRange(DstSizes, DstSubscripts, DstPtr)) {
3570 SrcSubscripts.
clear();
3571 DstSubscripts.
clear();
3576 dbgs() <<
"Delinearized subscripts of fixed-size array\n"
3577 <<
"SrcGEP:" << *SrcPtr <<
"\n"
3578 <<
"DstGEP:" << *DstPtr <<
"\n";
3583bool DependenceInfo::tryDelinearizeParametricSize(
3584 Instruction *Src, Instruction *Dst,
const SCEV *SrcAccessFn,
3585 const SCEV *DstAccessFn, SmallVectorImpl<const SCEV *> &SrcSubscripts,
3586 SmallVectorImpl<const SCEV *> &DstSubscripts) {
3590 const SCEVUnknown *SrcBase =
3592 const SCEVUnknown *DstBase =
3594 assert(SrcBase && DstBase && SrcBase == DstBase &&
3595 "expected src and dst scev unknowns to be equal");
3597 const SCEV *ElementSize = SE->getElementSize(Src);
3598 if (ElementSize != SE->getElementSize(Dst))
3601 const SCEV *SrcSCEV = SE->getMinusSCEV(SrcAccessFn, SrcBase);
3602 const SCEV *DstSCEV = SE->getMinusSCEV(DstAccessFn, DstBase);
3623 if (SrcSubscripts.
size() < 2 || DstSubscripts.
size() < 2 ||
3624 SrcSubscripts.
size() != DstSubscripts.
size())
3627 size_t Size = SrcSubscripts.
size();
3636 for (
size_t I = 1;
I <
Size; ++
I) {
3637 bool SNN = isKnownNonNegative(SrcSubscripts[
I], SrcPtr);
3638 bool DNN = isKnownNonNegative(DstSubscripts[
I], DstPtr);
3639 bool SLT = isKnownLessThan(SrcSubscripts[
I], Sizes[
I - 1]);
3640 bool DLT = isKnownLessThan(DstSubscripts[
I], Sizes[
I - 1]);
3641 if (SNN && DNN && SLT && DLT)
3645 dbgs() <<
"Delinearization checks failed: can't prove the following\n";
3647 dbgs() <<
" isKnownNonNegative(" << *SrcSubscripts[
I] <<
")\n";
3649 dbgs() <<
" isKnownNonNegative(" << *DstSubscripts[
I] <<
")\n";
3651 dbgs() <<
" isKnownLessThan(" << *SrcSubscripts[
I] <<
", "
3652 << *
Sizes[
I - 1] <<
")\n";
3654 dbgs() <<
" isKnownLessThan(" << *DstSubscripts[
I] <<
", "
3655 << *
Sizes[
I - 1] <<
")\n";
3669 for (
unsigned VI : BV.
set_bits()) {
3679 FunctionAnalysisManager::Invalidator &Inv) {
3686 return Inv.invalidate<
AAManager>(F, PA) ||
3706std::unique_ptr<Dependence>
3708 bool UnderRuntimeAssumptions) {
3710 bool PossiblyLoopIndependent =
true;
3712 PossiblyLoopIndependent =
false;
3714 if (!(Src->mayReadOrWriteMemory() && Dst->mayReadOrWriteMemory()))
3720 LLVM_DEBUG(
dbgs() <<
"can only handle simple loads and stores\n");
3721 return std::make_unique<Dependence>(Src, Dst,
3733 return std::make_unique<Dependence>(Src, Dst,
3747 LLVM_DEBUG(
dbgs() <<
"can't analyze must alias with different sizes\n");
3748 return std::make_unique<Dependence>(Src, Dst,
3754 const SCEV *SrcSCEV = SE->getSCEV(SrcPtr);
3755 const SCEV *DstSCEV = SE->getSCEV(DstPtr);
3758 const SCEV *SrcBase = SE->getPointerBase(SrcSCEV);
3759 const SCEV *DstBase = SE->getPointerBase(DstSCEV);
3760 if (SrcBase != DstBase) {
3767 LLVM_DEBUG(
dbgs() <<
"can't analyze SCEV with different pointer base\n");
3768 return std::make_unique<Dependence>(Src, Dst,
3776 Loop *SrcLoop = LI->getLoopFor(Src->getParent());
3777 Loop *DstLoop = LI->getLoopFor(Dst->getParent());
3778 if (!isLoopInvariant(SrcBase, SrcLoop) ||
3779 !isLoopInvariant(DstBase, DstLoop)) {
3780 LLVM_DEBUG(
dbgs() <<
"The base pointer is not loop invariant.\n");
3781 return std::make_unique<Dependence>(Src, Dst,
3786 const SCEV *SrcEv = SE->getMinusSCEV(SrcSCEV, SrcBase);
3787 const SCEV *DstEv = SE->getMinusSCEV(DstSCEV, DstBase);
3790 if (!SE->isKnownMultipleOf(SrcEv, EltSize, Assume) ||
3791 !SE->isKnownMultipleOf(DstEv, EltSize, Assume)) {
3792 LLVM_DEBUG(
dbgs() <<
"can't analyze SCEV with different offsets\n");
3793 return std::make_unique<Dependence>(Src, Dst,
3797 if (!Assume.empty()) {
3798 if (!UnderRuntimeAssumptions)
3799 return std::make_unique<Dependence>(Src, Dst,
3802 unsigned N = Assumptions.size();
3804 bool Implied =
false;
3805 for (
unsigned I = 0;
I !=
N && !Implied;
I++)
3806 if (Assumptions[
I]->implies(
P, *SE))
3809 Assumptions.push_back(
P);
3815 Pair[0].Src = SrcEv;
3816 Pair[0].Dst = DstEv;
3819 if (tryDelinearize(Src, Dst, Pair)) {
3821 Pairs = Pair.
size();
3826 establishNestingLevels(Src, Dst);
3828 LLVM_DEBUG(
dbgs() <<
" common nesting levels = " << CommonLevels <<
"\n");
3829 LLVM_DEBUG(
dbgs() <<
" maximum nesting levels = " << MaxLevels <<
"\n");
3830 LLVM_DEBUG(
dbgs() <<
" SameSD nesting levels = " << SameSDLevels <<
"\n");
3833 CommonLevels += SameSDLevels;
3834 MaxLevels -= SameSDLevels;
3835 if (SameSDLevels > 0) {
3838 for (
unsigned P = 0;
P < Pairs; ++
P) {
3840 Subscript::ClassificationKind TestClass =
3841 classifyPair(Pair[
P].Src, LI->getLoopFor(Src->getParent()),
3842 Pair[
P].Dst, LI->getLoopFor(Dst->getParent()),
Loops);
3844 if (TestClass != Subscript::ZIV && TestClass != Subscript::SIV &&
3845 TestClass != Subscript::RDIV) {
3847 CommonLevels -= SameSDLevels;
3848 MaxLevels += SameSDLevels;
3855 if (SameSDLevels > 0)
3859 PossiblyLoopIndependent, CommonLevels);
3862 for (
unsigned P = 0;
P < Pairs; ++
P) {
3863 assert(Pair[
P].Src->getType()->isIntegerTy() &&
"Src must be an integer");
3864 assert(Pair[
P].Dst->getType()->isIntegerTy() &&
"Dst must be an integer");
3865 Pair[
P].Loops.
resize(MaxLevels + 1);
3866 Pair[
P].GroupLoops.
resize(MaxLevels + 1);
3868 removeMatchingExtensions(&Pair[
P]);
3869 Pair[
P].Classification =
3870 classifyPair(Pair[
P].Src, LI->getLoopFor(Src->getParent()), Pair[
P].Dst,
3871 LI->getLoopFor(Dst->getParent()), Pair[
P].Loops);
3872 Pair[
P].GroupLoops = Pair[
P].Loops;
3873 Pair[
P].Group.set(
P);
3942 for (
unsigned SI = 0;
SI < Pairs; ++
SI) {
3943 if (Pair[
SI].Classification == Subscript::NonLinear) {
3945 ++NonlinearSubscriptPairs;
3946 collectCommonLoops(Pair[
SI].Src, LI->getLoopFor(Src->getParent()),
3948 collectCommonLoops(Pair[
SI].Dst, LI->getLoopFor(Dst->getParent()),
3950 Result.Consistent =
false;
3951 }
else if (Pair[
SI].Classification == Subscript::ZIV) {
3957 for (
unsigned SJ =
SI + 1; SJ < Pairs; ++SJ) {
3959 Intersection &= Pair[SJ].GroupLoops;
3960 if (Intersection.
any()) {
3962 Pair[SJ].GroupLoops |= Pair[
SI].GroupLoops;
3964 Pair[SJ].Group |= Pair[
SI].Group;
3969 if (Pair[
SI].Group.count() == 1) {
3971 ++SeparableSubscriptPairs;
3974 ++CoupledSubscriptPairs;
3985 Constraint NewConstraint;
3986 NewConstraint.setAny(SE);
3991 switch (Pair[
SI].Classification) {
3992 case Subscript::ZIV:
3994 if (testZIV(Pair[
SI].Src, Pair[
SI].Dst, Result))
3997 case Subscript::SIV: {
4000 const SCEV *SplitIter =
nullptr;
4001 if (testSIV(Pair[
SI].Src, Pair[
SI].Dst, Level, Result, NewConstraint,
4006 case Subscript::RDIV:
4008 if (testRDIV(Pair[
SI].Src, Pair[
SI].Dst, Result))
4011 case Subscript::MIV:
4013 if (testMIV(Pair[
SI].Src, Pair[
SI].Dst, Pair[
SI].
Loops, Result))
4021 if (Coupled.
count()) {
4024 LLVM_DEBUG(
dbgs() <<
"MaxLevels + 1 = " << MaxLevels + 1 <<
"\n");
4026 for (
unsigned II = 0;
II <= MaxLevels; ++
II)
4027 Constraints[
II].setAny(SE);
4035 for (
unsigned SJ : Group.set_bits()) {
4037 if (Pair[SJ].Classification == Subscript::SIV)
4043 unifySubscriptType(PairsInGroup);
4045 while (Sivs.
any()) {
4047 for (
unsigned SJ : Sivs.
set_bits()) {
4051 const SCEV *SplitIter =
nullptr;
4053 if (testSIV(Pair[SJ].Src, Pair[SJ].Dst, Level, Result, NewConstraint,
4056 ConstrainedLevels.
set(Level);
4057 if (intersectConstraints(&Constraints[Level], &NewConstraint)) {
4058 if (Constraints[Level].isEmpty()) {
4059 ++DeltaIndependence;
4071 for (
unsigned SJ : Mivs.
set_bits()) {
4074 if (propagate(Pair[SJ].Src, Pair[SJ].Dst, Pair[SJ].
Loops,
4075 Constraints, Result.Consistent)) {
4077 ++DeltaPropagations;
4078 Pair[SJ].Classification = classifyPair(
4079 Pair[SJ].Src, LI->getLoopFor(Src->getParent()), Pair[SJ].Dst,
4080 LI->getLoopFor(Dst->getParent()), Pair[SJ].Loops);
4081 switch (Pair[SJ].Classification) {
4082 case Subscript::ZIV:
4084 if (testZIV(Pair[SJ].Src, Pair[SJ].Dst, Result))
4088 case Subscript::SIV:
4092 case Subscript::RDIV:
4093 case Subscript::MIV:
4104 for (
unsigned SJ : Mivs.
set_bits()) {
4105 if (Pair[SJ].Classification == Subscript::RDIV) {
4107 if (testRDIV(Pair[SJ].Src, Pair[SJ].Dst, Result))
4117 for (
unsigned SJ : Mivs.
set_bits()) {
4118 if (Pair[SJ].Classification == Subscript::MIV) {
4120 if (testMIV(Pair[SJ].Src, Pair[SJ].Dst, Pair[SJ].
Loops, Result))
4128 for (
unsigned SJ : ConstrainedLevels.
set_bits()) {
4129 if (SJ > CommonLevels)
4131 updateDirection(Result.DV[SJ - 1], Constraints[SJ]);
4140 for (
unsigned SI = 0;
SI < Pairs; ++
SI)
4141 CompleteLoops |= Pair[
SI].
Loops;
4142 for (
unsigned II = 1;
II <= CommonLevels; ++
II)
4143 if (CompleteLoops[
II])
4144 Result.DV[
II - 1].Scalar =
false;
4149 for (
unsigned II = 1;
II <= Result.getLevels(); ++
II) {
4151 if (Result.DV[
II - 1].Distance ==
nullptr)
4152 Result.DV[
II - 1].Distance = SE->getZero(SrcSCEV->
getType());
4154 assert(Result.DV[
II - 1].Distance->isZero() &&
4155 "Inconsistency between distance and direction");
4161 const SCEV *Distance = Result.getDistance(
II);
4162 if (Distance && Distance->
isZero())
4164 "Distance is zero, but direction is not EQ");
4168 if (SameSDLevels > 0) {
4171 assert(CommonLevels >= SameSDLevels);
4172 CommonLevels -= SameSDLevels;
4173 MaxLevels += SameSDLevels;
4174 std::unique_ptr<FullDependence::DVEntry[]> DV, DVSameSD;
4175 DV = std::make_unique<FullDependence::DVEntry[]>(CommonLevels);
4176 DVSameSD = std::make_unique<FullDependence::DVEntry[]>(SameSDLevels);
4177 for (
unsigned Level = 0; Level < CommonLevels; ++Level)
4178 DV[Level] = Result.DV[Level];
4179 for (
unsigned Level = 0; Level < SameSDLevels; ++Level)
4180 DVSameSD[Level] = Result.DV[CommonLevels + Level];
4181 Result.DV = std::move(DV);
4182 Result.DVSameSD = std::move(DVSameSD);
4183 Result.Levels = CommonLevels;
4184 Result.SameSDLevels = SameSDLevels;
4186 Result.Consistent =
false;
4189 if (PossiblyLoopIndependent) {
4193 for (
unsigned II = 1;
II <= CommonLevels; ++
II) {
4195 Result.LoopIndependent =
false;
4202 bool AllEqual =
true;
4203 for (
unsigned II = 1;
II <= CommonLevels; ++
II) {
4213 return std::make_unique<FullDependence>(std::move(Result));
4264 unsigned SplitLevel) {
4266 "Dep should be splitable at SplitLevel");
4269 assert(Src->mayReadFromMemory() || Src->mayWriteToMemory());
4270 assert(Dst->mayReadFromMemory() || Dst->mayWriteToMemory());
4280 establishNestingLevels(Src, Dst);
4282 FullDependence Result(Src, Dst, Dep.Assumptions,
false, CommonLevels);
4286 const SCEV *SrcSCEV = SE->getSCEV(SrcPtr);
4287 const SCEV *DstSCEV = SE->getSCEV(DstPtr);
4288 Pair[0].Src = SE->removePointerBase(SrcSCEV);
4289 Pair[0].Dst = SE->removePointerBase(DstSCEV);
4292 if (tryDelinearize(Src, Dst, Pair)) {
4294 Pairs = Pair.
size();
4298 for (
unsigned P = 0;
P < Pairs; ++
P) {
4299 assert(Pair[
P].Src->getType()->isIntegerTy() &&
"Src must be an integer");
4300 assert(Pair[
P].Dst->getType()->isIntegerTy() &&
"Dst must be an integer");
4301 Pair[
P].Loops.
resize(MaxLevels + 1);
4302 Pair[
P].GroupLoops.
resize(MaxLevels + 1);
4304 removeMatchingExtensions(&Pair[
P]);
4305 Pair[
P].Classification =
4306 classifyPair(Pair[
P].Src, LI->getLoopFor(Src->getParent()), Pair[
P].Dst,
4307 LI->getLoopFor(Dst->getParent()), Pair[
P].Loops);
4308 Pair[
P].GroupLoops = Pair[
P].Loops;
4309 Pair[
P].Group.set(
P);
4316 for (
unsigned SI = 0;
SI < Pairs; ++
SI) {
4317 if (Pair[
SI].Classification == Subscript::NonLinear) {
4319 collectCommonLoops(Pair[
SI].Src, LI->getLoopFor(Src->getParent()),
4321 collectCommonLoops(Pair[
SI].Dst, LI->getLoopFor(Dst->getParent()),
4323 Result.Consistent =
false;
4324 }
else if (Pair[
SI].Classification == Subscript::ZIV)
4329 for (
unsigned SJ =
SI + 1; SJ < Pairs; ++SJ) {
4331 Intersection &= Pair[SJ].GroupLoops;
4332 if (Intersection.
any()) {
4334 Pair[SJ].GroupLoops |= Pair[
SI].GroupLoops;
4336 Pair[SJ].Group |= Pair[
SI].Group;
4341 if (Pair[
SI].Group.count() == 1)
4349 Constraint NewConstraint;
4350 NewConstraint.setAny(SE);
4354 switch (Pair[
SI].Classification) {
4355 case Subscript::SIV: {
4357 const SCEV *SplitIter =
nullptr;
4358 (void)testSIV(Pair[
SI].Src, Pair[
SI].Dst, Level, Result, NewConstraint,
4360 if (Level == SplitLevel) {
4361 assert(SplitIter !=
nullptr);
4366 case Subscript::ZIV:
4367 case Subscript::RDIV:
4368 case Subscript::MIV:
4375 assert(!Coupled.
empty() &&
"coupled expected non-empty");
4379 for (
unsigned II = 0;
II <= MaxLevels; ++
II)
4380 Constraints[
II].setAny(SE);
4386 for (
unsigned SJ : Group.set_bits()) {
4387 if (Pair[SJ].Classification == Subscript::SIV)
4392 while (Sivs.
any()) {
4394 for (
unsigned SJ : Sivs.
set_bits()) {
4397 const SCEV *SplitIter =
nullptr;
4398 (void)testSIV(Pair[SJ].Src, Pair[SJ].Dst, Level, Result, NewConstraint,
4400 if (Level == SplitLevel && SplitIter)
4402 ConstrainedLevels.
set(Level);
4403 if (intersectConstraints(&Constraints[Level], &NewConstraint))
4410 for (
unsigned SJ : Mivs.
set_bits()) {
4412 if (!propagate(Pair[SJ].Src, Pair[SJ].Dst, Pair[SJ].
Loops, Constraints,
4415 Pair[SJ].Classification = classifyPair(
4416 Pair[SJ].Src, LI->getLoopFor(Src->getParent()), Pair[SJ].Dst,
4417 LI->getLoopFor(Dst->getParent()), Pair[SJ].Loops);
4418 switch (Pair[SJ].Classification) {
4419 case Subscript::ZIV:
4422 case Subscript::SIV:
4426 case Subscript::RDIV:
4427 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...