72 #define DEBUG_TYPE "da"
77 STATISTIC(TotalArrayPairs,
"Array pairs tested");
78 STATISTIC(SeparableSubscriptPairs,
"Separable subscript pairs");
79 STATISTIC(CoupledSubscriptPairs,
"Coupled subscript pairs");
80 STATISTIC(NonlinearSubscriptPairs,
"Nonlinear subscript pairs");
81 STATISTIC(ZIVapplications,
"ZIV applications");
82 STATISTIC(ZIVindependence,
"ZIV independence");
83 STATISTIC(StrongSIVapplications,
"Strong SIV applications");
84 STATISTIC(StrongSIVsuccesses,
"Strong SIV successes");
85 STATISTIC(StrongSIVindependence,
"Strong SIV independence");
86 STATISTIC(WeakCrossingSIVapplications,
"Weak-Crossing SIV applications");
87 STATISTIC(WeakCrossingSIVsuccesses,
"Weak-Crossing SIV successes");
88 STATISTIC(WeakCrossingSIVindependence,
"Weak-Crossing SIV independence");
89 STATISTIC(ExactSIVapplications,
"Exact SIV applications");
90 STATISTIC(ExactSIVsuccesses,
"Exact SIV successes");
91 STATISTIC(ExactSIVindependence,
"Exact SIV independence");
92 STATISTIC(WeakZeroSIVapplications,
"Weak-Zero SIV applications");
93 STATISTIC(WeakZeroSIVsuccesses,
"Weak-Zero SIV successes");
94 STATISTIC(WeakZeroSIVindependence,
"Weak-Zero SIV independence");
95 STATISTIC(ExactRDIVapplications,
"Exact RDIV applications");
96 STATISTIC(ExactRDIVindependence,
"Exact RDIV independence");
97 STATISTIC(SymbolicRDIVapplications,
"Symbolic RDIV applications");
98 STATISTIC(SymbolicRDIVindependence,
"Symbolic RDIV independence");
99 STATISTIC(DeltaApplications,
"Delta applications");
100 STATISTIC(DeltaSuccesses,
"Delta successes");
101 STATISTIC(DeltaIndependence,
"Delta independence");
102 STATISTIC(DeltaPropagations,
"Delta propagations");
103 STATISTIC(GCDapplications,
"GCD applications");
104 STATISTIC(GCDsuccesses,
"GCD successes");
105 STATISTIC(GCDindependence,
"GCD independence");
106 STATISTIC(BanerjeeApplications,
"Banerjee applications");
107 STATISTIC(BanerjeeIndependence,
"Banerjee independence");
108 STATISTIC(BanerjeeSuccesses,
"Banerjee successes");
112 cl::desc(
"Try to delinearize array references."));
118 "Dependence Analysis",
true,
true)
125 char DependenceAnalysis::
ID = 0;
129 return new DependenceAnalysis();
135 AA = &getAnalysis<AliasAnalysis>();
136 SE = &getAnalysis<ScalarEvolution>();
137 LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
162 SrcI != SrcE; ++SrcI) {
163 if (isa<StoreInst>(*SrcI) || isa<LoadInst>(*SrcI)) {
165 DstI != DstE; ++DstI) {
166 if (isa<StoreInst>(*DstI) || isa<LoadInst>(*DstI)) {
167 OS <<
"da analyze - ";
168 if (
auto D = DA->
depends(&*SrcI, &*DstI,
true)) {
171 if (D->isSplitable(
Level)) {
172 OS <<
"da analyze - split level = " <<
Level;
231 bool PossiblyLoopIndependent,
232 unsigned CommonLevels)
233 :
Dependence(Source, Destination), Levels(CommonLevels),
234 LoopIndependent(PossiblyLoopIndependent) {
236 DV = CommonLevels ?
new DVEntry[CommonLevels] :
nullptr;
243 assert(0 < Level && Level <= Levels &&
"Level out of range");
250 assert(0 < Level && Level <= Levels &&
"Level out of range");
259 assert(0 < Level && Level <= Levels &&
"Level out of range");
260 return DV[Level - 1].
Scalar;
267 assert(0 < Level && Level <= Levels &&
"Level out of range");
275 assert(0 < Level && Level <= Levels &&
"Level out of range");
282 assert(0 < Level && Level <= Levels &&
"Level out of range");
292 const SCEV *DependenceAnalysis::Constraint::getX()
const {
293 assert(
Kind == Point &&
"Kind should be Point");
300 const SCEV *DependenceAnalysis::Constraint::getY()
const {
301 assert(
Kind == Point &&
"Kind should be Point");
308 const SCEV *DependenceAnalysis::Constraint::getA()
const {
309 assert((
Kind == Line ||
Kind == Distance) &&
310 "Kind should be Line (or Distance)");
317 const SCEV *DependenceAnalysis::Constraint::getB()
const {
318 assert((
Kind == Line ||
Kind == Distance) &&
319 "Kind should be Line (or Distance)");
326 const SCEV *DependenceAnalysis::Constraint::getC()
const {
327 assert((
Kind == Line ||
Kind == Distance) &&
328 "Kind should be Line (or Distance)");
335 const SCEV *DependenceAnalysis::Constraint::getD()
const {
336 assert(
Kind == Distance &&
"Kind should be Distance");
337 return SE->getNegativeSCEV(
C);
342 const Loop *DependenceAnalysis::Constraint::getAssociatedLoop()
const {
343 assert((
Kind == Distance ||
Kind == Line ||
Kind == Point) &&
344 "Kind should be Distance, Line, or Point");
345 return AssociatedLoop;
349 void DependenceAnalysis::Constraint::setPoint(
const SCEV *
X,
351 const Loop *CurLoop) {
355 AssociatedLoop = CurLoop;
359 void DependenceAnalysis::Constraint::setLine(
const SCEV *AA,
362 const Loop *CurLoop) {
367 AssociatedLoop = CurLoop;
371 void DependenceAnalysis::Constraint::setDistance(
const SCEV *D,
372 const Loop *CurLoop) {
374 A = SE->getConstant(D->
getType(), 1);
375 B = SE->getNegativeSCEV(
A);
376 C = SE->getNegativeSCEV(D);
377 AssociatedLoop = CurLoop;
381 void DependenceAnalysis::Constraint::setEmpty() {
399 OS <<
" Point is <" << *getX() <<
", " << *getY() <<
">\n";
400 else if (isDistance())
401 OS <<
" Distance is " << *getD() <<
402 " (" << *getA() <<
"*X + " << *getB() <<
"*Y = " << *getC() <<
")\n";
404 OS <<
" Line is " << *getA() <<
"*X + " <<
405 *getB() <<
"*Y = " << *getC() <<
"\n";
418 bool DependenceAnalysis::intersectConstraints(Constraint *
X,
419 const Constraint *
Y) {
421 DEBUG(
dbgs() <<
"\tintersect constraints\n");
424 assert(!Y->isPoint() &&
"Y must not be a Point");
438 if (X->isDistance() && Y->isDistance()) {
439 DEBUG(
dbgs() <<
"\t intersect 2 distances\n");
449 if (isa<SCEVConstant>(Y->getD())) {
462 assert(!(X->isPoint() && Y->isPoint()) &&
463 "We shouldn't ever see X->isPoint() && Y->isPoint()");
465 if (X->isLine() && Y->isLine()) {
466 DEBUG(
dbgs() <<
"\t intersect 2 lines\n");
485 DEBUG(
dbgs() <<
"\t\tdifferent slopes\n");
500 if (!C1B2_C2B1 || !C1A2_C2A1 ||
501 !A1B2_A2B1 || !A2B1_A1B2)
503 APInt Xtop = C1B2_C2B1->getValue()->getValue();
504 APInt Xbot = A1B2_A2B1->getValue()->getValue();
506 APInt Ybot = A2B1_A1B2->getValue()->getValue();
507 DEBUG(
dbgs() <<
"\t\tXtop = " << Xtop <<
"\n");
508 DEBUG(
dbgs() <<
"\t\tXbot = " << Xbot <<
"\n");
509 DEBUG(
dbgs() <<
"\t\tYtop = " << Ytop <<
"\n");
510 DEBUG(
dbgs() <<
"\t\tYbot = " << Ybot <<
"\n");
517 if (Xr != 0 || Yr != 0) {
522 DEBUG(
dbgs() <<
"\t\tX = " << Xq <<
", Y = " << Yq <<
"\n");
523 if (Xq.
slt(0) || Yq.
slt(0)) {
529 collectConstantUpperBound(X->getAssociatedLoop(), Prod1->
getType())) {
530 APInt UpperBound = CUB->getValue()->getValue();
531 DEBUG(
dbgs() <<
"\t\tupper bound = " << UpperBound <<
"\n");
532 if (Xq.
sgt(UpperBound) || Yq.
sgt(UpperBound)) {
540 X->getAssociatedLoop());
548 assert(!(X->isLine() && Y->isPoint()) &&
"This case should never occur");
550 if (X->isPoint() && Y->isLine()) {
551 DEBUG(
dbgs() <<
"\t intersect Point and Line\n");
575 bool Splitable =
false;
591 for (
unsigned II = 1; II <= Levels; ++II) {
642 if (
const LoadInst *LI = dyn_cast<LoadInst>(I))
643 return LI->isUnordered();
644 else if (
const StoreInst *
SI = dyn_cast<StoreInst>(I))
645 return SI->isUnordered();
652 if (
LoadInst *LI = dyn_cast<LoadInst>(I))
653 return LI->getPointerOperand();
655 return SI->getPointerOperand();
711 void DependenceAnalysis::establishNestingLevels(
const Instruction *Src,
719 SrcLevels = SrcLevel;
720 MaxLevels = SrcLevel + DstLevel;
721 while (SrcLevel > DstLevel) {
725 while (DstLevel > SrcLevel) {
729 while (SrcLoop != DstLoop) {
734 CommonLevels = SrcLevel;
735 MaxLevels -= CommonLevels;
741 unsigned DependenceAnalysis::mapSrcLoop(
const Loop *SrcLoop)
const {
748 unsigned DependenceAnalysis::mapDstLoop(
const Loop *DstLoop)
const {
750 if (D > CommonLevels)
751 return D - CommonLevels + SrcLevels;
759 const Loop *LoopNest)
const {
770 void DependenceAnalysis::collectCommonLoops(
const SCEV *Expression,
771 const Loop *LoopNest,
783 unsigned widestWidthSeen = 0;
788 for (
unsigned i = 0; i < Pairs.
size(); i++) {
789 const SCEV *Src = Pairs[i]->Src;
790 const SCEV *Dst = Pairs[i]->Dst;
793 if (SrcTy ==
nullptr || DstTy ==
nullptr) {
794 assert(SrcTy == DstTy &&
"This function only unify integer types and "
795 "expect Src and Dst share the same type "
803 if (DstTy->getBitWidth() > widestWidthSeen) {
804 widestWidthSeen = DstTy->getBitWidth();
810 assert(widestWidthSeen > 0);
813 for (
unsigned i = 0; i < Pairs.
size(); i++) {
814 const SCEV *Src = Pairs[i]->Src;
815 const SCEV *Dst = Pairs[i]->Dst;
818 if (SrcTy ==
nullptr || DstTy ==
nullptr) {
819 assert(SrcTy == DstTy &&
"This function only unify integer types and "
820 "expect Src and Dst share the same type "
827 if (DstTy->getBitWidth() < widestWidthSeen) {
838 void DependenceAnalysis::removeMatchingExtensions(Subscript *Pair) {
839 const SCEV *Src = Pair->Src;
840 const SCEV *Dst = Pair->Dst;
841 if ((isa<SCEVZeroExtendExpr>(Src) && isa<SCEVZeroExtendExpr>(Dst)) ||
842 (isa<SCEVSignExtendExpr>(Src) && isa<SCEVSignExtendExpr>(Dst))) {
846 const SCEV *DstCastOp = DstCast->getOperand();
847 if (SrcCastOp->getType() == DstCastOp->
getType()) {
848 Pair->Src = SrcCastOp;
849 Pair->Dst = DstCastOp;
857 bool DependenceAnalysis::checkSrcSubscript(
const SCEV *Src,
858 const Loop *LoopNest,
866 if (!isa<SCEVCouldNotCompute>(UB)) {
876 return checkSrcSubscript(Start, LoopNest, Loops);
883 bool DependenceAnalysis::checkDstSubscript(
const SCEV *Dst,
884 const Loop *LoopNest,
892 if (!isa<SCEVCouldNotCompute>(UB)) {
902 return checkDstSubscript(Start, LoopNest, Loops);
909 DependenceAnalysis::Subscript::ClassificationKind
910 DependenceAnalysis::classifyPair(
const SCEV *Src,
const Loop *SrcLoopNest,
911 const SCEV *Dst,
const Loop *DstLoopNest,
915 if (!checkSrcSubscript(Src, SrcLoopNest, SrcLoops))
916 return Subscript::NonLinear;
917 if (!checkDstSubscript(Dst, DstLoopNest, DstLoops))
918 return Subscript::NonLinear;
921 unsigned N = Loops.
count();
923 return Subscript::ZIV;
925 return Subscript::SIV;
926 if (N == 2 && (SrcLoops.count() == 0 ||
927 DstLoops.count() == 0 ||
928 (SrcLoops.count() == 1 && DstLoops.count() == 1)))
929 return Subscript::RDIV;
930 return Subscript::MIV;
946 const SCEV *Y)
const {
949 if ((isa<SCEVSignExtendExpr>(X) &&
950 isa<SCEVSignExtendExpr>(Y)) ||
951 (isa<SCEVZeroExtendExpr>(X) &&
952 isa<SCEVZeroExtendExpr>(Y))) {
956 const SCEV *Yop = CY->getOperand();
957 if (Xop->getType() == Yop->
getType()) {
997 const SCEV *DependenceAnalysis::collectUpperBound(
const Loop *L,
1009 const SCEVConstant *DependenceAnalysis::collectConstantUpperBound(
const Loop *L,
1012 if (
const SCEV *UB = collectUpperBound(L, T))
1028 bool DependenceAnalysis::testZIV(
const SCEV *Src,
1031 DEBUG(
dbgs() <<
" src = " << *Src <<
"\n");
1032 DEBUG(
dbgs() <<
" dst = " << *Dst <<
"\n");
1035 DEBUG(
dbgs() <<
" provably dependent\n");
1039 DEBUG(
dbgs() <<
" provably independent\n");
1043 DEBUG(
dbgs() <<
" possibly dependent\n");
1044 Result.Consistent =
false;
1076 bool DependenceAnalysis::strongSIVtest(
const SCEV *Coeff,
1077 const SCEV *SrcConst,
1078 const SCEV *DstConst,
1079 const Loop *CurLoop,
1082 Constraint &NewConstraint)
const {
1084 DEBUG(
dbgs() <<
"\t Coeff = " << *Coeff);
1086 DEBUG(
dbgs() <<
"\t SrcConst = " << *SrcConst);
1088 DEBUG(
dbgs() <<
"\t DstConst = " << *DstConst);
1090 ++StrongSIVapplications;
1091 assert(0 < Level && Level <= CommonLevels &&
"level out of range");
1095 DEBUG(
dbgs() <<
"\t Delta = " << *Delta);
1099 if (
const SCEV *UpperBound = collectUpperBound(CurLoop, Delta->
getType())) {
1100 DEBUG(
dbgs() <<
"\t UpperBound = " << *UpperBound);
1101 DEBUG(
dbgs() <<
", " << *UpperBound->getType() <<
"\n");
1102 const SCEV *AbsDelta =
1104 const SCEV *AbsCoeff =
1109 ++StrongSIVindependence;
1110 ++StrongSIVsuccesses;
1116 if (isa<SCEVConstant>(Delta) && isa<SCEVConstant>(Coeff)) {
1117 APInt ConstDelta = cast<SCEVConstant>(Delta)->getValue()->getValue();
1118 APInt ConstCoeff = cast<SCEVConstant>(Coeff)->getValue()->getValue();
1119 APInt Distance = ConstDelta;
1120 APInt Remainder = ConstDelta;
1122 DEBUG(
dbgs() <<
"\t Distance = " << Distance <<
"\n");
1123 DEBUG(
dbgs() <<
"\t Remainder = " << Remainder <<
"\n");
1125 if (Remainder != 0) {
1127 ++StrongSIVindependence;
1128 ++StrongSIVsuccesses;
1132 NewConstraint.setDistance(SE->
getConstant(Distance), CurLoop);
1133 if (Distance.
sgt(0))
1135 else if (Distance.
slt(0))
1139 ++StrongSIVsuccesses;
1141 else if (Delta->
isZero()) {
1144 NewConstraint.setDistance(Delta, CurLoop);
1146 ++StrongSIVsuccesses;
1149 if (Coeff->
isOne()) {
1150 DEBUG(
dbgs() <<
"\t Distance = " << *Delta <<
"\n");
1152 NewConstraint.setDistance(Delta, CurLoop);
1155 Result.Consistent =
false;
1156 NewConstraint.setLine(Coeff,
1171 if ((DeltaMaybePositive && CoeffMaybePositive) ||
1172 (DeltaMaybeNegative && CoeffMaybeNegative))
1176 if ((DeltaMaybeNegative && CoeffMaybePositive) ||
1177 (DeltaMaybePositive && CoeffMaybeNegative))
1179 if (NewDirection < Result.DV[Level].
Direction)
1180 ++StrongSIVsuccesses;
1215 bool DependenceAnalysis::weakCrossingSIVtest(
const SCEV *Coeff,
1216 const SCEV *SrcConst,
1217 const SCEV *DstConst,
1218 const Loop *CurLoop,
1221 Constraint &NewConstraint,
1222 const SCEV *&SplitIter)
const {
1223 DEBUG(
dbgs() <<
"\tWeak-Crossing SIV test\n");
1224 DEBUG(
dbgs() <<
"\t Coeff = " << *Coeff <<
"\n");
1225 DEBUG(
dbgs() <<
"\t SrcConst = " << *SrcConst <<
"\n");
1226 DEBUG(
dbgs() <<
"\t DstConst = " << *DstConst <<
"\n");
1227 ++WeakCrossingSIVapplications;
1228 assert(0 < Level && Level <= CommonLevels &&
"Level out of range");
1230 Result.Consistent =
false;
1232 DEBUG(
dbgs() <<
"\t Delta = " << *Delta <<
"\n");
1233 NewConstraint.setLine(Coeff, Coeff, Delta, CurLoop);
1237 ++WeakCrossingSIVsuccesses;
1239 ++WeakCrossingSIVindependence;
1252 assert(ConstCoeff &&
1253 "dynamic cast of negative of ConstCoeff should yield constant");
1256 assert(SE->
isKnownPositive(ConstCoeff) &&
"ConstCoeff should be positive");
1264 DEBUG(
dbgs() <<
"\t Split iter = " << *SplitIter <<
"\n");
1272 DEBUG(
dbgs() <<
"\t Delta = " << *Delta <<
"\n");
1273 DEBUG(
dbgs() <<
"\t ConstCoeff = " << *ConstCoeff <<
"\n");
1276 ++WeakCrossingSIVindependence;
1277 ++WeakCrossingSIVsuccesses;
1283 if (
const SCEV *UpperBound = collectUpperBound(CurLoop, Delta->
getType())) {
1284 DEBUG(
dbgs() <<
"\t UpperBound = " << *UpperBound <<
"\n");
1288 DEBUG(
dbgs() <<
"\t ML = " << *ML <<
"\n");
1291 ++WeakCrossingSIVindependence;
1292 ++WeakCrossingSIVsuccesses;
1299 ++WeakCrossingSIVsuccesses;
1301 ++WeakCrossingSIVindependence;
1313 APInt Distance = APDelta;
1314 APInt Remainder = APDelta;
1316 DEBUG(
dbgs() <<
"\t Remainder = " << Remainder <<
"\n");
1317 if (Remainder != 0) {
1319 ++WeakCrossingSIVindependence;
1320 ++WeakCrossingSIVsuccesses;
1323 DEBUG(
dbgs() <<
"\t Distance = " << Distance <<
"\n");
1327 Remainder = Distance.
srem(Two);
1328 DEBUG(
dbgs() <<
"\t Remainder = " << Remainder <<
"\n");
1329 if (Remainder != 0) {
1332 ++WeakCrossingSIVsuccesses;
1351 APInt A0(Bits, 1,
true), A1(Bits, 0,
true);
1352 APInt B0(Bits, 0,
true), B1(Bits, 1,
true);
1359 APInt A2 = A0 - Q*A1; A0 = A1; A1 = A2;
1360 APInt B2 = B0 - Q*B1; B0 = B1; B1 = B2;
1365 DEBUG(
dbgs() <<
"\t GCD = " << G <<
"\n");
1366 X = AM.
slt(0) ? -A1 : A1;
1367 Y = BM.
slt(0) ? B1 : -B1;
1387 if ((A.
sgt(0) && B.
sgt(0)) ||
1402 if ((A.
sgt(0) && B.
sgt(0)) ||
1412 return A.
sgt(B) ? A : B;
1418 return A.
slt(B) ? A : B;
1437 bool DependenceAnalysis::exactSIVtest(
const SCEV *SrcCoeff,
1438 const SCEV *DstCoeff,
1439 const SCEV *SrcConst,
1440 const SCEV *DstConst,
1441 const Loop *CurLoop,
1444 Constraint &NewConstraint)
const {
1446 DEBUG(
dbgs() <<
"\t SrcCoeff = " << *SrcCoeff <<
" = AM\n");
1447 DEBUG(
dbgs() <<
"\t DstCoeff = " << *DstCoeff <<
" = BM\n");
1448 DEBUG(
dbgs() <<
"\t SrcConst = " << *SrcConst <<
"\n");
1449 DEBUG(
dbgs() <<
"\t DstConst = " << *DstConst <<
"\n");
1450 ++ExactSIVapplications;
1451 assert(0 < Level && Level <= CommonLevels &&
"Level out of range");
1453 Result.Consistent =
false;
1455 DEBUG(
dbgs() <<
"\t Delta = " << *Delta <<
"\n");
1461 if (!ConstDelta || !ConstSrcCoeff || !ConstDstCoeff)
1466 APInt AM = ConstSrcCoeff->getValue()->getValue();
1467 APInt BM = ConstDstCoeff->getValue()->getValue();
1471 ++ExactSIVindependence;
1472 ++ExactSIVsuccesses;
1476 DEBUG(
dbgs() <<
"\t X = " << X <<
", Y = " << Y <<
"\n");
1479 APInt UM(Bits, 1,
true);
1480 bool UMvalid =
false;
1483 collectConstantUpperBound(CurLoop, Delta->
getType())) {
1484 UM = CUB->getValue()->getValue();
1485 DEBUG(
dbgs() <<
"\t UM = " << UM <<
"\n");
1496 DEBUG(
dbgs() <<
"\t TL = " << TL <<
"\n");
1499 DEBUG(
dbgs() <<
"\t TU = " << TU <<
"\n");
1504 DEBUG(
dbgs() <<
"\t TU = " << TU <<
"\n");
1507 DEBUG(
dbgs() <<
"\t TL = " << TL <<
"\n");
1515 DEBUG(
dbgs() <<
"\t TL = " << TL <<
"\n");
1518 DEBUG(
dbgs() <<
"\t TU = " << TU <<
"\n");
1523 DEBUG(
dbgs() <<
"\t TU = " << TU <<
"\n");
1526 DEBUG(
dbgs() <<
"\t TL = " << TL <<
"\n");
1530 ++ExactSIVindependence;
1531 ++ExactSIVsuccesses;
1541 DEBUG(
dbgs() <<
"\t exploring LT direction\n");
1545 DEBUG(
dbgs() <<
"\t\t TL = " << TL <<
"\n");
1549 DEBUG(
dbgs() <<
"\t\t TU = " << TU <<
"\n");
1553 ++ExactSIVsuccesses;
1559 DEBUG(
dbgs() <<
"\t exploring EQ direction\n");
1562 DEBUG(
dbgs() <<
"\t\t TL = " << TL <<
"\n");
1566 DEBUG(
dbgs() <<
"\t\t TU = " << TU <<
"\n");
1571 DEBUG(
dbgs() <<
"\t\t TL = " << TL <<
"\n");
1575 DEBUG(
dbgs() <<
"\t\t TU = " << TU <<
"\n");
1579 ++ExactSIVsuccesses;
1585 DEBUG(
dbgs() <<
"\t exploring GT direction\n");
1588 DEBUG(
dbgs() <<
"\t\t TL = " << TL <<
"\n");
1592 DEBUG(
dbgs() <<
"\t\t TU = " << TU <<
"\n");
1596 ++ExactSIVsuccesses;
1602 ++ExactSIVindependence;
1614 return ConstDividend.
srem(ConstDivisor) == 0;
1649 bool DependenceAnalysis::weakZeroSrcSIVtest(
const SCEV *DstCoeff,
1650 const SCEV *SrcConst,
1651 const SCEV *DstConst,
1652 const Loop *CurLoop,
1655 Constraint &NewConstraint)
const {
1659 DEBUG(
dbgs() <<
"\tWeak-Zero (src) SIV test\n");
1660 DEBUG(
dbgs() <<
"\t DstCoeff = " << *DstCoeff <<
"\n");
1661 DEBUG(
dbgs() <<
"\t SrcConst = " << *SrcConst <<
"\n");
1662 DEBUG(
dbgs() <<
"\t DstConst = " << *DstConst <<
"\n");
1663 ++WeakZeroSIVapplications;
1664 assert(0 < Level && Level <= MaxLevels &&
"Level out of range");
1666 Result.Consistent =
false;
1669 DstCoeff, Delta, CurLoop);
1670 DEBUG(
dbgs() <<
"\t Delta = " << *Delta <<
"\n");
1672 if (Level < CommonLevels) {
1675 ++WeakZeroSIVsuccesses;
1682 const SCEV *AbsCoeff =
1685 const SCEV *NewDelta =
1690 if (
const SCEV *UpperBound = collectUpperBound(CurLoop, Delta->
getType())) {
1691 DEBUG(
dbgs() <<
"\t UpperBound = " << *UpperBound <<
"\n");
1694 ++WeakZeroSIVindependence;
1695 ++WeakZeroSIVsuccesses;
1700 if (Level < CommonLevels) {
1703 ++WeakZeroSIVsuccesses;
1713 ++WeakZeroSIVindependence;
1714 ++WeakZeroSIVsuccesses;
1719 if (isa<SCEVConstant>(Delta) &&
1721 ++WeakZeroSIVindependence;
1722 ++WeakZeroSIVsuccesses;
1760 bool DependenceAnalysis::weakZeroDstSIVtest(
const SCEV *SrcCoeff,
1761 const SCEV *SrcConst,
1762 const SCEV *DstConst,
1763 const Loop *CurLoop,
1766 Constraint &NewConstraint)
const {
1769 DEBUG(
dbgs() <<
"\tWeak-Zero (dst) SIV test\n");
1770 DEBUG(
dbgs() <<
"\t SrcCoeff = " << *SrcCoeff <<
"\n");
1771 DEBUG(
dbgs() <<
"\t SrcConst = " << *SrcConst <<
"\n");
1772 DEBUG(
dbgs() <<
"\t DstConst = " << *DstConst <<
"\n");
1773 ++WeakZeroSIVapplications;
1774 assert(0 < Level && Level <= SrcLevels &&
"Level out of range");
1776 Result.Consistent =
false;
1780 DEBUG(
dbgs() <<
"\t Delta = " << *Delta <<
"\n");
1782 if (Level < CommonLevels) {
1785 ++WeakZeroSIVsuccesses;
1792 const SCEV *AbsCoeff =
1795 const SCEV *NewDelta =
1800 if (
const SCEV *UpperBound = collectUpperBound(CurLoop, Delta->
getType())) {
1801 DEBUG(
dbgs() <<
"\t UpperBound = " << *UpperBound <<
"\n");
1804 ++WeakZeroSIVindependence;
1805 ++WeakZeroSIVsuccesses;
1810 if (Level < CommonLevels) {
1813 ++WeakZeroSIVsuccesses;
1823 ++WeakZeroSIVindependence;
1824 ++WeakZeroSIVsuccesses;
1829 if (isa<SCEVConstant>(Delta) &&
1831 ++WeakZeroSIVindependence;
1832 ++WeakZeroSIVsuccesses;
1846 bool DependenceAnalysis::exactRDIVtest(
const SCEV *SrcCoeff,
1847 const SCEV *DstCoeff,
1848 const SCEV *SrcConst,
1849 const SCEV *DstConst,
1850 const Loop *SrcLoop,
1851 const Loop *DstLoop,
1854 DEBUG(
dbgs() <<
"\t SrcCoeff = " << *SrcCoeff <<
" = AM\n");
1855 DEBUG(
dbgs() <<
"\t DstCoeff = " << *DstCoeff <<
" = BM\n");
1856 DEBUG(
dbgs() <<
"\t SrcConst = " << *SrcConst <<
"\n");
1857 DEBUG(
dbgs() <<
"\t DstConst = " << *DstConst <<
"\n");
1858 ++ExactRDIVapplications;
1859 Result.Consistent =
false;
1861 DEBUG(
dbgs() <<
"\t Delta = " << *Delta <<
"\n");
1865 if (!ConstDelta || !ConstSrcCoeff || !ConstDstCoeff)
1870 APInt AM = ConstSrcCoeff->getValue()->getValue();
1871 APInt BM = ConstDstCoeff->getValue()->getValue();
1875 ++ExactRDIVindependence;
1879 DEBUG(
dbgs() <<
"\t X = " << X <<
", Y = " << Y <<
"\n");
1882 APInt SrcUM(Bits, 1,
true);
1883 bool SrcUMvalid =
false;
1886 collectConstantUpperBound(SrcLoop, Delta->
getType())) {
1887 SrcUM = UpperBound->getValue()->getValue();
1888 DEBUG(
dbgs() <<
"\t SrcUM = " << SrcUM <<
"\n");
1892 APInt DstUM(Bits, 1,
true);
1893 bool DstUMvalid =
false;
1896 collectConstantUpperBound(DstLoop, Delta->
getType())) {
1897 DstUM = UpperBound->getValue()->getValue();
1898 DEBUG(
dbgs() <<
"\t DstUM = " << DstUM <<
"\n");
1909 DEBUG(
dbgs() <<
"\t TL = " << TL <<
"\n");
1912 DEBUG(
dbgs() <<
"\t TU = " << TU <<
"\n");
1917 DEBUG(
dbgs() <<
"\t TU = " << TU <<
"\n");
1920 DEBUG(
dbgs() <<
"\t TL = " << TL <<
"\n");
1928 DEBUG(
dbgs() <<
"\t TL = " << TL <<
"\n");
1931 DEBUG(
dbgs() <<
"\t TU = " << TU <<
"\n");
1936 DEBUG(
dbgs() <<
"\t TU = " << TU <<
"\n");
1939 DEBUG(
dbgs() <<
"\t TL = " << TL <<
"\n");
1943 ++ExactRDIVindependence;
1990 bool DependenceAnalysis::symbolicRDIVtest(
const SCEV *A1,
1995 const Loop *Loop2)
const {
1996 ++SymbolicRDIVapplications;
1997 DEBUG(
dbgs() <<
"\ttry symbolic RDIV test\n");
2000 DEBUG(
dbgs() <<
"\t A2 = " << *A2 <<
"\n");
2001 DEBUG(
dbgs() <<
"\t C1 = " << *C1 <<
"\n");
2002 DEBUG(
dbgs() <<
"\t C2 = " << *C2 <<
"\n");
2003 const SCEV *N1 = collectUpperBound(Loop1, A1->
getType());
2004 const SCEV *N2 = collectUpperBound(Loop2, A1->
getType());
2005 DEBUG(
if (N1)
dbgs() <<
"\t N1 = " << *N1 <<
"\n");
2006 DEBUG(
if (N2)
dbgs() <<
"\t N2 = " << *N2 <<
"\n");
2009 DEBUG(
dbgs() <<
"\t C2 - C1 = " << *C2_C1 <<
"\n");
2010 DEBUG(
dbgs() <<
"\t C1 - C2 = " << *C1_C2 <<
"\n");
2017 DEBUG(
dbgs() <<
"\t A1*N1 = " << *A1N1 <<
"\n");
2019 ++SymbolicRDIVindependence;
2026 DEBUG(
dbgs() <<
"\t A2*N2 = " << *A2N2 <<
"\n");
2028 ++SymbolicRDIVindependence;
2040 DEBUG(
dbgs() <<
"\t A1*N1 - A2*N2 = " << *A1N1_A2N2 <<
"\n");
2042 ++SymbolicRDIVindependence;
2048 ++SymbolicRDIVindependence;
2061 DEBUG(
dbgs() <<
"\t A1*N1 - A2*N2 = " << *A1N1_A2N2 <<
"\n");
2063 ++SymbolicRDIVindependence;
2069 ++SymbolicRDIVindependence;
2078 DEBUG(
dbgs() <<
"\t A1*N1 = " << *A1N1 <<
"\n");
2080 ++SymbolicRDIVindependence;
2087 DEBUG(
dbgs() <<
"\t A2*N2 = " << *A2N2 <<
"\n");
2089 ++SymbolicRDIVindependence;
2107 bool DependenceAnalysis::testSIV(
const SCEV *Src,
2111 Constraint &NewConstraint,
2112 const SCEV *&SplitIter)
const {
2113 DEBUG(
dbgs() <<
" src = " << *Src <<
"\n");
2114 DEBUG(
dbgs() <<
" dst = " << *Dst <<
"\n");
2117 if (SrcAddRec && DstAddRec) {
2119 const SCEV *DstConst = DstAddRec->getStart();
2121 const SCEV *DstCoeff = DstAddRec->getStepRecurrence(*SE);
2123 assert(CurLoop == DstAddRec->getLoop() &&
2124 "both loops in SIV should be same");
2125 Level = mapSrcLoop(CurLoop);
2127 if (SrcCoeff == DstCoeff)
2128 disproven = strongSIVtest(SrcCoeff, SrcConst, DstConst, CurLoop,
2129 Level, Result, NewConstraint);
2131 disproven = weakCrossingSIVtest(SrcCoeff, SrcConst, DstConst, CurLoop,
2132 Level, Result, NewConstraint, SplitIter);
2134 disproven = exactSIVtest(SrcCoeff, DstCoeff, SrcConst, DstConst, CurLoop,
2135 Level, Result, NewConstraint);
2137 gcdMIVtest(Src, Dst, Result) ||
2138 symbolicRDIVtest(SrcCoeff, DstCoeff, SrcConst, DstConst, CurLoop, CurLoop);
2143 const SCEV *DstConst = Dst;
2145 Level = mapSrcLoop(CurLoop);
2146 return weakZeroDstSIVtest(SrcCoeff, SrcConst, DstConst, CurLoop,
2147 Level, Result, NewConstraint) ||
2148 gcdMIVtest(Src, Dst, Result);
2151 const SCEV *DstConst = DstAddRec->getStart();
2152 const SCEV *DstCoeff = DstAddRec->getStepRecurrence(*SE);
2153 const SCEV *SrcConst = Src;
2154 const Loop *CurLoop = DstAddRec->getLoop();
2155 Level = mapDstLoop(CurLoop);
2156 return weakZeroSrcSIVtest(DstCoeff, SrcConst, DstConst,
2157 CurLoop, Level, Result, NewConstraint) ||
2158 gcdMIVtest(Src, Dst, Result);
2178 bool DependenceAnalysis::testRDIV(
const SCEV *Src,
2187 const SCEV *SrcConst, *DstConst;
2188 const SCEV *SrcCoeff, *DstCoeff;
2189 const Loop *SrcLoop, *DstLoop;
2191 DEBUG(
dbgs() <<
" src = " << *Src <<
"\n");
2192 DEBUG(
dbgs() <<
" dst = " << *Dst <<
"\n");
2195 if (SrcAddRec && DstAddRec) {
2198 SrcLoop = SrcAddRec->
getLoop();
2199 DstConst = DstAddRec->getStart();
2200 DstCoeff = DstAddRec->getStepRecurrence(*SE);
2201 DstLoop = DstAddRec->getLoop();
2203 else if (SrcAddRec) {
2205 dyn_cast<SCEVAddRecExpr>(SrcAddRec->
getStart())) {
2206 SrcConst = tmpAddRec->getStart();
2207 SrcCoeff = tmpAddRec->getStepRecurrence(*SE);
2208 SrcLoop = tmpAddRec->getLoop();
2211 DstLoop = SrcAddRec->
getLoop();
2216 else if (DstAddRec) {
2218 dyn_cast<SCEVAddRecExpr>(DstAddRec->getStart())) {
2219 DstConst = tmpAddRec->getStart();
2220 DstCoeff = tmpAddRec->getStepRecurrence(*SE);
2221 DstLoop = tmpAddRec->getLoop();
2224 SrcLoop = DstAddRec->getLoop();
2231 return exactRDIVtest(SrcCoeff, DstCoeff,
2235 gcdMIVtest(Src, Dst, Result) ||
2236 symbolicRDIVtest(SrcCoeff, DstCoeff,
2245 bool DependenceAnalysis::testMIV(
const SCEV *Src,
2249 DEBUG(
dbgs() <<
" src = " << *Src <<
"\n");
2250 DEBUG(
dbgs() <<
" dst = " << *Dst <<
"\n");
2251 Result.Consistent =
false;
2252 return gcdMIVtest(Src, Dst, Result) ||
2253 banerjeeMIVtest(Src, Dst, Loops, Result);
2261 for (
unsigned Op = 0, Ops = Product->
getNumOperands(); Op < Ops; Op++) {
2287 bool DependenceAnalysis::gcdMIVtest(
const SCEV *Src,
2299 const SCEV *Coefficients = Src;
2301 dyn_cast<SCEVAddRecExpr>(Coefficients)) {
2304 if (
const SCEVMulExpr *Product = dyn_cast<SCEVMulExpr>(Coeff))
2314 const SCEV *SrcConst = Coefficients;
2322 dyn_cast<SCEVAddRecExpr>(Coefficients)) {
2325 if (
const SCEVMulExpr *Product = dyn_cast<SCEVMulExpr>(Coeff))
2335 const SCEV *DstConst = Coefficients;
2339 DEBUG(
dbgs() <<
" Delta = " << *Delta <<
"\n");
2341 if (
const SCEVAddExpr *Sum = dyn_cast<SCEVAddExpr>(Delta)) {
2343 for (
unsigned Op = 0, Ops = Sum->getNumOperands(); Op < Ops; Op++) {
2344 const SCEV *Operand = Sum->getOperand(Op);
2345 if (isa<SCEVConstant>(Operand)) {
2346 assert(!Constant &&
"Surprised to find multiple constants");
2347 Constant = cast<SCEVConstant>(Operand);
2349 else if (
const SCEVMulExpr *Product = dyn_cast<SCEVMulExpr>(Operand)) {
2357 ConstOpValue.
abs());
2366 DEBUG(
dbgs() <<
" ConstDelta = " << ConstDelta <<
"\n");
2367 if (ConstDelta == 0)
2370 DEBUG(
dbgs() <<
" RunningGCD = " << RunningGCD <<
"\n");
2371 APInt Remainder = ConstDelta.
srem(RunningGCD);
2372 if (Remainder != 0) {
2389 DEBUG(
dbgs() <<
" ExtraGCD = " << ExtraGCD <<
'\n');
2391 bool Improved =
false;
2394 dyn_cast<SCEVAddRecExpr>(Coefficients)) {
2397 RunningGCD = ExtraGCD;
2400 const SCEV *Inner = Src;
2401 while (RunningGCD != 1 && isa<SCEVAddRecExpr>(Inner)) {
2402 AddRec = cast<SCEVAddRecExpr>(Inner);
2404 if (CurLoop == AddRec->
getLoop())
2407 if (
const SCEVMulExpr *Product = dyn_cast<SCEVMulExpr>(Coeff))
2412 Constant = cast<SCEVConstant>(Coeff);
2419 while (RunningGCD != 1 && isa<SCEVAddRecExpr>(Inner)) {
2420 AddRec = cast<SCEVAddRecExpr>(Inner);
2422 if (CurLoop == AddRec->
getLoop())
2425 if (
const SCEVMulExpr *Product = dyn_cast<SCEVMulExpr>(Coeff))
2430 Constant = cast<SCEVConstant>(Coeff);
2437 if (
const SCEVMulExpr *Product = dyn_cast<SCEVMulExpr>(Delta))
2441 else if (isa<SCEVConstant>(Delta))
2442 Constant = cast<SCEVConstant>(Delta);
2450 DEBUG(
dbgs() <<
"\tRunningGCD = " << RunningGCD <<
"\n");
2451 if (RunningGCD != 0) {
2452 Remainder = ConstDelta.
srem(RunningGCD);
2453 DEBUG(
dbgs() <<
"\tRemainder = " << Remainder <<
"\n");
2454 if (Remainder != 0) {
2455 unsigned Level = mapSrcLoop(CurLoop);
2501 bool DependenceAnalysis::banerjeeMIVtest(
const SCEV *Src,
2506 ++BanerjeeApplications;
2507 DEBUG(
dbgs() <<
" Src = " << *Src <<
'\n');
2509 CoefficientInfo *
A = collectCoeffInfo(Src,
true, A0);
2510 DEBUG(
dbgs() <<
" Dst = " << *Dst <<
'\n');
2512 CoefficientInfo *B = collectCoeffInfo(Dst,
false, B0);
2513 BoundInfo *Bound =
new BoundInfo[MaxLevels + 1];
2515 DEBUG(
dbgs() <<
"\tDelta = " << *Delta <<
'\n');
2519 for (
unsigned K = 1; K <= MaxLevels; ++K) {
2520 Bound[K].Iterations = A[K].Iterations ? A[K].Iterations : B[K].Iterations;
2523 findBoundsALL(A, B, Bound, K);
2527 DEBUG(
dbgs() << *Bound[K].Lower[Dependence::DVEntry::ALL] <<
'\t');
2530 if (Bound[K].Upper[Dependence::DVEntry::ALL])
2531 DEBUG(
dbgs() << *Bound[K].Upper[Dependence::DVEntry::ALL] <<
'\n');
2538 bool Disproved =
false;
2539 if (testBounds(Dependence::DVEntry::ALL, 0, Bound, Delta)) {
2541 unsigned DepthExpanded = 0;
2542 unsigned NewDeps = exploreDirections(1, A, B, Bound,
2543 Loops, DepthExpanded, Delta);
2545 bool Improved =
false;
2546 for (
unsigned K = 1; K <= CommonLevels; ++K) {
2548 unsigned Old = Result.DV[K - 1].
Direction;
2549 Result.DV[K - 1].
Direction = Old & Bound[K].DirSet;
2550 Improved |= Old != Result.DV[K - 1].
Direction;
2559 ++BanerjeeSuccesses;
2562 ++BanerjeeIndependence;
2567 ++BanerjeeIndependence;
2582 unsigned DependenceAnalysis::exploreDirections(
unsigned Level,
2587 unsigned &DepthExpanded,
2588 const SCEV *Delta)
const {
2589 if (Level > CommonLevels) {
2592 for (
unsigned K = 1; K <= CommonLevels; ++K) {
2594 Bound[K].DirSet |= Bound[K].Direction;
2596 switch (Bound[K].Direction) {
2606 case Dependence::DVEntry::ALL:
2619 if (Level > DepthExpanded) {
2620 DepthExpanded =
Level;
2622 findBoundsLT(A, B, Bound, Level);
2623 findBoundsGT(A, B, Bound, Level);
2624 findBoundsEQ(A, B, Bound, Level);
2626 DEBUG(
dbgs() <<
"\tBound for level = " << Level <<
'\n');
2629 DEBUG(
dbgs() << *Bound[Level].Lower[Dependence::DVEntry::LT] <<
'\t');
2632 if (Bound[Level].Upper[Dependence::DVEntry::LT])
2633 DEBUG(
dbgs() << *Bound[Level].Upper[Dependence::DVEntry::LT] <<
'\n');
2638 DEBUG(
dbgs() << *Bound[Level].Lower[Dependence::DVEntry::EQ] <<
'\t');
2641 if (Bound[Level].Upper[Dependence::DVEntry::EQ])
2642 DEBUG(
dbgs() << *Bound[Level].Upper[Dependence::DVEntry::EQ] <<
'\n');
2647 DEBUG(
dbgs() << *Bound[Level].Lower[Dependence::DVEntry::GT] <<
'\t');
2650 if (Bound[Level].Upper[Dependence::DVEntry::GT])
2651 DEBUG(
dbgs() << *Bound[Level].Upper[Dependence::DVEntry::GT] <<
'\n');
2657 unsigned NewDeps = 0;
2660 if (testBounds(Dependence::DVEntry::LT, Level, Bound, Delta))
2661 NewDeps += exploreDirections(Level + 1, A, B, Bound,
2662 Loops, DepthExpanded, Delta);
2665 if (testBounds(Dependence::DVEntry::EQ, Level, Bound, Delta))
2666 NewDeps += exploreDirections(Level + 1, A, B, Bound,
2667 Loops, DepthExpanded, Delta);
2670 if (testBounds(Dependence::DVEntry::GT, Level, Bound, Delta))
2671 NewDeps += exploreDirections(Level + 1, A, B, Bound,
2672 Loops, DepthExpanded, Delta);
2678 return exploreDirections(Level + 1, A, B, Bound, Loops, DepthExpanded, Delta);
2683 bool DependenceAnalysis::testBounds(
unsigned char DirKind,
2686 const SCEV *Delta)
const {
2687 Bound[
Level].Direction = DirKind;
2688 if (
const SCEV *LowerBound = getLowerBound(Bound))
2691 if (
const SCEV *UpperBound = getUpperBound(Bound))
2713 void DependenceAnalysis::findBoundsALL(CoefficientInfo *A,
2719 if (Bound[K].Iterations) {
2722 Bound[K].Iterations);
2725 Bound[K].Iterations);
2730 Bound[K].Lower[Dependence::DVEntry::ALL] =
2733 Bound[K].Upper[Dependence::DVEntry::ALL] =
2754 void DependenceAnalysis::findBoundsEQ(CoefficientInfo *A,
2760 if (Bound[K].Iterations) {
2762 const SCEV *NegativePart = getNegativePart(Delta);
2764 SE->
getMulExpr(NegativePart, Bound[K].Iterations);
2765 const SCEV *PositivePart = getPositivePart(Delta);
2767 SE->
getMulExpr(PositivePart, Bound[K].Iterations);
2773 const SCEV *NegativePart = getNegativePart(Delta);
2774 if (NegativePart->
isZero())
2775 Bound[K].Lower[Dependence::DVEntry::EQ] = NegativePart;
2776 const SCEV *PositivePart = getPositivePart(Delta);
2777 if (PositivePart->
isZero())
2778 Bound[K].Upper[Dependence::DVEntry::EQ] = PositivePart;
2796 void DependenceAnalysis::findBoundsLT(CoefficientInfo *A,
2802 if (Bound[K].Iterations) {
2803 const SCEV *Iter_1 =
2805 SE->
getConstant(Bound[K].Iterations->getType(), 1));
2806 const SCEV *NegPart =
2807 getNegativePart(SE->
getMinusSCEV(A[K].NegPart, B[K].Coeff));
2810 const SCEV *PosPart =
2811 getPositivePart(SE->
getMinusSCEV(A[K].PosPart, B[K].Coeff));
2818 const SCEV *NegPart =
2819 getNegativePart(SE->
getMinusSCEV(A[K].NegPart, B[K].Coeff));
2821 Bound[K].Lower[Dependence::DVEntry::LT] = SE->
getNegativeSCEV(B[K].Coeff);
2822 const SCEV *PosPart =
2823 getPositivePart(SE->
getMinusSCEV(A[K].PosPart, B[K].Coeff));
2825 Bound[K].Upper[Dependence::DVEntry::LT] = SE->
getNegativeSCEV(B[K].Coeff);
2843 void DependenceAnalysis::findBoundsGT(CoefficientInfo *A,
2849 if (Bound[K].Iterations) {
2850 const SCEV *Iter_1 =
2852 SE->
getConstant(Bound[K].Iterations->getType(), 1));
2853 const SCEV *NegPart =
2854 getNegativePart(SE->
getMinusSCEV(A[K].Coeff, B[K].PosPart));
2857 const SCEV *PosPart =
2858 getPositivePart(SE->
getMinusSCEV(A[K].Coeff, B[K].NegPart));
2865 const SCEV *NegPart = getNegativePart(SE->
getMinusSCEV(A[K].Coeff, B[K].PosPart));
2867 Bound[K].Lower[Dependence::DVEntry::GT] = A[K].Coeff;
2868 const SCEV *PosPart = getPositivePart(SE->
getMinusSCEV(A[K].Coeff, B[K].NegPart));
2870 Bound[K].Upper[Dependence::DVEntry::GT] = A[K].Coeff;
2876 const SCEV *DependenceAnalysis::getPositivePart(
const SCEV *X)
const {
2882 const SCEV *DependenceAnalysis::getNegativePart(
const SCEV *X)
const {
2890 DependenceAnalysis::CoefficientInfo *
2891 DependenceAnalysis::collectCoeffInfo(
const SCEV *Subscript,
2893 const SCEV *&Constant)
const {
2895 CoefficientInfo *CI =
new CoefficientInfo[MaxLevels + 1];
2896 for (
unsigned K = 1; K <= MaxLevels; ++K) {
2898 CI[K].PosPart = Zero;
2899 CI[K].NegPart = Zero;
2900 CI[K].Iterations =
nullptr;
2902 while (
const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(Subscript)) {
2904 unsigned K = SrcFlag ? mapSrcLoop(L) : mapDstLoop(L);
2906 CI[K].PosPart = getPositivePart(CI[K].Coeff);
2907 CI[K].NegPart = getNegativePart(CI[K].Coeff);
2908 CI[K].Iterations = collectUpperBound(L, Subscript->
getType());
2911 Constant = Subscript;
2913 DEBUG(
dbgs() <<
"\tCoefficient Info\n");
2914 for (
unsigned K = 1; K <= MaxLevels; ++K) {
2915 DEBUG(
dbgs() <<
"\t " << K <<
"\t" << *CI[K].Coeff);
2921 if (CI[K].Iterations)
2927 DEBUG(
dbgs() <<
"\t Constant = " << *Subscript <<
'\n');
2937 const SCEV *DependenceAnalysis::getLowerBound(BoundInfo *Bound)
const {
2938 const SCEV *Sum = Bound[1].Lower[Bound[1].Direction];
2939 for (
unsigned K = 2; Sum && K <= MaxLevels; ++K) {
2940 if (Bound[K].Lower[Bound[K].Direction])
2941 Sum = SE->
getAddExpr(Sum, Bound[K].Lower[Bound[K].Direction]);
2953 const SCEV *DependenceAnalysis::getUpperBound(BoundInfo *Bound)
const {
2954 const SCEV *Sum = Bound[1].Upper[Bound[1].Direction];
2955 for (
unsigned K = 2; Sum && K <= MaxLevels; ++K) {
2956 if (Bound[K].Upper[Bound[K].Direction])
2957 Sum = SE->
getAddExpr(Sum, Bound[K].Upper[Bound[K].Direction]);
2974 const SCEV *DependenceAnalysis::findCoefficient(
const SCEV *Expr,
2975 const Loop *TargetLoop)
const {
2979 if (AddRec->
getLoop() == TargetLoop)
2981 return findCoefficient(AddRec->
getStart(), TargetLoop);
2990 const SCEV *DependenceAnalysis::zeroCoefficient(
const SCEV *Expr,
2991 const Loop *TargetLoop)
const {
2995 if (AddRec->
getLoop() == TargetLoop)
3009 const SCEV *DependenceAnalysis::addToCoefficient(
const SCEV *Expr,
3010 const Loop *TargetLoop,
3018 if (AddRec->
getLoop() == TargetLoop) {
3030 addToCoefficient(AddRec->
getStart(), TargetLoop, Value),
3046 bool DependenceAnalysis::propagate(
const SCEV *&Src,
3051 bool Result =
false;
3053 DEBUG(
dbgs() <<
"\t Constraint[" << LI <<
"] is");
3055 if (Constraints[LI].isDistance())
3056 Result |= propagateDistance(Src, Dst, Constraints[LI], Consistent);
3057 else if (Constraints[LI].isLine())
3058 Result |= propagateLine(Src, Dst, Constraints[LI], Consistent);
3059 else if (Constraints[LI].isPoint())
3060 Result |= propagatePoint(Src, Dst, Constraints[LI]);
3071 bool DependenceAnalysis::propagateDistance(
const SCEV *&Src,
3073 Constraint &CurConstraint,
3075 const Loop *CurLoop = CurConstraint.getAssociatedLoop();
3076 DEBUG(
dbgs() <<
"\t\tSrc is " << *Src <<
"\n");
3077 const SCEV *A_K = findCoefficient(Src, CurLoop);
3082 Src = zeroCoefficient(Src, CurLoop);
3083 DEBUG(
dbgs() <<
"\t\tnew Src is " << *Src <<
"\n");
3084 DEBUG(
dbgs() <<
"\t\tDst is " << *Dst <<
"\n");
3086 DEBUG(
dbgs() <<
"\t\tnew Dst is " << *Dst <<
"\n");
3087 if (!findCoefficient(Dst, CurLoop)->
isZero())
3098 bool DependenceAnalysis::propagateLine(
const SCEV *&Src,
3100 Constraint &CurConstraint,
3102 const Loop *CurLoop = CurConstraint.getAssociatedLoop();
3103 const SCEV *A = CurConstraint.getA();
3104 const SCEV *B = CurConstraint.getB();
3105 const SCEV *
C = CurConstraint.getC();
3106 DEBUG(
dbgs() <<
"\t\tA = " << *A <<
", B = " << *B <<
", C = " << *C <<
"\n");
3107 DEBUG(
dbgs() <<
"\t\tSrc = " << *Src <<
"\n");
3108 DEBUG(
dbgs() <<
"\t\tDst = " << *Dst <<
"\n");
3112 if (!Bconst || !Cconst)
return false;
3114 APInt Charlie = Cconst->getValue()->getValue();
3116 assert(Charlie.
srem(Beta) == 0 &&
"C should be evenly divisible by B");
3117 const SCEV *AP_K = findCoefficient(Dst, CurLoop);
3120 Dst = zeroCoefficient(Dst, CurLoop);
3121 if (!findCoefficient(Src, CurLoop)->
isZero())
3127 if (!Aconst || !Cconst)
return false;
3129 APInt Charlie = Cconst->getValue()->getValue();
3131 assert(Charlie.
srem(Alpha) == 0 &&
"C should be evenly divisible by A");
3132 const SCEV *A_K = findCoefficient(Src, CurLoop);
3134 Src = zeroCoefficient(Src, CurLoop);
3135 if (!findCoefficient(Dst, CurLoop)->
isZero())
3141 if (!Aconst || !Cconst)
return false;
3143 APInt Charlie = Cconst->getValue()->getValue();
3145 assert(Charlie.
srem(Alpha) == 0 &&
"C should be evenly divisible by A");
3146 const SCEV *A_K = findCoefficient(Src, CurLoop);
3148 Src = zeroCoefficient(Src, CurLoop);
3149 Dst = addToCoefficient(Dst, CurLoop, A_K);
3150 if (!findCoefficient(Dst, CurLoop)->
isZero())
3155 const SCEV *A_K = findCoefficient(Src, CurLoop);
3159 Src = zeroCoefficient(Src, CurLoop);
3160 Dst = addToCoefficient(Dst, CurLoop, SE->
getMulExpr(A_K, B));
3161 if (!findCoefficient(Dst, CurLoop)->
isZero())
3164 DEBUG(
dbgs() <<
"\t\tnew Src = " << *Src <<
"\n");
3165 DEBUG(
dbgs() <<
"\t\tnew Dst = " << *Dst <<
"\n");
3173 bool DependenceAnalysis::propagatePoint(
const SCEV *&Src,
3175 Constraint &CurConstraint) {
3176 const Loop *CurLoop = CurConstraint.getAssociatedLoop();
3177 const SCEV *A_K = findCoefficient(Src, CurLoop);
3178 const SCEV *AP_K = findCoefficient(Dst, CurLoop);
3181 DEBUG(
dbgs() <<
"\t\tSrc is " << *Src <<
"\n");
3183 Src = zeroCoefficient(Src, CurLoop);
3184 DEBUG(
dbgs() <<
"\t\tnew Src is " << *Src <<
"\n");
3185 DEBUG(
dbgs() <<
"\t\tDst is " << *Dst <<
"\n");
3186 Dst = zeroCoefficient(Dst, CurLoop);
3187 DEBUG(
dbgs() <<
"\t\tnew Dst is " << *Dst <<
"\n");
3194 const Constraint &CurConstraint
3196 DEBUG(
dbgs() <<
"\tUpdate direction, constraint =");
3198 if (CurConstraint.isAny())
3200 else if (CurConstraint.isDistance()) {
3203 Level.
Distance = CurConstraint.getD();
3206 NewDirection = Dependence::DVEntry::EQ;
3208 NewDirection |= Dependence::DVEntry::LT;
3210 NewDirection |= Dependence::DVEntry::GT;
3213 else if (CurConstraint.isLine()) {
3218 else if (CurConstraint.isPoint()) {
3223 CurConstraint.getY(),
3224 CurConstraint.getX()))
3228 CurConstraint.getY(),
3229 CurConstraint.getX()))
3233 CurConstraint.getY(),
3234 CurConstraint.getX()))
3247 bool DependenceAnalysis::tryDelinearize(
const SCEV *SrcSCEV,
3248 const SCEV *DstSCEV,
3250 const SCEV *ElementSize) {
3256 if (!SrcBase || !DstBase || SrcBase != DstBase)
3264 if (!SrcAR || !DstAR || !SrcAR->
isAffine() || !DstAR->isAffine())
3282 if (SrcSubscripts.
size() < 2 || DstSubscripts.
size() < 2 ||
3283 SrcSubscripts.
size() != DstSubscripts.
size())
3289 dbgs() <<
"\nSrcSubscripts: ";
3290 for (
int i = 0; i <
size; i++)
3291 dbgs() << *SrcSubscripts[i];
3292 dbgs() <<
"\nDstSubscripts: ";
3293 for (
int i = 0; i <
size; i++)
3294 dbgs() << *DstSubscripts[i];
3302 for (
int i = 0; i <
size; ++i) {
3303 Pair[i].Src = SrcSubscripts[i];
3304 Pair[i].Dst = DstSubscripts[i];
3305 unifySubscriptType(&Pair[i]);
3345 std::unique_ptr<Dependence>
3347 bool PossiblyLoopIndependent) {
3349 PossiblyLoopIndependent =
false;
3358 DEBUG(
dbgs() <<
"can only handle simple loads and stores\n");
3359 return make_unique<Dependence>(Src, Dst);
3370 DEBUG(
dbgs() <<
"can't analyze may or partial alias\n");
3371 return make_unique<Dependence>(Src, Dst);
3381 establishNestingLevels(Src, Dst);
3382 DEBUG(
dbgs() <<
" common nesting levels = " << CommonLevels <<
"\n");
3383 DEBUG(
dbgs() <<
" maximum nesting levels = " << MaxLevels <<
"\n");
3385 FullDependence Result(Src, Dst, PossiblyLoopIndependent, CommonLevels);
3389 bool UsefulGEP =
false;
3392 if (SrcGEP && DstGEP &&
3395 const SCEV *DstPtrSCEV = SE->
getSCEV(DstGEP->getPointerOperand());
3396 DEBUG(
dbgs() <<
" SrcPtrSCEV = " << *SrcPtrSCEV <<
"\n");
3397 DEBUG(
dbgs() <<
" DstPtrSCEV = " << *DstPtrSCEV <<
"\n");
3410 DstIdx = DstGEP->idx_begin();
3412 ++SrcIdx, ++DstIdx, ++
P) {
3413 Pair[
P].Src = SE->
getSCEV(*SrcIdx);
3414 Pair[
P].Dst = SE->
getSCEV(*DstIdx);
3415 unifySubscriptType(&Pair[P]);
3422 DEBUG(
dbgs() <<
" SrcSCEV = " << *SrcSCEV <<
"\n");
3423 DEBUG(
dbgs() <<
" DstSCEV = " << *DstSCEV <<
"\n");
3424 Pair[0].Src = SrcSCEV;
3425 Pair[0].Dst = DstSCEV;
3428 if (
Delinearize && Pairs == 1 && CommonLevels > 1 &&
3429 tryDelinearize(Pair[0].Src, Pair[0].Dst, Pair, SE->
getElementSize(Src))) {
3431 Pairs = Pair.
size();
3434 for (
unsigned P = 0;
P < Pairs; ++
P) {
3435 Pair[
P].Loops.
resize(MaxLevels + 1);
3436 Pair[
P].GroupLoops.
resize(MaxLevels + 1);
3438 removeMatchingExtensions(&Pair[
P]);
3439 Pair[
P].Classification =
3440 classifyPair(Pair[P].Src, LI->
getLoopFor(Src->getParent()),
3441 Pair[P].Dst, LI->
getLoopFor(Dst->getParent()),
3443 Pair[
P].GroupLoops = Pair[
P].Loops;
3444 Pair[
P].Group.set(P);
3445 DEBUG(
dbgs() <<
" subscript " << P <<
"\n");
3446 DEBUG(
dbgs() <<
"\tsrc = " << *Pair[P].Src <<
"\n");
3447 DEBUG(
dbgs() <<
"\tdst = " << *Pair[P].Dst <<
"\n");
3448 DEBUG(
dbgs() <<
"\tclass = " << Pair[P].Classification <<
"\n");
3513 for (
unsigned SI = 0;
SI < Pairs; ++
SI) {
3514 if (Pair[
SI].Classification == Subscript::NonLinear) {
3516 ++NonlinearSubscriptPairs;
3517 collectCommonLoops(Pair[
SI].Src,
3520 collectCommonLoops(Pair[
SI].Dst,
3523 Result.Consistent =
false;
3524 }
else if (Pair[
SI].Classification == Subscript::ZIV) {
3531 for (
unsigned SJ =
SI + 1; SJ < Pairs; ++SJ) {
3533 Intersection &= Pair[SJ].GroupLoops;
3534 if (Intersection.
any()) {
3536 Pair[SJ].GroupLoops |= Pair[
SI].GroupLoops;
3538 Pair[SJ].Group |= Pair[
SI].Group;
3543 if (Pair[
SI].Group.count() == 1) {
3545 ++SeparableSubscriptPairs;
3549 ++CoupledSubscriptPairs;
3560 Constraint NewConstraint;
3561 NewConstraint.setAny(SE);
3566 switch (Pair[
SI].Classification) {
3567 case Subscript::ZIV:
3569 if (testZIV(Pair[
SI].Src, Pair[
SI].Dst, Result))
3572 case Subscript::SIV: {
3575 const SCEV *SplitIter =
nullptr;
3576 if (testSIV(Pair[
SI].Src, Pair[
SI].Dst, Level, Result, NewConstraint,
3581 case Subscript::RDIV:
3583 if (testRDIV(Pair[
SI].Src, Pair[
SI].Dst, Result))
3586 case Subscript::MIV:
3588 if (testMIV(Pair[
SI].Src, Pair[
SI].Dst, Pair[
SI].Loops, Result))
3596 if (Coupled.
count()) {
3598 DEBUG(
dbgs() <<
"starting on coupled subscripts\n");
3599 DEBUG(
dbgs() <<
"MaxLevels + 1 = " << MaxLevels + 1 <<
"\n");
3601 for (
unsigned II = 0; II <= MaxLevels; ++II)
3602 Constraints[II].setAny(SE);
3604 DEBUG(
dbgs() <<
"testing subscript group " <<
SI <<
" { ");
3612 if (Pair[SJ].Classification == Subscript::SIV)
3618 unifySubscriptType(PairsInGroup);
3620 while (Sivs.
any()) {
3621 bool Changed =
false;
3623 DEBUG(
dbgs() <<
"testing subscript " << SJ <<
", SIV\n");
3626 const SCEV *SplitIter =
nullptr;
3628 if (testSIV(Pair[SJ].Src, Pair[SJ].Dst, Level, Result, NewConstraint,
3631 ConstrainedLevels.
set(Level);
3632 if (intersectConstraints(&Constraints[Level], &NewConstraint)) {
3633 if (Constraints[Level].isEmpty()) {
3634 ++DeltaIndependence;
3648 DEBUG(
dbgs() <<
"\tSJ = " << SJ <<
"\n");
3649 if (propagate(Pair[SJ].Src, Pair[SJ].Dst, Pair[SJ].Loops,
3650 Constraints, Result.Consistent)) {
3652 ++DeltaPropagations;
3653 Pair[SJ].Classification =
3654 classifyPair(Pair[SJ].Src, LI->
getLoopFor(Src->getParent()),
3655 Pair[SJ].Dst, LI->
getLoopFor(Dst->getParent()),
3657 switch (Pair[SJ].Classification) {
3658 case Subscript::ZIV:
3660 if (testZIV(Pair[SJ].Src, Pair[SJ].Dst, Result))
3664 case Subscript::SIV:
3668 case Subscript::RDIV:
3669 case Subscript::MIV:
3681 if (Pair[SJ].Classification == Subscript::RDIV) {
3683 if (testRDIV(Pair[SJ].Src, Pair[SJ].Dst, Result))
3694 if (Pair[SJ].Classification == Subscript::MIV) {
3696 if (testMIV(Pair[SJ].Src, Pair[SJ].Dst, Pair[SJ].Loops, Result))
3705 for (
int SJ = ConstrainedLevels.
find_first(); SJ >= 0;
3707 if (SJ > (
int)CommonLevels)
3709 updateDirection(Result.DV[SJ - 1], Constraints[SJ]);
3718 for (
unsigned SI = 0;
SI < Pairs; ++
SI)
3719 CompleteLoops |= Pair[
SI].Loops;
3720 for (
unsigned II = 1; II <= CommonLevels; ++II)
3721 if (CompleteLoops[II])
3722 Result.DV[II - 1].
Scalar =
false;
3724 if (PossiblyLoopIndependent) {
3728 for (
unsigned II = 1; II <= CommonLevels; ++II) {
3730 Result.LoopIndependent =
false;
3738 bool AllEqual =
true;
3739 for (
unsigned II = 1; II <= CommonLevels; ++II) {
3749 auto Final = make_unique<FullDependence>(Result);
3750 Result.DV =
nullptr;
3751 return std::move(Final);
3804 unsigned SplitLevel) {
3806 "Dep should be splitable at SplitLevel");
3809 assert(Src->mayReadFromMemory() || Src->mayWriteToMemory());
3819 establishNestingLevels(Src, Dst);
3824 bool UsefulGEP =
false;
3827 if (SrcGEP && DstGEP &&
3830 const SCEV *DstPtrSCEV = SE->
getSCEV(DstGEP->getPointerOperand());
3841 DstIdx = DstGEP->idx_begin();
3843 ++SrcIdx, ++DstIdx, ++
P) {
3844 Pair[
P].Src = SE->
getSCEV(*SrcIdx);
3845 Pair[
P].Dst = SE->
getSCEV(*DstIdx);
3851 Pair[0].Src = SrcSCEV;
3852 Pair[0].Dst = DstSCEV;
3855 if (
Delinearize && Pairs == 1 && CommonLevels > 1 &&
3856 tryDelinearize(Pair[0].Src, Pair[0].Dst, Pair, SE->
getElementSize(Src))) {
3858 Pairs = Pair.
size();
3861 for (
unsigned P = 0;
P < Pairs; ++
P) {
3862 Pair[
P].Loops.
resize(MaxLevels + 1);
3863 Pair[
P].GroupLoops.
resize(MaxLevels + 1);
3865 removeMatchingExtensions(&Pair[
P]);
3866 Pair[
P].Classification =
3867 classifyPair(Pair[P].Src, LI->
getLoopFor(Src->getParent()),
3868 Pair[P].Dst, LI->
getLoopFor(Dst->getParent()),
3870 Pair[
P].GroupLoops = Pair[
P].Loops;
3871 Pair[
P].Group.set(P);
3878 for (
unsigned SI = 0;
SI < Pairs; ++
SI) {
3879 if (Pair[
SI].Classification == Subscript::NonLinear) {
3881 collectCommonLoops(Pair[
SI].Src,
3884 collectCommonLoops(Pair[
SI].Dst,
3887 Result.Consistent =
false;
3889 else if (Pair[
SI].Classification == Subscript::ZIV)
3894 for (
unsigned SJ =
SI + 1; SJ < Pairs; ++SJ) {
3896 Intersection &= Pair[SJ].GroupLoops;
3897 if (Intersection.
any()) {
3899 Pair[SJ].GroupLoops |= Pair[
SI].GroupLoops;
3901 Pair[SJ].Group |= Pair[
SI].Group;
3906 if (Pair[
SI].Group.count() == 1)
3914 Constraint NewConstraint;
3915 NewConstraint.setAny(SE);
3919 switch (Pair[
SI].Classification) {
3920 case Subscript::SIV: {
3922 const SCEV *SplitIter =
nullptr;
3923 (void) testSIV(Pair[
SI].Src, Pair[
SI].Dst, Level,
3924 Result, NewConstraint, SplitIter);
3925 if (Level == SplitLevel) {
3926 assert(SplitIter !=
nullptr);
3931 case Subscript::ZIV:
3932 case Subscript::RDIV:
3933 case Subscript::MIV:
3940 if (Coupled.
count()) {
3943 for (
unsigned II = 0; II <= MaxLevels; ++II)
3944 Constraints[II].setAny(SE);
3951 if (Pair[SJ].Classification == Subscript::SIV)
3956 while (Sivs.
any()) {
3957 bool Changed =
false;
3961 const SCEV *SplitIter =
nullptr;
3962 (void) testSIV(Pair[SJ].Src, Pair[SJ].Dst, Level,
3963 Result, NewConstraint, SplitIter);
3964 if (Level == SplitLevel && SplitIter)
3966 ConstrainedLevels.
set(Level);
3967 if (intersectConstraints(&Constraints[Level], &NewConstraint))
3975 if (propagate(Pair[SJ].Src, Pair[SJ].Dst,
3976 Pair[SJ].Loops, Constraints, Result.Consistent)) {
3977 Pair[SJ].Classification =
3978 classifyPair(Pair[SJ].Src, LI->
getLoopFor(Src->getParent()),
3979 Pair[SJ].Dst, LI->
getLoopFor(Dst->getParent()),
3981 switch (Pair[SJ].Classification) {
3982 case Subscript::ZIV:
3985 case Subscript::SIV:
3989 case Subscript::RDIV:
3990 case Subscript::MIV:
NoWrapFlags getNoWrapFlags(NoWrapFlags Mask=NoWrapMask) const
The two locations precisely alias each other.
void print(raw_ostream &, const Module *=nullptr) const override
print - Print out the internal state of the pass.
void push_back(const T &Elt)
const SCEV * getDistance(unsigned Level) const override
getDistance - Returns the distance (or NULL) associated with a particular level.
A parsed version of the target data layout string in and methods for querying it. ...
unsigned getLoopDepth(const BlockT *BB) const
getLoopDepth - Return the loop nesting level of the specified block.
APInt LLVM_ATTRIBUTE_UNUSED_RESULT abs() const
Get the absolute value;.
size_type count() const
count - Returns the number of bits which are set.
bool isAnti() const
isAnti - Returns true if this is an anti dependence.
INITIALIZE_PASS_BEGIN(DependenceAnalysis,"da","Dependence Analysis", true, true) INITIALIZE_PASS_END(DependenceAnalysis
virtual bool isConfused() const
isConfused - Returns true if this dependence is confused (the compiler understands nothing and makes ...
static bool isLoopInvariant(Value *V, const Loop *L, const DominatorTree *DT)
isLoopInvariant - Perform a quick domtree based check for loop invariance assuming that V is used wit...
bool isOne() const
isOne - Return true if the expression is a constant one.
SmallBitVector - This is a 'bitvector' (really, a variable-sized bit array), optimized for the case w...
const SCEV * getConstant(ConstantInt *V)
STATISTIC(NumFunctions,"Total number of functions")
DependenceAnalysis - This class is the main dependence-analysis driver.
APInt GreatestCommonDivisor(const APInt &Val1, const APInt &Val2)
Compute GCD of two APInt values.
A Module instance is used to store all the information related to an LLVM module. ...
virtual bool isPeelFirst(unsigned Level) const
isPeelFirst - Returns true if peeling the first iteration from this loop will break this dependence...
bool isZero() const
isZero - Return true if the expression is a constant zero.
FunctionPass * createDependenceAnalysisPass()
createDependenceAnalysisPass - This creates an instance of the DependenceAnalysis pass...
unsigned getNumOperands() const
The two locations alias, but only due to a partial overlap.
const SCEV * getPointerBase(const SCEV *V)
getPointerBase - Transitively follow the chain of pointer-type operands until reaching a SCEV that do...
ScalarEvolution - This class is the main scalar evolution driver.
bool isKnownNonNegative(const SCEV *S)
isKnownNonNegative - Test if the given expression is known to be non-negative.
static APInt ceilingOfQuotient(APInt A, APInt B)
static void dumpExampleDependence(raw_ostream &OS, Function *F, DependenceAnalysis *DA)
static void sdivrem(const APInt &LHS, const APInt &RHS, APInt &Quotient, APInt &Remainder)
const SCEV * getStepRecurrence(ScalarEvolution &SE) const
getStepRecurrence - This method constructs and returns the recurrence indicating how much this expres...
static Value * getPointerOperand(Instruction *I)
static void dumpSmallBitVector(SmallBitVector &BV)
bool isLoopInvariant(const SCEV *S, const Loop *L)
isLoopInvariant - Return true if the value of the given SCEV is unchanging in the specified loop...
LoopT * getParentLoop() const
The two locations do not alias at all.
LoadInst - an instruction for reading from memory.
unsigned getBitWidth() const
Get the number of bits in this IntegerType.
LoopT * getLoopFor(const BlockT *BB) const
getLoopFor - Return the inner most loop that BB lives in.
static APInt getSignedMaxValue(unsigned numBits)
Gets maximum signed value of APInt for a specific bit width.
The two locations may or may not alias. This is the least precise result.
SCEVCastExpr - This is the base class for unary cast operator classes.
const SCEV * getStart() const
bool isKnownNonPositive(const SCEV *S)
isKnownNonPositive - Test if the given expression is known to be non-positive.
Type * getPointerOperandType() const
Method to return the pointer operand as a PointerType.
#define INITIALIZE_PASS_DEPENDENCY(depName)
void computeAccessFunctions(const SCEV *Expr, SmallVectorImpl< const SCEV * > &Subscripts, SmallVectorImpl< const SCEV * > &Sizes)
Return in Subscripts the access functions for each dimension in Sizes.
void getAnalysisUsage(AnalysisUsage &) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
inst_iterator inst_begin(Function *F)
bool isPeelLast(unsigned Level) const override
isPeelLast - Returns true if peeling the last iteration from this loop will break this dependence...
const APInt & getValue() const
Return the constant as an APInt value reference.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
A Use represents the edge between a Value definition and its users.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
static bool findGCD(unsigned Bits, APInt AM, APInt BM, APInt Delta, APInt &G, APInt &X, APInt &Y)
uint64_t getTypeSizeInBits(Type *Ty) const
getTypeSizeInBits - Return the size in bits of the specified type, for which isSCEVable must return t...
int find_first() const
find_first - Returns the index of the first set bit, -1 if none of the bits are set.
virtual bool isSplitable(unsigned Level) const
isSplitable - Returns true if splitting this loop will break the dependence.
SCEVMulExpr - This node represents multiplication of some number of SCEVs.
bool isKnownPredicate(ICmpInst::Predicate Pred, const SCEV *LHS, const SCEV *RHS)
isKnownPredicate - Test if the given expression is known to satisfy the condition described by Pred...
bool mayReadFromMemory() const
mayReadFromMemory - Return true if this instruction may read memory.
SCEVAddRecExpr - This node represents a polynomial recurrence on the trip count of the specified loop...
bool sgt(const APInt &RHS) const
Signed greather than comparison.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
uint64_t getTypeStoreSize(Type *Ty)
getTypeStoreSize - Return the DataLayout store size for the given type, if known, or a conservative v...
static cl::opt< bool > Delinearize("da-delinearize", cl::init(false), cl::Hidden, cl::ZeroOrMore, cl::desc("Try to delinearize array references."))
static const SCEVConstant * getConstantPart(const SCEVMulExpr *Product)
StoreInst - an instruction for storing to memory.
const SCEV * getAddRecExpr(const SCEV *Start, const SCEV *Step, const Loop *L, SCEV::NoWrapFlags Flags)
getAddRecExpr - Get an add recurrence expression for the specified loop.
size_t size() const
size - Get the array size.
size_t getNumOperands() const
void releaseMemory() override
releaseMemory() - This member can be implemented by a pass if it wants to be able to release its memo...
unsigned getDirection(unsigned Level) const override
getDirection - Returns the direction associated with a particular level.
SCEVUnknown - This means that we are dealing with an entirely unknown SCEV value, and only represent ...
initializer< Ty > init(const Ty &Val)
bool runOnFunction(Function &F) override
runOnFunction - Virtual method overriden by subclasses to do the per-function processing of the pass...
bool isAffine() const
isAffine - Return true if this represents an expression A + B*x where A and B are loop invariant valu...
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
* if(!EatIfPresent(lltok::kw_thread_local)) return false
ParseOptionalThreadLocal := /*empty.
LLVM Basic Block Representation.
The instances of the Type class are immutable: once they are created, they are never changed...
Type * getType() const
getType - Return the LLVM type of this SCEV expression.
This is an important base class in LLVM.
virtual bool isScalar(unsigned Level) const
isScalar - Returns true if a particular level is scalar; that is, if no subscript in the source or de...
const SCEV * getOperand(unsigned i) const
static bool isLoadOrStore(const Instruction *I)
bool isSplitable(unsigned Level) const override
isSplitable - Returns true if splitting the loop will break the dependence.
bool isFlow() const
isFlow - Returns true if this is a flow (aka true) dependence.
const SCEV * getSMaxExpr(const SCEV *LHS, const SCEV *RHS)
AliasResult
The possible results of an alias query.
Represent the analysis usage information of a pass.
static AliasResult underlyingObjectsAlias(AliasAnalysis *AA, const DataLayout &DL, const Value *A, const Value *B)
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang","erlang-compatible garbage collector")
const SCEV * getMinusSCEV(const SCEV *LHS, const SCEV *RHS, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap)
getMinusSCEV - Return LHS-RHS. Minus is represented in SCEV as A+B*-1.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
unsigned getBitWidth() const
Return the number of bits in the APInt.
int find_next(unsigned Prev) const
find_next - Returns the index of the next set bit following the "Prev" bit.
Value * getPointerOperand()
FunctionPass class - This class is used to implement most global optimizations.
APInt LLVM_ATTRIBUTE_UNUSED_RESULT sdiv(const APInt &RHS) const
Signed division function for APInt.
bool isPeelFirst(unsigned Level) const override
isPeelFirst - Returns true if peeling the first iteration from this loop will break this dependence...
Class to represent integer types.
virtual const SCEV * getDistance(unsigned Level) const
getDistance - Returns the distance (or NULL) associated with a particular level.
bool isKnownNegative(const SCEV *S)
isKnownNegative - Test if the given expression is known to be negative.
Instruction * getSrc() const
getSrc - Returns the source instruction for this dependence.
static APInt minAPInt(APInt A, APInt B)
#define INITIALIZE_AG_DEPENDENCY(depName)
void findArrayDimensions(SmallVectorImpl< const SCEV * > &Terms, SmallVectorImpl< const SCEV * > &Sizes, const SCEV *ElementSize) const
Compute the array dimensions Sizes from the set of Terms extracted from the memory access function of...
virtual unsigned getDirection(unsigned Level) const
getDirection - Returns the direction associated with a particular level.
Value * GetUnderlyingObject(Value *V, const DataLayout &DL, unsigned MaxLookup=6)
GetUnderlyingObject - This method strips off any GEP address adjustments and pointer casts from the s...
virtual bool isConsistent() const
isConsistent - Returns true if this dependence is consistent (occurs every time the source and destin...
bool mayWriteToMemory() const
mayWriteToMemory - Return true if this instruction may modify memory.
APInt LLVM_ATTRIBUTE_UNUSED_RESULT srem(const APInt &RHS) const
Function for signed remainder operation.
const SCEV * getSMinExpr(const SCEV *LHS, const SCEV *RHS)
bool isKnownPositive(const SCEV *S)
isKnownPositive - Test if the given expression is known to be positive.
bool slt(const APInt &RHS) const
Signed less than comparison.
virtual AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB)
Alias Queries...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Module.h This file contains the declarations for the Module class.
Type * getType() const
All values are typed, get the type of this value.
static APInt floorOfQuotient(APInt A, APInt B)
const SCEV * getSplitIteration(const Dependence &Dep, unsigned Level)
getSplitIteration - Give a dependence that's splittable at some particular level, return the iteratio...
virtual unsigned getLevels() const
getLevels - Returns the number of common loops surrounding the source and destination of the dependen...
ConstantInt * getValue() const
virtual bool isPeelLast(unsigned Level) const
isPeelLast - Returns true if peeling the last iteration from this loop will break this dependence...
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Class for arbitrary precision integers.
SCEVAddExpr - This node represents an addition of some number of SCEVs.
const SCEV * getSignExtendExpr(const SCEV *Op, Type *Ty)
FullDependence(Instruction *Src, Instruction *Dst, bool LoopIndependent, unsigned Levels)
void setPreservesAll()
Set by analyses that do not transform their input at all.
LLVM_ATTRIBUTE_UNUSED_RESULT std::enable_if< !is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
const SCEV * getAddExpr(SmallVectorImpl< const SCEV * > &Ops, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap)
getAddExpr - Get a canonical add expression, or something simpler if possible.
bool isScalar(unsigned Level) const override
isScalar - Returns true if a particular level is scalar; that is, if no subscript in the source or de...
static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT, AssumptionCache *AC)
void collectParametricTerms(const SCEV *Expr, SmallVectorImpl< const SCEV * > &Terms)
Collect parametric terms occurring in step expressions.
SCEV - This class represents an analyzed expression in the program.
virtual bool isLoopIndependent() const
isLoopIndependent - Returns true if this is a loop-independent dependence.
Instruction * getDst() const
getDst - Returns the destination instruction for this dependence.
void dump(raw_ostream &OS) const
dump - For debugging purposes, dumps a dependence to OS.
bool isKnownNonZero(const SCEV *S)
isKnownNonZero - Test if the given expression is known to be non-zero.
FullDependence - This class represents a dependence between two memory references in a function...
static bool isRemainderZero(const SCEVConstant *Dividend, const SCEVConstant *Divisor)
AnalysisUsage & addRequiredTransitive()
const Loop * getLoop() const
Dependence::DVEntry - Each level in the distance/direction vector has a direction (or perhaps a union...
static APInt maxAPInt(APInt A, APInt B)
bool isInput() const
isInput - Returns true if this is an input dependence.
const SCEV * getBackedgeTakenCount(const Loop *L)
getBackedgeTakenCount - If the specified loop has a predictable backedge-taken count, return it, otherwise return a SCEVCouldNotCompute object.
const ARM::ArchExtKind Kind
static APInt getSignedMinValue(unsigned numBits)
Gets minimum signed value of APInt for a specific bit width.
LLVM Value Representation.
bool any() const
any - Returns true if any bit is set.
const SCEV * getSCEV(Value *V)
getSCEV - Return a SCEV expression for the full generality of the specified expression.
This class implements an extremely fast bulk output stream that can only output to a stream...
std::unique_ptr< Dependence > depends(Instruction *Src, Instruction *Dst, bool PossiblyLoopIndependent)
depends - Tests for a dependence between the Src and Dst instructions.
const SCEV * getUDivExpr(const SCEV *LHS, const SCEV *RHS)
getUDivExpr - Get a canonical unsigned division expression, or something simpler if possible...
The legacy pass manager's analysis pass to compute loop information.
C - The default llvm calling convention, compatible with C.
inst_iterator inst_end(Function *F)
bool isOutput() const
isOutput - Returns true if this is an output dependence.
const SCEV * getTruncateOrZeroExtend(const SCEV *V, Type *Ty)
getTruncateOrZeroExtend - Return a SCEV corresponding to a conversion of the input value to the speci...
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml","ocaml 3.10-compatible collector")
const SCEV * getNegativeSCEV(const SCEV *V)
getNegativeSCEV - Return the SCEV object corresponding to -V.
const SCEV * getElementSize(Instruction *Inst)
Return the size of an element read or written by Inst.
static APInt getNullValue(unsigned numBits)
Get the '0' value.
Dependence - This class represents a dependence between two memory memory references in a function...
const SCEV * getOperand() const
unsigned getLoopDepth() const
getLoopDepth - Return the nesting level of this loop.
const SCEV * getMulExpr(SmallVectorImpl< const SCEV * > &Ops, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap)
getMulExpr - Get a canonical multiply expression, or something simpler if possible.
bool hasLoopInvariantBackedgeTakenCount(const Loop *L)
hasLoopInvariantBackedgeTakenCount - Return true if the specified loop has an analyzable loop-invaria...
const BasicBlock * getParent() const
SCEVConstant - This class represents a constant integer value.