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."));
128 "Dependence Analysis",
true,
true)
135 char DependenceAnalysisWrapperPass::
ID = 0;
138 return new DependenceAnalysisWrapperPass();
142 auto &AA = getAnalysis<AAResultsWrapperPass>().getAAResults();
143 auto &SE = getAnalysis<ScalarEvolutionWrapperPass>().getSE();
144 auto &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
169 if (isa<StoreInst>(*SrcI) || isa<LoadInst>(*SrcI)) {
171 DstI != DstE; ++DstI) {
172 if (isa<StoreInst>(*DstI) || isa<LoadInst>(*DstI)) {
173 OS <<
"da analyze - ";
174 if (
auto D = DA->
depends(&*SrcI, &*DstI,
true)) {
177 if (
D->isSplitable(
Level)) {
178 OS <<
"da analyze - split level = " <<
Level;
237 bool PossiblyLoopIndependent,
238 unsigned CommonLevels)
239 :
Dependence(Source, Destination), Levels(CommonLevels),
240 LoopIndependent(PossiblyLoopIndependent) {
243 DV = make_unique<DVEntry[]>(CommonLevels);
250 assert(0 < Level && Level <= Levels &&
"Level out of range");
251 return DV[Level - 1].Direction;
257 assert(0 < Level && Level <= Levels &&
"Level out of range");
258 return DV[Level - 1].Distance;
266 assert(0 < Level && Level <= Levels &&
"Level out of range");
267 return DV[Level - 1].Scalar;
274 assert(0 < Level && Level <= Levels &&
"Level out of range");
275 return DV[Level - 1].PeelFirst;
282 assert(0 < Level && Level <= Levels &&
"Level out of range");
283 return DV[Level - 1].PeelLast;
289 assert(0 < Level && Level <= Levels &&
"Level out of range");
290 return DV[Level - 1].Splitable;
299 const SCEV *DependenceInfo::Constraint::getX()
const {
300 assert(
Kind == Point &&
"Kind should be Point");
307 const SCEV *DependenceInfo::Constraint::getY()
const {
308 assert(
Kind == Point &&
"Kind should be Point");
315 const SCEV *DependenceInfo::Constraint::getA()
const {
317 "Kind should be Line (or Distance)");
324 const SCEV *DependenceInfo::Constraint::getB()
const {
326 "Kind should be Line (or Distance)");
333 const SCEV *DependenceInfo::Constraint::getC()
const {
335 "Kind should be Line (or Distance)");
342 const SCEV *DependenceInfo::Constraint::getD()
const {
343 assert(
Kind == Distance &&
"Kind should be Distance");
344 return SE->getNegativeSCEV(
C);
349 const Loop *DependenceInfo::Constraint::getAssociatedLoop()
const {
351 "Kind should be Distance, Line, or Point");
352 return AssociatedLoop;
355 void DependenceInfo::Constraint::setPoint(
const SCEV *
X,
const SCEV *
Y,
356 const Loop *CurLoop) {
360 AssociatedLoop = CurLoop;
363 void DependenceInfo::Constraint::setLine(
const SCEV *AA,
const SCEV *BB,
364 const SCEV *CC,
const Loop *CurLoop) {
369 AssociatedLoop = CurLoop;
372 void DependenceInfo::Constraint::setDistance(
const SCEV *
D,
373 const Loop *CurLoop) {
376 B = SE->getNegativeSCEV(
A);
377 C = SE->getNegativeSCEV(D);
378 AssociatedLoop = CurLoop;
381 void DependenceInfo::Constraint::setEmpty() {
Kind =
Empty; }
396 OS <<
" Point is <" << *getX() <<
", " << *getY() <<
">\n";
397 else if (isDistance())
398 OS <<
" Distance is " << *getD() <<
399 " (" << *getA() <<
"*X + " << *getB() <<
"*Y = " << *getC() <<
")\n";
401 OS <<
" Line is " << *getA() <<
"*X + " <<
402 *getB() <<
"*Y = " << *getC() <<
"\n";
415 bool DependenceInfo::intersectConstraints(Constraint *
X,
const Constraint *
Y) {
417 DEBUG(
dbgs() <<
"\tintersect constraints\n");
420 assert(!Y->isPoint() &&
"Y must not be a Point");
434 if (X->isDistance() && Y->isDistance()) {
435 DEBUG(
dbgs() <<
"\t intersect 2 distances\n");
445 if (isa<SCEVConstant>(Y->getD())) {
458 assert(!(X->isPoint() && Y->isPoint()) &&
459 "We shouldn't ever see X->isPoint() && Y->isPoint()");
461 if (X->isLine() && Y->isLine()) {
462 DEBUG(
dbgs() <<
"\t intersect 2 lines\n");
481 DEBUG(
dbgs() <<
"\t\tdifferent slopes\n");
496 if (!C1B2_C2B1 || !C1A2_C2A1 ||
497 !A1B2_A2B1 || !A2B1_A1B2)
499 APInt Xtop = C1B2_C2B1->getAPInt();
500 APInt Xbot = A1B2_A2B1->getAPInt();
502 APInt Ybot = A2B1_A1B2->getAPInt();
503 DEBUG(
dbgs() <<
"\t\tXtop = " << Xtop <<
"\n");
504 DEBUG(
dbgs() <<
"\t\tXbot = " << Xbot <<
"\n");
505 DEBUG(
dbgs() <<
"\t\tYtop = " << Ytop <<
"\n");
506 DEBUG(
dbgs() <<
"\t\tYbot = " << Ybot <<
"\n");
513 if (Xr != 0 || Yr != 0) {
518 DEBUG(
dbgs() <<
"\t\tX = " << Xq <<
", Y = " << Yq <<
"\n");
519 if (Xq.
slt(0) || Yq.
slt(0)) {
525 collectConstantUpperBound(X->getAssociatedLoop(), Prod1->
getType())) {
526 const APInt &UpperBound = CUB->getAPInt();
527 DEBUG(
dbgs() <<
"\t\tupper bound = " << UpperBound <<
"\n");
528 if (Xq.
sgt(UpperBound) || Yq.
sgt(UpperBound)) {
536 X->getAssociatedLoop());
544 assert(!(X->isLine() && Y->isPoint()) &&
"This case should never occur");
546 if (X->isPoint() && Y->isLine()) {
547 DEBUG(
dbgs() <<
"\t intersect Point and Line\n");
571 bool Splitable =
false;
587 for (
unsigned II = 1; II <= Levels; ++II) {
638 if (
const LoadInst *LI = dyn_cast<LoadInst>(I))
639 return LI->isUnordered();
640 else if (
const StoreInst *
SI = dyn_cast<StoreInst>(I))
641 return SI->isUnordered();
648 if (
LoadInst *LI = dyn_cast<LoadInst>(I))
649 return LI->getPointerOperand();
651 return SI->getPointerOperand();
707 void DependenceInfo::establishNestingLevels(
const Instruction *Src,
715 SrcLevels = SrcLevel;
716 MaxLevels = SrcLevel + DstLevel;
717 while (SrcLevel > DstLevel) {
721 while (DstLevel > SrcLevel) {
725 while (SrcLoop != DstLoop) {
730 CommonLevels = SrcLevel;
731 MaxLevels -= CommonLevels;
737 unsigned DependenceInfo::mapSrcLoop(
const Loop *SrcLoop)
const {
744 unsigned DependenceInfo::mapDstLoop(
const Loop *DstLoop)
const {
746 if (D > CommonLevels)
747 return D - CommonLevels + SrcLevels;
754 bool DependenceInfo::isLoopInvariant(
const SCEV *Expression,
755 const Loop *LoopNest)
const {
766 void DependenceInfo::collectCommonLoops(
const SCEV *Expression,
767 const Loop *LoopNest,
771 if (Level <= CommonLevels && !SE->isLoopInvariant(Expression, LoopNest))
779 unsigned widestWidthSeen = 0;
784 for (Subscript *Pair : Pairs) {
785 const SCEV *Src = Pair->Src;
786 const SCEV *Dst = Pair->Dst;
789 if (SrcTy ==
nullptr || DstTy ==
nullptr) {
790 assert(SrcTy == DstTy &&
"This function only unify integer types and "
791 "expect Src and Dst share the same type "
799 if (DstTy->getBitWidth() > widestWidthSeen) {
800 widestWidthSeen = DstTy->getBitWidth();
806 assert(widestWidthSeen > 0);
809 for (Subscript *Pair : Pairs) {
810 const SCEV *Src = Pair->Src;
811 const SCEV *Dst = Pair->Dst;
814 if (SrcTy ==
nullptr || DstTy ==
nullptr) {
815 assert(SrcTy == DstTy &&
"This function only unify integer types and "
816 "expect Src and Dst share the same type "
823 if (DstTy->getBitWidth() < widestWidthSeen) {
834 void DependenceInfo::removeMatchingExtensions(Subscript *Pair) {
835 const SCEV *Src = Pair->Src;
836 const SCEV *Dst = Pair->Dst;
837 if ((isa<SCEVZeroExtendExpr>(Src) && isa<SCEVZeroExtendExpr>(Dst)) ||
838 (isa<SCEVSignExtendExpr>(Src) && isa<SCEVSignExtendExpr>(Dst))) {
842 const SCEV *DstCastOp = DstCast->getOperand();
843 if (SrcCastOp->getType() == DstCastOp->
getType()) {
844 Pair->Src = SrcCastOp;
845 Pair->Dst = DstCastOp;
853 bool DependenceInfo::checkSrcSubscript(
const SCEV *Src,
const Loop *LoopNest,
857 return isLoopInvariant(Src, LoopNest);
861 if (!isa<SCEVCouldNotCompute>(UB)) {
868 if (!isLoopInvariant(Step, LoopNest))
871 return checkSrcSubscript(Start, LoopNest, Loops);
878 bool DependenceInfo::checkDstSubscript(
const SCEV *Dst,
const Loop *LoopNest,
882 return isLoopInvariant(Dst, LoopNest);
886 if (!isa<SCEVCouldNotCompute>(UB)) {
893 if (!isLoopInvariant(Step, LoopNest))
896 return checkDstSubscript(Start, LoopNest, Loops);
903 DependenceInfo::Subscript::ClassificationKind
904 DependenceInfo::classifyPair(
const SCEV *Src,
const Loop *SrcLoopNest,
905 const SCEV *Dst,
const Loop *DstLoopNest,
909 if (!checkSrcSubscript(Src, SrcLoopNest, SrcLoops))
910 return Subscript::NonLinear;
911 if (!checkDstSubscript(Dst, DstLoopNest, DstLoops))
912 return Subscript::NonLinear;
915 unsigned N = Loops.
count();
917 return Subscript::ZIV;
919 return Subscript::SIV;
920 if (N == 2 && (SrcLoops.count() == 0 ||
921 DstLoops.count() == 0 ||
922 (SrcLoops.count() == 1 && DstLoops.count() == 1)))
923 return Subscript::RDIV;
924 return Subscript::MIV;
939 const SCEV *Y)
const {
942 if ((isa<SCEVSignExtendExpr>(X) &&
943 isa<SCEVSignExtendExpr>(Y)) ||
944 (isa<SCEVZeroExtendExpr>(X) &&
945 isa<SCEVZeroExtendExpr>(Y))) {
949 const SCEV *Yop = CY->getOperand();
950 if (Xop->getType() == Yop->
getType()) {
990 const SCEV *DependenceInfo::collectUpperBound(
const Loop *
L,
Type *
T)
const {
1001 const SCEVConstant *DependenceInfo::collectConstantUpperBound(
const Loop *L,
1003 if (
const SCEV *UB = collectUpperBound(L, T))
1019 bool DependenceInfo::testZIV(
const SCEV *Src,
const SCEV *Dst,
1021 DEBUG(
dbgs() <<
" src = " << *Src <<
"\n");
1022 DEBUG(
dbgs() <<
" dst = " << *Dst <<
"\n");
1025 DEBUG(
dbgs() <<
" provably dependent\n");
1029 DEBUG(
dbgs() <<
" provably independent\n");
1033 DEBUG(
dbgs() <<
" possibly dependent\n");
1034 Result.Consistent =
false;
1066 bool DependenceInfo::strongSIVtest(
const SCEV *Coeff,
const SCEV *SrcConst,
1067 const SCEV *DstConst,
const Loop *CurLoop,
1069 Constraint &NewConstraint)
const {
1071 DEBUG(
dbgs() <<
"\t Coeff = " << *Coeff);
1073 DEBUG(
dbgs() <<
"\t SrcConst = " << *SrcConst);
1075 DEBUG(
dbgs() <<
"\t DstConst = " << *DstConst);
1077 ++StrongSIVapplications;
1078 assert(0 < Level && Level <= CommonLevels &&
"level out of range");
1082 DEBUG(
dbgs() <<
"\t Delta = " << *Delta);
1086 if (
const SCEV *UpperBound = collectUpperBound(CurLoop, Delta->
getType())) {
1087 DEBUG(
dbgs() <<
"\t UpperBound = " << *UpperBound);
1088 DEBUG(
dbgs() <<
", " << *UpperBound->getType() <<
"\n");
1089 const SCEV *AbsDelta =
1091 const SCEV *AbsCoeff =
1096 ++StrongSIVindependence;
1097 ++StrongSIVsuccesses;
1103 if (isa<SCEVConstant>(Delta) && isa<SCEVConstant>(Coeff)) {
1104 APInt ConstDelta = cast<SCEVConstant>(Delta)->getAPInt();
1105 APInt ConstCoeff = cast<SCEVConstant>(Coeff)->getAPInt();
1106 APInt Distance = ConstDelta;
1107 APInt Remainder = ConstDelta;
1109 DEBUG(
dbgs() <<
"\t Distance = " << Distance <<
"\n");
1110 DEBUG(
dbgs() <<
"\t Remainder = " << Remainder <<
"\n");
1112 if (Remainder != 0) {
1114 ++StrongSIVindependence;
1115 ++StrongSIVsuccesses;
1119 NewConstraint.setDistance(SE->
getConstant(Distance), CurLoop);
1120 if (Distance.
sgt(0))
1122 else if (Distance.
slt(0))
1126 ++StrongSIVsuccesses;
1128 else if (Delta->
isZero()) {
1130 Result.DV[
Level].Distance = Delta;
1131 NewConstraint.setDistance(Delta, CurLoop);
1133 ++StrongSIVsuccesses;
1136 if (Coeff->
isOne()) {
1137 DEBUG(
dbgs() <<
"\t Distance = " << *Delta <<
"\n");
1138 Result.DV[
Level].Distance = Delta;
1139 NewConstraint.setDistance(Delta, CurLoop);
1142 Result.Consistent =
false;
1143 NewConstraint.setLine(Coeff,
1158 if ((DeltaMaybePositive && CoeffMaybePositive) ||
1159 (DeltaMaybeNegative && CoeffMaybeNegative))
1163 if ((DeltaMaybeNegative && CoeffMaybePositive) ||
1164 (DeltaMaybePositive && CoeffMaybeNegative))
1166 if (NewDirection < Result.DV[Level].Direction)
1167 ++StrongSIVsuccesses;
1168 Result.DV[
Level].Direction &= NewDirection;
1202 bool DependenceInfo::weakCrossingSIVtest(
1203 const SCEV *Coeff,
const SCEV *SrcConst,
const SCEV *DstConst,
1205 Constraint &NewConstraint,
const SCEV *&SplitIter)
const {
1206 DEBUG(
dbgs() <<
"\tWeak-Crossing SIV test\n");
1207 DEBUG(
dbgs() <<
"\t Coeff = " << *Coeff <<
"\n");
1208 DEBUG(
dbgs() <<
"\t SrcConst = " << *SrcConst <<
"\n");
1209 DEBUG(
dbgs() <<
"\t DstConst = " << *DstConst <<
"\n");
1210 ++WeakCrossingSIVapplications;
1211 assert(0 < Level && Level <= CommonLevels &&
"Level out of range");
1213 Result.Consistent =
false;
1215 DEBUG(
dbgs() <<
"\t Delta = " << *Delta <<
"\n");
1216 NewConstraint.setLine(Coeff, Coeff, Delta, CurLoop);
1220 ++WeakCrossingSIVsuccesses;
1221 if (!Result.DV[Level].Direction) {
1222 ++WeakCrossingSIVindependence;
1225 Result.DV[
Level].Distance = Delta;
1232 Result.DV[
Level].Splitable =
true;
1236 "dynamic cast of negative of ConstCoeff should yield constant");
1245 DEBUG(
dbgs() <<
"\t Split iter = " << *SplitIter <<
"\n");
1253 DEBUG(
dbgs() <<
"\t Delta = " << *Delta <<
"\n");
1254 DEBUG(
dbgs() <<
"\t ConstCoeff = " << *ConstCoeff <<
"\n");
1257 ++WeakCrossingSIVindependence;
1258 ++WeakCrossingSIVsuccesses;
1264 if (
const SCEV *UpperBound = collectUpperBound(CurLoop, Delta->
getType())) {
1265 DEBUG(
dbgs() <<
"\t UpperBound = " << *UpperBound <<
"\n");
1269 DEBUG(
dbgs() <<
"\t ML = " << *ML <<
"\n");
1272 ++WeakCrossingSIVindependence;
1273 ++WeakCrossingSIVsuccesses;
1280 ++WeakCrossingSIVsuccesses;
1281 if (!Result.DV[Level].Direction) {
1282 ++WeakCrossingSIVindependence;
1285 Result.DV[
Level].Splitable =
false;
1294 APInt Distance = APDelta;
1295 APInt Remainder = APDelta;
1297 DEBUG(
dbgs() <<
"\t Remainder = " << Remainder <<
"\n");
1298 if (Remainder != 0) {
1300 ++WeakCrossingSIVindependence;
1301 ++WeakCrossingSIVsuccesses;
1304 DEBUG(
dbgs() <<
"\t Distance = " << Distance <<
"\n");
1308 Remainder = Distance.
srem(Two);
1309 DEBUG(
dbgs() <<
"\t Remainder = " << Remainder <<
"\n");
1310 if (Remainder != 0) {
1313 ++WeakCrossingSIVsuccesses;
1331 APInt A0(Bits, 1,
true), A1(Bits, 0,
true);
1332 APInt B0(Bits, 0,
true), B1(Bits, 1,
true);
1339 APInt A2 = A0 - Q*A1; A0 = A1; A1 = A2;
1340 APInt B2 = B0 - Q*B1; B0 = B1; B1 = B2;
1345 DEBUG(
dbgs() <<
"\t GCD = " << G <<
"\n");
1346 X = AM.
slt(0) ? -A1 : A1;
1347 Y = BM.
slt(0) ? B1 : -B1;
1365 if ((A.
sgt(0) && B.
sgt(0)) ||
1378 if ((A.
sgt(0) && B.
sgt(0)) ||
1388 return A.
sgt(B) ? A :
B;
1394 return A.
slt(B) ? A :
B;
1413 bool DependenceInfo::exactSIVtest(
const SCEV *SrcCoeff,
const SCEV *DstCoeff,
1414 const SCEV *SrcConst,
const SCEV *DstConst,
1415 const Loop *CurLoop,
unsigned Level,
1417 Constraint &NewConstraint)
const {
1419 DEBUG(
dbgs() <<
"\t SrcCoeff = " << *SrcCoeff <<
" = AM\n");
1420 DEBUG(
dbgs() <<
"\t DstCoeff = " << *DstCoeff <<
" = BM\n");
1421 DEBUG(
dbgs() <<
"\t SrcConst = " << *SrcConst <<
"\n");
1422 DEBUG(
dbgs() <<
"\t DstConst = " << *DstConst <<
"\n");
1423 ++ExactSIVapplications;
1424 assert(0 < Level && Level <= CommonLevels &&
"Level out of range");
1426 Result.Consistent =
false;
1428 DEBUG(
dbgs() <<
"\t Delta = " << *Delta <<
"\n");
1434 if (!ConstDelta || !ConstSrcCoeff || !ConstDstCoeff)
1439 APInt AM = ConstSrcCoeff->getAPInt();
1440 APInt BM = ConstDstCoeff->getAPInt();
1444 ++ExactSIVindependence;
1445 ++ExactSIVsuccesses;
1449 DEBUG(
dbgs() <<
"\t X = " << X <<
", Y = " << Y <<
"\n");
1452 APInt UM(Bits, 1,
true);
1453 bool UMvalid =
false;
1456 collectConstantUpperBound(CurLoop, Delta->
getType())) {
1457 UM = CUB->getAPInt();
1458 DEBUG(
dbgs() <<
"\t UM = " << UM <<
"\n");
1469 DEBUG(
dbgs() <<
"\t TL = " << TL <<
"\n");
1472 DEBUG(
dbgs() <<
"\t TU = " << TU <<
"\n");
1477 DEBUG(
dbgs() <<
"\t TU = " << TU <<
"\n");
1480 DEBUG(
dbgs() <<
"\t TL = " << TL <<
"\n");
1488 DEBUG(
dbgs() <<
"\t TL = " << TL <<
"\n");
1491 DEBUG(
dbgs() <<
"\t TU = " << TU <<
"\n");
1496 DEBUG(
dbgs() <<
"\t TU = " << TU <<
"\n");
1499 DEBUG(
dbgs() <<
"\t TL = " << TL <<
"\n");
1503 ++ExactSIVindependence;
1504 ++ExactSIVsuccesses;
1514 DEBUG(
dbgs() <<
"\t exploring LT direction\n");
1518 DEBUG(
dbgs() <<
"\t\t TL = " << TL <<
"\n");
1522 DEBUG(
dbgs() <<
"\t\t TU = " << TU <<
"\n");
1526 ++ExactSIVsuccesses;
1532 DEBUG(
dbgs() <<
"\t exploring EQ direction\n");
1535 DEBUG(
dbgs() <<
"\t\t TL = " << TL <<
"\n");
1539 DEBUG(
dbgs() <<
"\t\t TU = " << TU <<
"\n");
1544 DEBUG(
dbgs() <<
"\t\t TL = " << TL <<
"\n");
1548 DEBUG(
dbgs() <<
"\t\t TU = " << TU <<
"\n");
1552 ++ExactSIVsuccesses;
1558 DEBUG(
dbgs() <<
"\t exploring GT direction\n");
1561 DEBUG(
dbgs() <<
"\t\t TL = " << TL <<
"\n");
1565 DEBUG(
dbgs() <<
"\t\t TU = " << TU <<
"\n");
1569 ++ExactSIVsuccesses;
1573 Result.DV[
Level].Direction &= NewDirection;
1575 ++ExactSIVindependence;
1587 return ConstDividend.
srem(ConstDivisor) == 0;
1622 bool DependenceInfo::weakZeroSrcSIVtest(
const SCEV *DstCoeff,
1623 const SCEV *SrcConst,
1624 const SCEV *DstConst,
1625 const Loop *CurLoop,
unsigned Level,
1627 Constraint &NewConstraint)
const {
1631 DEBUG(
dbgs() <<
"\tWeak-Zero (src) SIV test\n");
1632 DEBUG(
dbgs() <<
"\t DstCoeff = " << *DstCoeff <<
"\n");
1633 DEBUG(
dbgs() <<
"\t SrcConst = " << *SrcConst <<
"\n");
1634 DEBUG(
dbgs() <<
"\t DstConst = " << *DstConst <<
"\n");
1635 ++WeakZeroSIVapplications;
1636 assert(0 < Level && Level <= MaxLevels &&
"Level out of range");
1638 Result.Consistent =
false;
1640 NewConstraint.setLine(SE->
getZero(Delta->
getType()), DstCoeff, Delta,
1642 DEBUG(
dbgs() <<
"\t Delta = " << *Delta <<
"\n");
1644 if (Level < CommonLevels) {
1646 Result.DV[
Level].PeelFirst =
true;
1647 ++WeakZeroSIVsuccesses;
1654 const SCEV *AbsCoeff =
1657 const SCEV *NewDelta =
1662 if (
const SCEV *UpperBound = collectUpperBound(CurLoop, Delta->
getType())) {
1663 DEBUG(
dbgs() <<
"\t UpperBound = " << *UpperBound <<
"\n");
1666 ++WeakZeroSIVindependence;
1667 ++WeakZeroSIVsuccesses;
1672 if (Level < CommonLevels) {
1674 Result.DV[
Level].PeelLast =
true;
1675 ++WeakZeroSIVsuccesses;
1685 ++WeakZeroSIVindependence;
1686 ++WeakZeroSIVsuccesses;
1691 if (isa<SCEVConstant>(Delta) &&
1693 ++WeakZeroSIVindependence;
1694 ++WeakZeroSIVsuccesses;
1732 bool DependenceInfo::weakZeroDstSIVtest(
const SCEV *SrcCoeff,
1733 const SCEV *SrcConst,
1734 const SCEV *DstConst,
1735 const Loop *CurLoop,
unsigned Level,
1737 Constraint &NewConstraint)
const {
1740 DEBUG(
dbgs() <<
"\tWeak-Zero (dst) SIV test\n");
1741 DEBUG(
dbgs() <<
"\t SrcCoeff = " << *SrcCoeff <<
"\n");
1742 DEBUG(
dbgs() <<
"\t SrcConst = " << *SrcConst <<
"\n");
1743 DEBUG(
dbgs() <<
"\t DstConst = " << *DstConst <<
"\n");
1744 ++WeakZeroSIVapplications;
1745 assert(0 < Level && Level <= SrcLevels &&
"Level out of range");
1747 Result.Consistent =
false;
1749 NewConstraint.setLine(SrcCoeff, SE->
getZero(Delta->
getType()), Delta,
1751 DEBUG(
dbgs() <<
"\t Delta = " << *Delta <<
"\n");
1753 if (Level < CommonLevels) {
1755 Result.DV[
Level].PeelFirst =
true;
1756 ++WeakZeroSIVsuccesses;
1763 const SCEV *AbsCoeff =
1766 const SCEV *NewDelta =
1771 if (
const SCEV *UpperBound = collectUpperBound(CurLoop, Delta->
getType())) {
1772 DEBUG(
dbgs() <<
"\t UpperBound = " << *UpperBound <<
"\n");
1775 ++WeakZeroSIVindependence;
1776 ++WeakZeroSIVsuccesses;
1781 if (Level < CommonLevels) {
1783 Result.DV[
Level].PeelLast =
true;
1784 ++WeakZeroSIVsuccesses;
1794 ++WeakZeroSIVindependence;
1795 ++WeakZeroSIVsuccesses;
1800 if (isa<SCEVConstant>(Delta) &&
1802 ++WeakZeroSIVindependence;
1803 ++WeakZeroSIVsuccesses;
1817 bool DependenceInfo::exactRDIVtest(
const SCEV *SrcCoeff,
const SCEV *DstCoeff,
1818 const SCEV *SrcConst,
const SCEV *DstConst,
1819 const Loop *SrcLoop,
const Loop *DstLoop,
1822 DEBUG(
dbgs() <<
"\t SrcCoeff = " << *SrcCoeff <<
" = AM\n");
1823 DEBUG(
dbgs() <<
"\t DstCoeff = " << *DstCoeff <<
" = BM\n");
1824 DEBUG(
dbgs() <<
"\t SrcConst = " << *SrcConst <<
"\n");
1825 DEBUG(
dbgs() <<
"\t DstConst = " << *DstConst <<
"\n");
1826 ++ExactRDIVapplications;
1827 Result.Consistent =
false;
1829 DEBUG(
dbgs() <<
"\t Delta = " << *Delta <<
"\n");
1833 if (!ConstDelta || !ConstSrcCoeff || !ConstDstCoeff)
1838 APInt AM = ConstSrcCoeff->getAPInt();
1839 APInt BM = ConstDstCoeff->getAPInt();
1843 ++ExactRDIVindependence;
1847 DEBUG(
dbgs() <<
"\t X = " << X <<
", Y = " << Y <<
"\n");
1850 APInt SrcUM(Bits, 1,
true);
1851 bool SrcUMvalid =
false;
1854 collectConstantUpperBound(SrcLoop, Delta->
getType())) {
1855 SrcUM = UpperBound->getAPInt();
1856 DEBUG(
dbgs() <<
"\t SrcUM = " << SrcUM <<
"\n");
1860 APInt DstUM(Bits, 1,
true);
1861 bool DstUMvalid =
false;
1864 collectConstantUpperBound(DstLoop, Delta->
getType())) {
1865 DstUM = UpperBound->getAPInt();
1866 DEBUG(
dbgs() <<
"\t DstUM = " << DstUM <<
"\n");
1877 DEBUG(
dbgs() <<
"\t TL = " << TL <<
"\n");
1880 DEBUG(
dbgs() <<
"\t TU = " << TU <<
"\n");
1885 DEBUG(
dbgs() <<
"\t TU = " << TU <<
"\n");
1888 DEBUG(
dbgs() <<
"\t TL = " << TL <<
"\n");
1896 DEBUG(
dbgs() <<
"\t TL = " << TL <<
"\n");
1899 DEBUG(
dbgs() <<
"\t TU = " << TU <<
"\n");
1904 DEBUG(
dbgs() <<
"\t TU = " << TU <<
"\n");
1907 DEBUG(
dbgs() <<
"\t TL = " << TL <<
"\n");
1911 ++ExactRDIVindependence;
1958 bool DependenceInfo::symbolicRDIVtest(
const SCEV *A1,
const SCEV *A2,
1961 const Loop *Loop2)
const {
1962 ++SymbolicRDIVapplications;
1963 DEBUG(
dbgs() <<
"\ttry symbolic RDIV test\n");
1966 DEBUG(
dbgs() <<
"\t A2 = " << *A2 <<
"\n");
1967 DEBUG(
dbgs() <<
"\t C1 = " << *C1 <<
"\n");
1968 DEBUG(
dbgs() <<
"\t C2 = " << *C2 <<
"\n");
1969 const SCEV *N1 = collectUpperBound(Loop1, A1->
getType());
1970 const SCEV *N2 = collectUpperBound(Loop2, A1->
getType());
1971 DEBUG(
if (N1)
dbgs() <<
"\t N1 = " << *N1 <<
"\n");
1972 DEBUG(
if (N2)
dbgs() <<
"\t N2 = " << *N2 <<
"\n");
1975 DEBUG(
dbgs() <<
"\t C2 - C1 = " << *C2_C1 <<
"\n");
1976 DEBUG(
dbgs() <<
"\t C1 - C2 = " << *C1_C2 <<
"\n");
1983 DEBUG(
dbgs() <<
"\t A1*N1 = " << *A1N1 <<
"\n");
1985 ++SymbolicRDIVindependence;
1992 DEBUG(
dbgs() <<
"\t A2*N2 = " << *A2N2 <<
"\n");
1994 ++SymbolicRDIVindependence;
2006 DEBUG(
dbgs() <<
"\t A1*N1 - A2*N2 = " << *A1N1_A2N2 <<
"\n");
2008 ++SymbolicRDIVindependence;
2014 ++SymbolicRDIVindependence;
2027 DEBUG(
dbgs() <<
"\t A1*N1 - A2*N2 = " << *A1N1_A2N2 <<
"\n");
2029 ++SymbolicRDIVindependence;
2035 ++SymbolicRDIVindependence;
2044 DEBUG(
dbgs() <<
"\t A1*N1 = " << *A1N1 <<
"\n");
2046 ++SymbolicRDIVindependence;
2053 DEBUG(
dbgs() <<
"\t A2*N2 = " << *A2N2 <<
"\n");
2055 ++SymbolicRDIVindependence;
2073 bool DependenceInfo::testSIV(
const SCEV *Src,
const SCEV *Dst,
unsigned &Level,
2075 const SCEV *&SplitIter)
const {
2076 DEBUG(
dbgs() <<
" src = " << *Src <<
"\n");
2077 DEBUG(
dbgs() <<
" dst = " << *Dst <<
"\n");
2080 if (SrcAddRec && DstAddRec) {
2082 const SCEV *DstConst = DstAddRec->getStart();
2084 const SCEV *DstCoeff = DstAddRec->getStepRecurrence(*SE);
2086 assert(CurLoop == DstAddRec->getLoop() &&
2087 "both loops in SIV should be same");
2088 Level = mapSrcLoop(CurLoop);
2090 if (SrcCoeff == DstCoeff)
2091 disproven = strongSIVtest(SrcCoeff, SrcConst, DstConst, CurLoop,
2092 Level, Result, NewConstraint);
2094 disproven = weakCrossingSIVtest(SrcCoeff, SrcConst, DstConst, CurLoop,
2095 Level, Result, NewConstraint, SplitIter);
2097 disproven = exactSIVtest(SrcCoeff, DstCoeff, SrcConst, DstConst, CurLoop,
2098 Level, Result, NewConstraint);
2100 gcdMIVtest(Src, Dst, Result) ||
2101 symbolicRDIVtest(SrcCoeff, DstCoeff, SrcConst, DstConst, CurLoop, CurLoop);
2106 const SCEV *DstConst = Dst;
2108 Level = mapSrcLoop(CurLoop);
2109 return weakZeroDstSIVtest(SrcCoeff, SrcConst, DstConst, CurLoop,
2110 Level, Result, NewConstraint) ||
2111 gcdMIVtest(Src, Dst, Result);
2114 const SCEV *DstConst = DstAddRec->getStart();
2115 const SCEV *DstCoeff = DstAddRec->getStepRecurrence(*SE);
2116 const SCEV *SrcConst = Src;
2117 const Loop *CurLoop = DstAddRec->getLoop();
2118 Level = mapDstLoop(CurLoop);
2119 return weakZeroSrcSIVtest(DstCoeff, SrcConst, DstConst,
2120 CurLoop, Level, Result, NewConstraint) ||
2121 gcdMIVtest(Src, Dst, Result);
2141 bool DependenceInfo::testRDIV(
const SCEV *Src,
const SCEV *Dst,
2149 const SCEV *SrcConst, *DstConst;
2150 const SCEV *SrcCoeff, *DstCoeff;
2151 const Loop *SrcLoop, *DstLoop;
2153 DEBUG(
dbgs() <<
" src = " << *Src <<
"\n");
2154 DEBUG(
dbgs() <<
" dst = " << *Dst <<
"\n");
2157 if (SrcAddRec && DstAddRec) {
2160 SrcLoop = SrcAddRec->
getLoop();
2161 DstConst = DstAddRec->getStart();
2162 DstCoeff = DstAddRec->getStepRecurrence(*SE);
2163 DstLoop = DstAddRec->getLoop();
2165 else if (SrcAddRec) {
2167 dyn_cast<SCEVAddRecExpr>(SrcAddRec->
getStart())) {
2168 SrcConst = tmpAddRec->getStart();
2169 SrcCoeff = tmpAddRec->getStepRecurrence(*SE);
2170 SrcLoop = tmpAddRec->getLoop();
2173 DstLoop = SrcAddRec->
getLoop();
2178 else if (DstAddRec) {
2180 dyn_cast<SCEVAddRecExpr>(DstAddRec->getStart())) {
2181 DstConst = tmpAddRec->getStart();
2182 DstCoeff = tmpAddRec->getStepRecurrence(*SE);
2183 DstLoop = tmpAddRec->getLoop();
2186 SrcLoop = DstAddRec->getLoop();
2193 return exactRDIVtest(SrcCoeff, DstCoeff,
2197 gcdMIVtest(Src, Dst, Result) ||
2198 symbolicRDIVtest(SrcCoeff, DstCoeff,
2207 bool DependenceInfo::testMIV(
const SCEV *Src,
const SCEV *Dst,
2210 DEBUG(
dbgs() <<
" src = " << *Src <<
"\n");
2211 DEBUG(
dbgs() <<
" dst = " << *Dst <<
"\n");
2212 Result.Consistent =
false;
2213 return gcdMIVtest(Src, Dst, Result) ||
2214 banerjeeMIVtest(Src, Dst, Loops, Result);
2222 if (
const auto *
Constant = dyn_cast<SCEVConstant>(Expr))
2224 else if (
const auto *Product = dyn_cast<SCEVMulExpr>(Expr))
2225 if (
const auto *
Constant = dyn_cast<SCEVConstant>(Product->getOperand(0)))
2249 bool DependenceInfo::gcdMIVtest(
const SCEV *Src,
const SCEV *Dst,
2260 const SCEV *Coefficients = Src;
2262 dyn_cast<SCEVAddRecExpr>(Coefficients)) {
2273 const SCEV *SrcConst = Coefficients;
2281 dyn_cast<SCEVAddRecExpr>(Coefficients)) {
2292 const SCEV *DstConst = Coefficients;
2296 DEBUG(
dbgs() <<
" Delta = " << *Delta <<
"\n");
2298 if (
const SCEVAddExpr *Sum = dyn_cast<SCEVAddExpr>(Delta)) {
2300 for (
unsigned Op = 0, Ops = Sum->getNumOperands();
Op < Ops;
Op++) {
2301 const SCEV *Operand = Sum->getOperand(
Op);
2302 if (isa<SCEVConstant>(Operand)) {
2303 assert(!Constant &&
"Surprised to find multiple constants");
2304 Constant = cast<SCEVConstant>(Operand);
2306 else if (
const SCEVMulExpr *Product = dyn_cast<SCEVMulExpr>(Operand)) {
2314 ConstOpValue.
abs());
2322 APInt ConstDelta = cast<SCEVConstant>(Constant)->getAPInt();
2323 DEBUG(
dbgs() <<
" ConstDelta = " << ConstDelta <<
"\n");
2324 if (ConstDelta == 0)
2327 DEBUG(
dbgs() <<
" RunningGCD = " << RunningGCD <<
"\n");
2328 APInt Remainder = ConstDelta.
srem(RunningGCD);
2329 if (Remainder != 0) {
2346 DEBUG(
dbgs() <<
" ExtraGCD = " << ExtraGCD <<
'\n');
2348 bool Improved =
false;
2351 dyn_cast<SCEVAddRecExpr>(Coefficients)) {
2354 RunningGCD = ExtraGCD;
2357 const SCEV *Inner = Src;
2358 while (RunningGCD != 1 && isa<SCEVAddRecExpr>(Inner)) {
2359 AddRec = cast<SCEVAddRecExpr>(Inner);
2361 if (CurLoop == AddRec->
getLoop())
2375 while (RunningGCD != 1 && isa<SCEVAddRecExpr>(Inner)) {
2376 AddRec = cast<SCEVAddRecExpr>(Inner);
2378 if (CurLoop == AddRec->
getLoop())
2401 DEBUG(
dbgs() <<
"\tRunningGCD = " << RunningGCD <<
"\n");
2402 if (RunningGCD != 0) {
2403 Remainder = ConstDelta.
srem(RunningGCD);
2404 DEBUG(
dbgs() <<
"\tRemainder = " << Remainder <<
"\n");
2405 if (Remainder != 0) {
2406 unsigned Level = mapSrcLoop(CurLoop);
2452 bool DependenceInfo::banerjeeMIVtest(
const SCEV *Src,
const SCEV *Dst,
2456 ++BanerjeeApplications;
2457 DEBUG(
dbgs() <<
" Src = " << *Src <<
'\n');
2459 CoefficientInfo *
A = collectCoeffInfo(Src,
true, A0);
2460 DEBUG(
dbgs() <<
" Dst = " << *Dst <<
'\n');
2462 CoefficientInfo *
B = collectCoeffInfo(Dst,
false, B0);
2463 BoundInfo *Bound =
new BoundInfo[MaxLevels + 1];
2465 DEBUG(
dbgs() <<
"\tDelta = " << *Delta <<
'\n');
2469 for (
unsigned K = 1; K <= MaxLevels; ++K) {
2470 Bound[K].Iterations = A[K].Iterations ? A[K].Iterations : B[K].Iterations;
2473 findBoundsALL(A, B, Bound, K);
2477 DEBUG(
dbgs() << *Bound[K].
Lower[Dependence::DVEntry::ALL] <<
'\t');
2480 if (Bound[K].
Upper[Dependence::DVEntry::ALL])
2481 DEBUG(
dbgs() << *Bound[K].
Upper[Dependence::DVEntry::ALL] <<
'\n');
2488 bool Disproved =
false;
2489 if (testBounds(Dependence::DVEntry::ALL, 0, Bound, Delta)) {
2491 unsigned DepthExpanded = 0;
2492 unsigned NewDeps = exploreDirections(1, A, B, Bound,
2493 Loops, DepthExpanded, Delta);
2495 bool Improved =
false;
2496 for (
unsigned K = 1; K <= CommonLevels; ++K) {
2498 unsigned Old = Result.DV[K - 1].Direction;
2499 Result.DV[K - 1].Direction = Old & Bound[K].DirSet;
2500 Improved |= Old != Result.DV[K - 1].Direction;
2501 if (!Result.DV[K - 1].Direction) {
2509 ++BanerjeeSuccesses;
2512 ++BanerjeeIndependence;
2517 ++BanerjeeIndependence;
2532 unsigned DependenceInfo::exploreDirections(
unsigned Level, CoefficientInfo *A,
2533 CoefficientInfo *B, BoundInfo *Bound,
2535 unsigned &DepthExpanded,
2536 const SCEV *Delta)
const {
2537 if (Level > CommonLevels) {
2540 for (
unsigned K = 1; K <= CommonLevels; ++K) {
2542 Bound[K].DirSet |= Bound[K].Direction;
2544 switch (Bound[K].Direction) {
2554 case Dependence::DVEntry::ALL:
2567 if (Level > DepthExpanded) {
2568 DepthExpanded =
Level;
2570 findBoundsLT(A, B, Bound, Level);
2571 findBoundsGT(A, B, Bound, Level);
2572 findBoundsEQ(A, B, Bound, Level);
2574 DEBUG(
dbgs() <<
"\tBound for level = " << Level <<
'\n');
2577 DEBUG(
dbgs() << *Bound[Level].
Lower[Dependence::DVEntry::LT] <<
'\t');
2580 if (Bound[Level].
Upper[Dependence::DVEntry::LT])
2581 DEBUG(
dbgs() << *Bound[Level].
Upper[Dependence::DVEntry::LT] <<
'\n');
2586 DEBUG(
dbgs() << *Bound[Level].
Lower[Dependence::DVEntry::EQ] <<
'\t');
2589 if (Bound[Level].
Upper[Dependence::DVEntry::EQ])
2590 DEBUG(
dbgs() << *Bound[Level].
Upper[Dependence::DVEntry::EQ] <<
'\n');
2595 DEBUG(
dbgs() << *Bound[Level].
Lower[Dependence::DVEntry::GT] <<
'\t');
2598 if (Bound[Level].
Upper[Dependence::DVEntry::GT])
2599 DEBUG(
dbgs() << *Bound[Level].
Upper[Dependence::DVEntry::GT] <<
'\n');
2605 unsigned NewDeps = 0;
2608 if (testBounds(Dependence::DVEntry::LT, Level, Bound, Delta))
2609 NewDeps += exploreDirections(Level + 1, A, B, Bound,
2610 Loops, DepthExpanded, Delta);
2613 if (testBounds(Dependence::DVEntry::EQ, Level, Bound, Delta))
2614 NewDeps += exploreDirections(Level + 1, A, B, Bound,
2615 Loops, DepthExpanded, Delta);
2618 if (testBounds(Dependence::DVEntry::GT, Level, Bound, Delta))
2619 NewDeps += exploreDirections(Level + 1, A, B, Bound,
2620 Loops, DepthExpanded, Delta);
2626 return exploreDirections(Level + 1, A, B, Bound, Loops, DepthExpanded, Delta);
2631 bool DependenceInfo::testBounds(
unsigned char DirKind,
unsigned Level,
2632 BoundInfo *Bound,
const SCEV *Delta)
const {
2633 Bound[
Level].Direction = DirKind;
2634 if (
const SCEV *LowerBound = getLowerBound(Bound))
2637 if (
const SCEV *UpperBound = getUpperBound(Bound))
2659 void DependenceInfo::findBoundsALL(CoefficientInfo *A, CoefficientInfo *B,
2660 BoundInfo *Bound,
unsigned K)
const {
2663 if (Bound[K].Iterations) {
2666 Bound[K].Iterations);
2669 Bound[K].Iterations);
2674 Bound[K].
Lower[Dependence::DVEntry::ALL] =
2675 SE->
getZero(A[K].Coeff->getType());
2677 Bound[K].
Upper[Dependence::DVEntry::ALL] =
2678 SE->
getZero(A[K].Coeff->getType());
2698 void DependenceInfo::findBoundsEQ(CoefficientInfo *A, CoefficientInfo *B,
2699 BoundInfo *Bound,
unsigned K)
const {
2702 if (Bound[K].Iterations) {
2704 const SCEV *NegativePart = getNegativePart(Delta);
2706 SE->
getMulExpr(NegativePart, Bound[K].Iterations);
2707 const SCEV *PositivePart = getPositivePart(Delta);
2709 SE->
getMulExpr(PositivePart, Bound[K].Iterations);
2715 const SCEV *NegativePart = getNegativePart(Delta);
2716 if (NegativePart->
isZero())
2717 Bound[K].
Lower[Dependence::DVEntry::EQ] = NegativePart;
2718 const SCEV *PositivePart = getPositivePart(Delta);
2719 if (PositivePart->
isZero())
2720 Bound[K].
Upper[Dependence::DVEntry::EQ] = PositivePart;
2738 void DependenceInfo::findBoundsLT(CoefficientInfo *A, CoefficientInfo *B,
2739 BoundInfo *Bound,
unsigned K)
const {
2742 if (Bound[K].Iterations) {
2744 Bound[K].Iterations, SE->
getOne(Bound[K].Iterations->getType()));
2745 const SCEV *NegPart =
2746 getNegativePart(SE->
getMinusSCEV(A[K].NegPart, B[K].Coeff));
2749 const SCEV *PosPart =
2750 getPositivePart(SE->
getMinusSCEV(A[K].PosPart, B[K].Coeff));
2757 const SCEV *NegPart =
2758 getNegativePart(SE->
getMinusSCEV(A[K].NegPart, B[K].Coeff));
2761 const SCEV *PosPart =
2762 getPositivePart(SE->
getMinusSCEV(A[K].PosPart, B[K].Coeff));
2782 void DependenceInfo::findBoundsGT(CoefficientInfo *A, CoefficientInfo *B,
2783 BoundInfo *Bound,
unsigned K)
const {
2786 if (Bound[K].Iterations) {
2788 Bound[K].Iterations, SE->
getOne(Bound[K].Iterations->getType()));
2789 const SCEV *NegPart =
2790 getNegativePart(SE->
getMinusSCEV(A[K].Coeff, B[K].PosPart));
2793 const SCEV *PosPart =
2794 getPositivePart(SE->
getMinusSCEV(A[K].Coeff, B[K].NegPart));
2801 const SCEV *NegPart = getNegativePart(SE->
getMinusSCEV(A[K].Coeff, B[K].PosPart));
2803 Bound[K].
Lower[Dependence::DVEntry::GT] = A[K].Coeff;
2804 const SCEV *PosPart = getPositivePart(SE->
getMinusSCEV(A[K].Coeff, B[K].NegPart));
2806 Bound[K].
Upper[Dependence::DVEntry::GT] = A[K].Coeff;
2812 const SCEV *DependenceInfo::getPositivePart(
const SCEV *X)
const {
2818 const SCEV *DependenceInfo::getNegativePart(
const SCEV *X)
const {
2826 DependenceInfo::CoefficientInfo *
2827 DependenceInfo::collectCoeffInfo(
const SCEV *Subscript,
bool SrcFlag,
2828 const SCEV *&Constant)
const {
2830 CoefficientInfo *CI =
new CoefficientInfo[MaxLevels + 1];
2831 for (
unsigned K = 1; K <= MaxLevels; ++K) {
2833 CI[K].PosPart =
Zero;
2834 CI[K].NegPart =
Zero;
2835 CI[K].Iterations =
nullptr;
2837 while (
const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(Subscript)) {
2839 unsigned K = SrcFlag ? mapSrcLoop(L) : mapDstLoop(L);
2841 CI[K].PosPart = getPositivePart(CI[K].Coeff);
2842 CI[K].NegPart = getNegativePart(CI[K].Coeff);
2843 CI[K].Iterations = collectUpperBound(L, Subscript->
getType());
2846 Constant = Subscript;
2848 DEBUG(
dbgs() <<
"\tCoefficient Info\n");
2849 for (
unsigned K = 1; K <= MaxLevels; ++K) {
2850 DEBUG(
dbgs() <<
"\t " << K <<
"\t" << *CI[K].Coeff);
2856 if (CI[K].Iterations)
2862 DEBUG(
dbgs() <<
"\t Constant = " << *Subscript <<
'\n');
2872 const SCEV *DependenceInfo::getLowerBound(BoundInfo *Bound)
const {
2873 const SCEV *Sum = Bound[1].Lower[Bound[1].Direction];
2874 for (
unsigned K = 2; Sum && K <= MaxLevels; ++K) {
2875 if (Bound[K].
Lower[Bound[K].Direction])
2888 const SCEV *DependenceInfo::getUpperBound(BoundInfo *Bound)
const {
2889 const SCEV *Sum = Bound[1].Upper[Bound[1].Direction];
2890 for (
unsigned K = 2; Sum && K <= MaxLevels; ++K) {
2891 if (Bound[K].
Upper[Bound[K].Direction])
2909 const SCEV *DependenceInfo::findCoefficient(
const SCEV *Expr,
2910 const Loop *TargetLoop)
const {
2914 if (AddRec->
getLoop() == TargetLoop)
2916 return findCoefficient(AddRec->
getStart(), TargetLoop);
2925 const SCEV *DependenceInfo::zeroCoefficient(
const SCEV *Expr,
2926 const Loop *TargetLoop)
const {
2930 if (AddRec->
getLoop() == TargetLoop)
2944 const SCEV *DependenceInfo::addToCoefficient(
const SCEV *Expr,
2945 const Loop *TargetLoop,
2953 if (AddRec->
getLoop() == TargetLoop) {
2965 addToCoefficient(AddRec->
getStart(), TargetLoop, Value),
2981 bool DependenceInfo::propagate(
const SCEV *&Src,
const SCEV *&Dst,
2985 bool Result =
false;
2987 DEBUG(
dbgs() <<
"\t Constraint[" << LI <<
"] is");
2989 if (Constraints[LI].isDistance())
2990 Result |= propagateDistance(Src, Dst, Constraints[LI], Consistent);
2991 else if (Constraints[LI].isLine())
2992 Result |= propagateLine(Src, Dst, Constraints[LI], Consistent);
2993 else if (Constraints[LI].isPoint())
2994 Result |= propagatePoint(Src, Dst, Constraints[LI]);
3005 bool DependenceInfo::propagateDistance(
const SCEV *&Src,
const SCEV *&Dst,
3006 Constraint &CurConstraint,
3008 const Loop *CurLoop = CurConstraint.getAssociatedLoop();
3009 DEBUG(
dbgs() <<
"\t\tSrc is " << *Src <<
"\n");
3010 const SCEV *A_K = findCoefficient(Src, CurLoop);
3015 Src = zeroCoefficient(Src, CurLoop);
3016 DEBUG(
dbgs() <<
"\t\tnew Src is " << *Src <<
"\n");
3017 DEBUG(
dbgs() <<
"\t\tDst is " << *Dst <<
"\n");
3019 DEBUG(
dbgs() <<
"\t\tnew Dst is " << *Dst <<
"\n");
3020 if (!findCoefficient(Dst, CurLoop)->
isZero())
3031 bool DependenceInfo::propagateLine(
const SCEV *&Src,
const SCEV *&Dst,
3032 Constraint &CurConstraint,
3034 const Loop *CurLoop = CurConstraint.getAssociatedLoop();
3035 const SCEV *A = CurConstraint.getA();
3036 const SCEV *B = CurConstraint.getB();
3037 const SCEV *
C = CurConstraint.getC();
3038 DEBUG(
dbgs() <<
"\t\tA = " << *A <<
", B = " << *B <<
", C = " << *C <<
"\n");
3039 DEBUG(
dbgs() <<
"\t\tSrc = " << *Src <<
"\n");
3040 DEBUG(
dbgs() <<
"\t\tDst = " << *Dst <<
"\n");
3044 if (!Bconst || !Cconst)
return false;
3046 APInt Charlie = Cconst->getAPInt();
3048 assert(Charlie.
srem(Beta) == 0 &&
"C should be evenly divisible by B");
3049 const SCEV *AP_K = findCoefficient(Dst, CurLoop);
3052 Dst = zeroCoefficient(Dst, CurLoop);
3053 if (!findCoefficient(Src, CurLoop)->
isZero())
3059 if (!Aconst || !Cconst)
return false;
3061 APInt Charlie = Cconst->getAPInt();
3063 assert(Charlie.
srem(Alpha) == 0 &&
"C should be evenly divisible by A");
3064 const SCEV *A_K = findCoefficient(Src, CurLoop);
3066 Src = zeroCoefficient(Src, CurLoop);
3067 if (!findCoefficient(Dst, CurLoop)->
isZero())
3073 if (!Aconst || !Cconst)
return false;
3075 APInt Charlie = Cconst->getAPInt();
3077 assert(Charlie.
srem(Alpha) == 0 &&
"C should be evenly divisible by A");
3078 const SCEV *A_K = findCoefficient(Src, CurLoop);
3080 Src = zeroCoefficient(Src, CurLoop);
3081 Dst = addToCoefficient(Dst, CurLoop, A_K);
3082 if (!findCoefficient(Dst, CurLoop)->
isZero())
3087 const SCEV *A_K = findCoefficient(Src, CurLoop);
3091 Src = zeroCoefficient(Src, CurLoop);
3092 Dst = addToCoefficient(Dst, CurLoop, SE->
getMulExpr(A_K, B));
3093 if (!findCoefficient(Dst, CurLoop)->
isZero())
3096 DEBUG(
dbgs() <<
"\t\tnew Src = " << *Src <<
"\n");
3097 DEBUG(
dbgs() <<
"\t\tnew Dst = " << *Dst <<
"\n");
3105 bool DependenceInfo::propagatePoint(
const SCEV *&Src,
const SCEV *&Dst,
3106 Constraint &CurConstraint) {
3107 const Loop *CurLoop = CurConstraint.getAssociatedLoop();
3108 const SCEV *A_K = findCoefficient(Src, CurLoop);
3109 const SCEV *AP_K = findCoefficient(Dst, CurLoop);
3112 DEBUG(
dbgs() <<
"\t\tSrc is " << *Src <<
"\n");
3114 Src = zeroCoefficient(Src, CurLoop);
3115 DEBUG(
dbgs() <<
"\t\tnew Src is " << *Src <<
"\n");
3116 DEBUG(
dbgs() <<
"\t\tDst is " << *Dst <<
"\n");
3117 Dst = zeroCoefficient(Dst, CurLoop);
3118 DEBUG(
dbgs() <<
"\t\tnew Dst is " << *Dst <<
"\n");
3125 const Constraint &CurConstraint)
const {
3126 DEBUG(
dbgs() <<
"\tUpdate direction, constraint =");
3128 if (CurConstraint.isAny())
3130 else if (CurConstraint.isDistance()) {
3133 Level.
Distance = CurConstraint.getD();
3136 NewDirection = Dependence::DVEntry::EQ;
3138 NewDirection |= Dependence::DVEntry::LT;
3140 NewDirection |= Dependence::DVEntry::GT;
3143 else if (CurConstraint.isLine()) {
3148 else if (CurConstraint.isPoint()) {
3153 CurConstraint.getY(),
3154 CurConstraint.getX()))
3158 CurConstraint.getY(),
3159 CurConstraint.getX()))
3163 CurConstraint.getY(),
3164 CurConstraint.getX()))
3186 const SCEV *SrcAccessFn =
3188 const SCEV *DstAccessFn =
3196 if (!SrcBase || !DstBase || SrcBase != DstBase)
3208 if (!SrcAR || !DstAR || !SrcAR->
isAffine() || !DstAR->isAffine())
3226 if (SrcSubscripts.
size() < 2 || DstSubscripts.
size() < 2 ||
3227 SrcSubscripts.
size() != DstSubscripts.
size())
3230 int size = SrcSubscripts.
size();
3233 dbgs() <<
"\nSrcSubscripts: ";
3234 for (
int i = 0;
i < size;
i++)
3235 dbgs() << *SrcSubscripts[
i];
3236 dbgs() <<
"\nDstSubscripts: ";
3237 for (
int i = 0;
i < size;
i++)
3238 dbgs() << *DstSubscripts[
i];
3246 for (
int i = 0;
i < size; ++
i) {
3247 Pair[
i].Src = SrcSubscripts[
i];
3248 Pair[
i].Dst = DstSubscripts[
i];
3249 unifySubscriptType(&Pair[
i]);
3288 std::unique_ptr<Dependence>
3290 bool PossiblyLoopIndependent) {
3292 PossiblyLoopIndependent =
false;
3301 DEBUG(
dbgs() <<
"can only handle simple loads and stores\n");
3302 return make_unique<Dependence>(Src, Dst);
3313 DEBUG(
dbgs() <<
"can't analyze may or partial alias\n");
3314 return make_unique<Dependence>(Src, Dst);
3324 establishNestingLevels(Src, Dst);
3325 DEBUG(
dbgs() <<
" common nesting levels = " << CommonLevels <<
"\n");
3326 DEBUG(
dbgs() <<
" maximum nesting levels = " << MaxLevels <<
"\n");
3328 FullDependence Result(Src, Dst, PossiblyLoopIndependent, CommonLevels);
3332 bool UsefulGEP =
false;
3335 if (SrcGEP && DstGEP &&
3338 const SCEV *DstPtrSCEV = SE->
getSCEV(DstGEP->getPointerOperand());
3339 DEBUG(
dbgs() <<
" SrcPtrSCEV = " << *SrcPtrSCEV <<
"\n");
3340 DEBUG(
dbgs() <<
" DstPtrSCEV = " << *DstPtrSCEV <<
"\n");
3353 DstIdx = DstGEP->idx_begin();
3355 ++SrcIdx, ++DstIdx, ++
P) {
3356 Pair[
P].Src = SE->
getSCEV(*SrcIdx);
3357 Pair[
P].Dst = SE->
getSCEV(*DstIdx);
3358 unifySubscriptType(&Pair[P]);
3365 DEBUG(
dbgs() <<
" SrcSCEV = " << *SrcSCEV <<
"\n");
3366 DEBUG(
dbgs() <<
" DstSCEV = " << *DstSCEV <<
"\n");
3367 Pair[0].Src = SrcSCEV;
3368 Pair[0].Dst = DstSCEV;
3372 if (tryDelinearize(Src, Dst, Pair)) {
3374 Pairs = Pair.
size();
3378 for (
unsigned P = 0;
P < Pairs; ++
P) {
3379 Pair[
P].Loops.
resize(MaxLevels + 1);
3380 Pair[
P].GroupLoops.
resize(MaxLevels + 1);
3382 removeMatchingExtensions(&Pair[
P]);
3383 Pair[
P].Classification =
3384 classifyPair(Pair[P].Src, LI->
getLoopFor(Src->getParent()),
3385 Pair[P].Dst, LI->
getLoopFor(Dst->getParent()),
3387 Pair[
P].GroupLoops = Pair[
P].Loops;
3388 Pair[
P].Group.set(P);
3389 DEBUG(
dbgs() <<
" subscript " << P <<
"\n");
3390 DEBUG(
dbgs() <<
"\tsrc = " << *Pair[P].Src <<
"\n");
3391 DEBUG(
dbgs() <<
"\tdst = " << *Pair[P].Dst <<
"\n");
3392 DEBUG(
dbgs() <<
"\tclass = " << Pair[P].Classification <<
"\n");
3457 for (
unsigned SI = 0;
SI < Pairs; ++
SI) {
3458 if (Pair[
SI].Classification == Subscript::NonLinear) {
3460 ++NonlinearSubscriptPairs;
3461 collectCommonLoops(Pair[
SI].Src,
3464 collectCommonLoops(Pair[
SI].Dst,
3467 Result.Consistent =
false;
3468 }
else if (Pair[
SI].Classification == Subscript::ZIV) {
3475 for (
unsigned SJ =
SI + 1; SJ < Pairs; ++SJ) {
3477 Intersection &= Pair[SJ].GroupLoops;
3478 if (Intersection.
any()) {
3480 Pair[SJ].GroupLoops |= Pair[
SI].GroupLoops;
3482 Pair[SJ].Group |= Pair[
SI].Group;
3487 if (Pair[
SI].Group.count() == 1) {
3489 ++SeparableSubscriptPairs;
3493 ++CoupledSubscriptPairs;
3504 Constraint NewConstraint;
3505 NewConstraint.setAny(SE);
3510 switch (Pair[
SI].Classification) {
3511 case Subscript::ZIV:
3513 if (testZIV(Pair[
SI].Src, Pair[
SI].Dst, Result))
3516 case Subscript::SIV: {
3519 const SCEV *SplitIter =
nullptr;
3520 if (testSIV(Pair[
SI].Src, Pair[
SI].Dst, Level, Result, NewConstraint,
3525 case Subscript::RDIV:
3527 if (testRDIV(Pair[
SI].Src, Pair[
SI].Dst, Result))
3530 case Subscript::MIV:
3532 if (testMIV(Pair[
SI].Src, Pair[
SI].Dst, Pair[
SI].Loops, Result))
3540 if (Coupled.
count()) {
3542 DEBUG(
dbgs() <<
"starting on coupled subscripts\n");
3543 DEBUG(
dbgs() <<
"MaxLevels + 1 = " << MaxLevels + 1 <<
"\n");
3545 for (
unsigned II = 0; II <= MaxLevels; ++II)
3546 Constraints[II].setAny(SE);
3548 DEBUG(
dbgs() <<
"testing subscript group " <<
SI <<
" { ");
3556 if (Pair[SJ].Classification == Subscript::SIV)
3562 unifySubscriptType(PairsInGroup);
3564 while (Sivs.
any()) {
3565 bool Changed =
false;
3567 DEBUG(
dbgs() <<
"testing subscript " << SJ <<
", SIV\n");
3570 const SCEV *SplitIter =
nullptr;
3572 if (testSIV(Pair[SJ].Src, Pair[SJ].Dst, Level, Result, NewConstraint,
3575 ConstrainedLevels.
set(Level);
3576 if (intersectConstraints(&Constraints[Level], &NewConstraint)) {
3577 if (Constraints[Level].isEmpty()) {
3578 ++DeltaIndependence;
3592 DEBUG(
dbgs() <<
"\tSJ = " << SJ <<
"\n");
3593 if (propagate(Pair[SJ].Src, Pair[SJ].Dst, Pair[SJ].Loops,
3594 Constraints, Result.Consistent)) {
3596 ++DeltaPropagations;
3597 Pair[SJ].Classification =
3598 classifyPair(Pair[SJ].Src, LI->
getLoopFor(Src->getParent()),
3599 Pair[SJ].Dst, LI->
getLoopFor(Dst->getParent()),
3601 switch (Pair[SJ].Classification) {
3602 case Subscript::ZIV:
3604 if (testZIV(Pair[SJ].Src, Pair[SJ].Dst, Result))
3608 case Subscript::SIV:
3612 case Subscript::RDIV:
3613 case Subscript::MIV:
3625 if (Pair[SJ].Classification == Subscript::RDIV) {
3627 if (testRDIV(Pair[SJ].Src, Pair[SJ].Dst, Result))
3638 if (Pair[SJ].Classification == Subscript::MIV) {
3640 if (testMIV(Pair[SJ].Src, Pair[SJ].Dst, Pair[SJ].Loops, Result))
3649 for (
int SJ = ConstrainedLevels.
find_first(); SJ >= 0;
3651 if (SJ > (
int)CommonLevels)
3653 updateDirection(Result.DV[SJ - 1], Constraints[SJ]);
3662 for (
unsigned SI = 0;
SI < Pairs; ++
SI)
3663 CompleteLoops |= Pair[
SI].Loops;
3664 for (
unsigned II = 1; II <= CommonLevels; ++II)
3665 if (CompleteLoops[II])
3666 Result.DV[II - 1].Scalar =
false;
3668 if (PossiblyLoopIndependent) {
3672 for (
unsigned II = 1; II <= CommonLevels; ++II) {
3674 Result.LoopIndependent =
false;
3682 bool AllEqual =
true;
3683 for (
unsigned II = 1; II <= CommonLevels; ++II) {
3693 return make_unique<FullDependence>(std::move(Result));
3746 unsigned SplitLevel) {
3748 "Dep should be splitable at SplitLevel");
3751 assert(Src->mayReadFromMemory() || Src->mayWriteToMemory());
3761 establishNestingLevels(Src, Dst);
3766 bool UsefulGEP =
false;
3769 if (SrcGEP && DstGEP &&
3772 const SCEV *DstPtrSCEV = SE->
getSCEV(DstGEP->getPointerOperand());
3773 UsefulGEP = isLoopInvariant(SrcPtrSCEV, LI->
getLoopFor(Src->getParent())) &&
3783 DstIdx = DstGEP->idx_begin();
3785 ++SrcIdx, ++DstIdx, ++
P) {
3786 Pair[
P].Src = SE->
getSCEV(*SrcIdx);
3787 Pair[
P].Dst = SE->
getSCEV(*DstIdx);
3793 Pair[0].Src = SrcSCEV;
3794 Pair[0].Dst = DstSCEV;
3798 if (tryDelinearize(Src, Dst, Pair)) {
3800 Pairs = Pair.
size();
3804 for (
unsigned P = 0;
P < Pairs; ++
P) {
3805 Pair[
P].Loops.
resize(MaxLevels + 1);
3806 Pair[
P].GroupLoops.
resize(MaxLevels + 1);
3808 removeMatchingExtensions(&Pair[
P]);
3809 Pair[
P].Classification =
3810 classifyPair(Pair[P].Src, LI->
getLoopFor(Src->getParent()),
3811 Pair[P].Dst, LI->
getLoopFor(Dst->getParent()),
3813 Pair[
P].GroupLoops = Pair[
P].Loops;
3814 Pair[
P].Group.set(P);
3821 for (
unsigned SI = 0;
SI < Pairs; ++
SI) {
3822 if (Pair[
SI].Classification == Subscript::NonLinear) {
3824 collectCommonLoops(Pair[
SI].Src,
3827 collectCommonLoops(Pair[
SI].Dst,
3830 Result.Consistent =
false;
3832 else if (Pair[
SI].Classification == Subscript::ZIV)
3837 for (
unsigned SJ =
SI + 1; SJ < Pairs; ++SJ) {
3839 Intersection &= Pair[SJ].GroupLoops;
3840 if (Intersection.
any()) {
3842 Pair[SJ].GroupLoops |= Pair[
SI].GroupLoops;
3844 Pair[SJ].Group |= Pair[
SI].Group;
3849 if (Pair[
SI].Group.count() == 1)
3857 Constraint NewConstraint;
3858 NewConstraint.setAny(SE);
3862 switch (Pair[
SI].Classification) {
3863 case Subscript::SIV: {
3865 const SCEV *SplitIter =
nullptr;
3866 (void) testSIV(Pair[
SI].Src, Pair[
SI].Dst, Level,
3867 Result, NewConstraint, SplitIter);
3868 if (Level == SplitLevel) {
3869 assert(SplitIter !=
nullptr);
3874 case Subscript::ZIV:
3875 case Subscript::RDIV:
3876 case Subscript::MIV:
3883 if (Coupled.
count()) {
3886 for (
unsigned II = 0; II <= MaxLevels; ++II)
3887 Constraints[II].setAny(SE);
3894 if (Pair[SJ].Classification == Subscript::SIV)
3899 while (Sivs.
any()) {
3900 bool Changed =
false;
3904 const SCEV *SplitIter =
nullptr;
3905 (void) testSIV(Pair[SJ].Src, Pair[SJ].Dst, Level,
3906 Result, NewConstraint, SplitIter);
3907 if (Level == SplitLevel && SplitIter)
3909 ConstrainedLevels.
set(Level);
3910 if (intersectConstraints(&Constraints[Level], &NewConstraint))
3918 if (propagate(Pair[SJ].Src, Pair[SJ].Dst,
3919 Pair[SJ].Loops, Constraints, Result.Consistent)) {
3920 Pair[SJ].Classification =
3921 classifyPair(Pair[SJ].Src, LI->
getLoopFor(Src->getParent()),
3922 Pair[SJ].Dst, LI->
getLoopFor(Dst->getParent()),
3924 switch (Pair[SJ].Classification) {
3925 case Subscript::ZIV:
3928 case Subscript::SIV:
3932 case Subscript::RDIV:
3933 case Subscript::MIV:
NoWrapFlags getNoWrapFlags(NoWrapFlags Mask=NoWrapMask) const
bool runOnFunction(Function &F) override
runOnFunction - Virtual method overriden by subclasses to do the per-function processing of the pass...
The two locations precisely alias each other.
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. ...
FunctionPass * createDependenceAnalysisWrapperPass()
createDependenceAnalysisPass - This creates an instance of the DependenceAnalysis wrapper pass...
unsigned getLoopDepth(const BlockT *BB) const
Return the loop nesting level of the specified block.
size_type count() const
Returns the number of bits which are set.
bool isAnti() const
isAnti - Returns true if this is an anti dependence.
virtual bool isConfused() const
isConfused - Returns true if this dependence is confused (the compiler understands nothing and makes ...
bool isOne() const
Return true if the expression is a constant one.
This is a 'bitvector' (really, a variable-sized bit array), optimized for the case when the array is ...
const SCEV * getConstant(ConstantInt *V)
STATISTIC(NumFunctions,"Total number of functions")
const SCEV * getSplitIteration(const Dependence &Dep, unsigned Level)
getSplitIteration - Give a dependence that's splittable at some particular level, return the iteratio...
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
Return true if the expression is a constant zero.
Legacy pass manager pass to access dependence information.
unsigned getNumOperands() const
The two locations alias, but only due to a partial overlap.
const SCEV * getPointerBase(const SCEV *V)
Transitively follow the chain of pointer-type operands until reaching a SCEV that does not have a sin...
The main scalar evolution driver.
bool isKnownNonNegative(const SCEV *S)
Test if the given expression is known to be non-negative.
static void sdivrem(const APInt &LHS, const APInt &RHS, APInt &Quotient, APInt &Remainder)
const SCEV * getStepRecurrence(ScalarEvolution &SE) const
Constructs and returns the recurrence indicating how much this expression steps by.
static Value * getPointerOperand(Instruction *I)
static void dumpSmallBitVector(SmallBitVector &BV)
bool isLoopInvariant(const SCEV *S, const Loop *L)
Return true if the value of the given SCEV is unchanging in the specified loop.
static void dump(StringRef Title, SpillInfo const &Spills)
LoopT * getParentLoop() const
The two locations do not alias at all.
An instruction for reading from memory.
unsigned getBitWidth() const
Get the number of bits in this IntegerType.
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
DependenceInfo - This class is the main dependence-analysis driver.
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.
This is the base class for unary cast operator classes.
const SCEV * getStart() const
static const SCEVConstant * getConstantPart(const SCEV *Expr)
bool isKnownNonPositive(const SCEV *S)
Test if the given expression is known to be non-positive.
const SCEV * getZero(Type *Ty)
Return a SCEV for the constant 0 of a specific type.
AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB)
The main low level interface to the alias analysis implementation.
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 (third step of delinearization)...
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...
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...
static GCRegistry::Add< StatepointGC > D("statepoint-example","an example strategy for statepoint")
uint64_t getTypeSizeInBits(Type *Ty) const
Return the size in bits of the specified type, for which isSCEVable must return true.
int find_first() const
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.
Analysis pass that exposes the LoopInfo for a function.
This node represents multiplication of some number of SCEVs.
bool isKnownPredicate(ICmpInst::Predicate Pred, const SCEV *LHS, const SCEV *RHS)
Test if the given expression is known to satisfy the condition described by Pred, LHS...
bool mayReadFromMemory() const
Return true if this instruction may read memory.
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)...
static cl::opt< bool > Delinearize("da-delinearize", cl::init(false), cl::Hidden, cl::ZeroOrMore, cl::desc("Try to delinearize array references."))
static APInt ceilingOfQuotient(const APInt &A, const APInt &B)
static GCRegistry::Add< OcamlGC > B("ocaml","ocaml 3.10-compatible GC")
An instruction for storing to memory.
const SCEV * getAddRecExpr(const SCEV *Start, const SCEV *Step, const Loop *L, SCEV::NoWrapFlags Flags)
Get an add recurrence expression for the specified loop.
unsigned getDirection(unsigned Level) const override
getDirection - Returns the direction associated with a particular level.
This means that we are dealing with an entirely unknown SCEV value, and only represent it as its LLVM...
initializer< Ty > init(const Ty &Val)
std::unique_ptr< Dependence > depends(Instruction *Src, Instruction *Dst, bool PossiblyLoopIndependent)
depends - Tests for a dependence between the Src and Dst instructions.
bool isAffine() const
Return true if this represents an expression A + B*x where A and B are loop invariant values...
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
const SCEV * getOne(Type *Ty)
Return a SCEV for the constant 1 of a specific type.
* if(!EatIfPresent(lltok::kw_thread_local)) return false
ParseOptionalThreadLocal := /*empty.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs...ExtraArgs)
Get the result of an analysis pass for a given IR unit.
LLVM Basic Block Representation.
The instances of the Type class are immutable: once they are created, they are never changed...
Type * getType() const
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...
static bool isLoadOrStore(const Instruction *I)
Function * getFunction() const
A manager for alias analyses.
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)
const SCEV * getSCEVAtScope(const SCEV *S, const Loop *L)
Return a SCEV expression for the specified value at the specified scope in the program.
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)
Return LHS-RHS. Minus is represented in SCEV as A+B*-1.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE,"Assign register bank of generic virtual registers", false, false) RegBankSelect
unsigned getBitWidth() const
Return the number of bits in the APInt.
int find_next(unsigned Prev) const
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 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)
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)
const APInt & getAPInt() const
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)
This method strips off any GEP address adjustments and pointer casts from the specified value...
virtual bool isConsistent() const
isConsistent - Returns true if this dependence is consistent (occurs every time the source and destin...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool mayWriteToMemory() const
Return true if this instruction may modify memory.
APInt srem(const APInt &RHS) const
Function for signed remainder operation.
const SCEV * getSMinExpr(const SCEV *LHS, const SCEV *RHS)
static bool findGCD(unsigned Bits, const APInt &AM, const APInt &BM, const APInt &Delta, APInt &G, APInt &X, APInt &Y)
bool isKnownPositive(const SCEV *S)
Test if the given expression is known to be positive.
bool slt(const APInt &RHS) const
Signed less than comparison.
static void dumpExampleDependence(raw_ostream &OS, DependenceInfo *DA)
static APInt floorOfQuotient(const APInt &A, const APInt &B)
void print(raw_ostream &, const Module *=nullptr) const override
print - Print out the internal state of the pass.
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.
virtual unsigned getLevels() const
getLevels - Returns the number of common loops surrounding the source and destination of the dependen...
virtual bool isPeelLast(unsigned Level) const
isPeelLast - Returns true if peeling the last iteration from this loop will break this dependence...
static GCRegistry::Add< ShadowStackGC > C("shadow-stack","Very portable GC for uncooperative code generators")
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Class for arbitrary precision integers.
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.
const SCEV * getAddExpr(SmallVectorImpl< const SCEV * > &Ops, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap)
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...
Analysis pass that exposes the ScalarEvolution for a function.
static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT, AssumptionCache *AC)
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
void collectParametricTerms(const SCEV *Expr, SmallVectorImpl< const SCEV * > &Terms)
Collect parametric terms occurring in step expressions (first step of delinearization).
INITIALIZE_PASS_BEGIN(DependenceAnalysisWrapperPass,"da","Dependence Analysis", true, true) INITIALIZE_PASS_END(DependenceAnalysisWrapperPass
This class represents an analyzed expression in the program.
Represents a single loop in the control flow graph.
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.
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
void dump(raw_ostream &OS) const
dump - For debugging purposes, dumps a dependence to OS.
bool isKnownNonZero(const SCEV *S)
Test if the given expression is known to be non-zero.
DependenceInfo & getDI() const
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
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...
uint64_t getTypeStoreSize(Type *Ty) const
Returns the maximum number of bytes that may be overwritten by storing the specified type...
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)
If the specified loop has a predictable backedge-taken count, return it, otherwise return a SCEVCould...
Result run(Function &F, FunctionAnalysisManager &FAM)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static APInt getSignedMinValue(unsigned numBits)
Gets minimum signed value of APInt for a specific bit width.
const SCEV * getNegativeSCEV(const SCEV *V, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap)
Return the SCEV object corresponding to -V.
Module * getParent()
Get the module that this global value is contained inside of...
LLVM Value Representation.
bool any() const
Returns true if any bit is set.
const SCEV * getSCEV(Value *V)
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...
const SCEV * getUDivExpr(const SCEV *LHS, const SCEV *RHS)
Get a canonical unsigned division expression, or something simpler if possible.
The legacy pass manager's analysis pass to compute loop information.
void releaseMemory() override
releaseMemory() - This member can be implemented by a pass if it wants to be able to release its memo...
inst_iterator inst_end(Function *F)
A container for analyses that lazily runs them and caches their results.
bool isOutput() const
isOutput - Returns true if this is an output dependence.
const SCEV * getTruncateOrZeroExtend(const SCEV *V, Type *Ty)
Return a SCEV corresponding to a conversion of the input value to the specified type.
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml","ocaml 3.10-compatible collector")
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.
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object...
APInt abs() const
Get the absolute value;.
Dependence - This class represents a dependence between two memory memory references in a function...
const SCEV * getOperand() const
static GCRegistry::Add< ErlangGC > A("erlang","erlang-compatible garbage collector")
unsigned getLoopDepth() const
Return the nesting level of this loop.
const SCEV * getMulExpr(SmallVectorImpl< const SCEV * > &Ops, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap)
Get a canonical multiply expression, or something simpler if possible.
bool hasLoopInvariantBackedgeTakenCount(const Loop *L)
Return true if the specified loop has an analyzable loop-invariant backedge-taken count...
A special type used by analysis passes to provide an address that identifies that particular analysis...
const BasicBlock * getParent() const
This class represents a constant integer value.