61 #include "llvm/Config/llvm-config.h" 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;
199 OS <<
"'Dependence Analysis' for function '" << F.
getName() <<
"':\n";
209 return Src->mayReadFromMemory() && Dst->mayReadFromMemory();
215 return Src->mayWriteToMemory() && Dst->mayWriteToMemory();
221 return Src->mayWriteToMemory() && Dst->mayReadFromMemory();
227 return Src->mayReadFromMemory() && Dst->mayWriteToMemory();
244 bool PossiblyLoopIndependent,
245 unsigned CommonLevels)
246 :
Dependence(Source, Destination), Levels(CommonLevels),
247 LoopIndependent(PossiblyLoopIndependent) {
250 DV = make_unique<DVEntry[]>(CommonLevels);
257 assert(0 < Level && Level <= Levels &&
"Level out of range");
258 return DV[Level - 1].Direction;
264 assert(0 < Level && Level <= Levels &&
"Level out of range");
265 return DV[Level - 1].Distance;
273 assert(0 < Level && Level <= Levels &&
"Level out of range");
274 return DV[Level - 1].Scalar;
281 assert(0 < Level && Level <= Levels &&
"Level out of range");
282 return DV[Level - 1].PeelFirst;
289 assert(0 < Level && Level <= Levels &&
"Level out of range");
290 return DV[Level - 1].PeelLast;
296 assert(0 < Level && Level <= Levels &&
"Level out of range");
297 return DV[Level - 1].Splitable;
306 const SCEV *DependenceInfo::Constraint::getX()
const {
307 assert(
Kind == Point &&
"Kind should be Point");
314 const SCEV *DependenceInfo::Constraint::getY()
const {
315 assert(
Kind == Point &&
"Kind should be Point");
322 const SCEV *DependenceInfo::Constraint::getA()
const {
324 "Kind should be Line (or Distance)");
331 const SCEV *DependenceInfo::Constraint::getB()
const {
333 "Kind should be Line (or Distance)");
340 const SCEV *DependenceInfo::Constraint::getC()
const {
342 "Kind should be Line (or Distance)");
349 const SCEV *DependenceInfo::Constraint::getD()
const {
350 assert(
Kind == Distance &&
"Kind should be Distance");
351 return SE->getNegativeSCEV(
C);
356 const Loop *DependenceInfo::Constraint::getAssociatedLoop()
const {
358 "Kind should be Distance, Line, or Point");
359 return AssociatedLoop;
362 void DependenceInfo::Constraint::setPoint(
const SCEV *
X,
const SCEV *
Y,
363 const Loop *CurLoop) {
367 AssociatedLoop = CurLoop;
370 void DependenceInfo::Constraint::setLine(
const SCEV *AA,
const SCEV *BB,
371 const SCEV *CC,
const Loop *CurLoop) {
376 AssociatedLoop = CurLoop;
379 void DependenceInfo::Constraint::setDistance(
const SCEV *
D,
380 const Loop *CurLoop) {
383 B = SE->getNegativeSCEV(A);
384 C = SE->getNegativeSCEV(D);
385 AssociatedLoop = CurLoop;
388 void DependenceInfo::Constraint::setEmpty() {
Kind =
Empty; }
395 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 403 OS <<
" Point is <" << *getX() <<
", " << *getY() <<
">\n";
404 else if (isDistance())
405 OS <<
" Distance is " << *getD() <<
406 " (" << *getA() <<
"*X + " << *getB() <<
"*Y = " << *getC() <<
")\n";
408 OS <<
" Line is " << *getA() <<
"*X + " <<
409 *getB() <<
"*Y = " << *getC() <<
"\n";
423 bool DependenceInfo::intersectConstraints(Constraint *X,
const Constraint *Y) {
428 assert(!Y->isPoint() &&
"Y must not be a Point");
442 if (X->isDistance() && Y->isDistance()) {
453 if (isa<SCEVConstant>(Y->getD())) {
466 assert(!(X->isPoint() && Y->isPoint()) &&
467 "We shouldn't ever see X->isPoint() && Y->isPoint()");
469 if (X->isLine() && Y->isLine()) {
471 const SCEV *Prod1 = SE->getMulExpr(X->getA(), Y->getB());
472 const SCEV *Prod2 = SE->getMulExpr(X->getB(), Y->getA());
476 Prod1 = SE->getMulExpr(X->getC(), Y->getB());
477 Prod2 = SE->getMulExpr(X->getB(), Y->getC());
490 const SCEV *C1B2 = SE->getMulExpr(X->getC(), Y->getB());
491 const SCEV *C1A2 = SE->getMulExpr(X->getC(), Y->getA());
492 const SCEV *C2B1 = SE->getMulExpr(Y->getC(), X->getB());
493 const SCEV *C2A1 = SE->getMulExpr(Y->getC(), X->getA());
494 const SCEV *A1B2 = SE->getMulExpr(X->getA(), Y->getB());
495 const SCEV *A2B1 = SE->getMulExpr(Y->getA(), X->getB());
504 if (!C1B2_C2B1 || !C1A2_C2A1 ||
505 !A1B2_A2B1 || !A2B1_A1B2)
507 APInt Xtop = C1B2_C2B1->getAPInt();
508 APInt Xbot = A1B2_A2B1->getAPInt();
510 APInt Ybot = A2B1_A1B2->getAPInt();
521 if (Xr != 0 || Yr != 0) {
527 if (Xq.
slt(0) || Yq.
slt(0)) {
533 collectConstantUpperBound(X->getAssociatedLoop(), Prod1->
getType())) {
534 const APInt &UpperBound = CUB->getAPInt();
536 if (Xq.
sgt(UpperBound) || Yq.
sgt(UpperBound)) {
542 X->setPoint(SE->getConstant(Xq),
544 X->getAssociatedLoop());
552 assert(!(X->isLine() && Y->isPoint()) &&
"This case should never occur");
554 if (X->isPoint() && Y->isLine()) {
556 const SCEV *A1X1 = SE->getMulExpr(Y->getA(), X->getX());
557 const SCEV *B1Y1 = SE->getMulExpr(Y->getB(), X->getY());
558 const SCEV *Sum = SE->getAddExpr(A1X1, B1Y1);
579 bool Splitable =
false;
595 for (
unsigned II = 1; II <= Levels; ++II) {
671 if (
const LoadInst *LI = dyn_cast<LoadInst>(I))
672 return LI->isUnordered();
673 else if (
const StoreInst *
SI = dyn_cast<StoreInst>(I))
674 return SI->isUnordered();
729 void DependenceInfo::establishNestingLevels(
const Instruction *Src,
733 unsigned SrcLevel = LI->getLoopDepth(SrcBlock);
734 unsigned DstLevel = LI->getLoopDepth(DstBlock);
735 const Loop *SrcLoop = LI->getLoopFor(SrcBlock);
736 const Loop *DstLoop = LI->getLoopFor(DstBlock);
737 SrcLevels = SrcLevel;
738 MaxLevels = SrcLevel + DstLevel;
739 while (SrcLevel > DstLevel) {
743 while (DstLevel > SrcLevel) {
747 while (SrcLoop != DstLoop) {
752 CommonLevels = SrcLevel;
753 MaxLevels -= CommonLevels;
759 unsigned DependenceInfo::mapSrcLoop(
const Loop *SrcLoop)
const {
766 unsigned DependenceInfo::mapDstLoop(
const Loop *DstLoop)
const {
768 if (D > CommonLevels)
769 return D - CommonLevels + SrcLevels;
776 bool DependenceInfo::isLoopInvariant(
const SCEV *Expression,
777 const Loop *LoopNest)
const {
780 return SE->isLoopInvariant(Expression, LoopNest) &&
788 void DependenceInfo::collectCommonLoops(
const SCEV *Expression,
789 const Loop *LoopNest,
793 if (Level <= CommonLevels && !SE->
isLoopInvariant(Expression, LoopNest))
801 unsigned widestWidthSeen = 0;
806 for (Subscript *Pair : Pairs) {
807 const SCEV *Src = Pair->Src;
808 const SCEV *Dst = Pair->Dst;
811 if (SrcTy ==
nullptr || DstTy ==
nullptr) {
812 assert(SrcTy == DstTy &&
"This function only unify integer types and " 813 "expect Src and Dst share the same type " 821 if (DstTy->getBitWidth() > widestWidthSeen) {
822 widestWidthSeen = DstTy->getBitWidth();
828 assert(widestWidthSeen > 0);
831 for (Subscript *Pair : Pairs) {
832 const SCEV *Src = Pair->Src;
833 const SCEV *Dst = Pair->Dst;
836 if (SrcTy ==
nullptr || DstTy ==
nullptr) {
837 assert(SrcTy == DstTy &&
"This function only unify integer types and " 838 "expect Src and Dst share the same type " 844 Pair->Src = SE->getSignExtendExpr(Src, widestType);
845 if (DstTy->getBitWidth() < widestWidthSeen) {
847 Pair->Dst = SE->getSignExtendExpr(Dst, widestType);
856 void DependenceInfo::removeMatchingExtensions(Subscript *Pair) {
857 const SCEV *Src = Pair->Src;
858 const SCEV *Dst = Pair->Dst;
859 if ((isa<SCEVZeroExtendExpr>(Src) && isa<SCEVZeroExtendExpr>(Dst)) ||
860 (isa<SCEVSignExtendExpr>(Src) && isa<SCEVSignExtendExpr>(Dst))) {
864 const SCEV *DstCastOp = DstCast->getOperand();
865 if (SrcCastOp->getType() == DstCastOp->
getType()) {
866 Pair->Src = SrcCastOp;
867 Pair->Dst = DstCastOp;
875 bool DependenceInfo::checkSrcSubscript(
const SCEV *Src,
const Loop *LoopNest,
882 const SCEV *UB = SE->getBackedgeTakenCount(AddRec->
getLoop());
883 if (!isa<SCEVCouldNotCompute>(UB)) {
884 if (SE->getTypeSizeInBits(Start->
getType()) <
885 SE->getTypeSizeInBits(UB->
getType())) {
893 return checkSrcSubscript(Start, LoopNest, Loops);
900 bool DependenceInfo::checkDstSubscript(
const SCEV *Dst,
const Loop *LoopNest,
907 const SCEV *UB = SE->getBackedgeTakenCount(AddRec->
getLoop());
908 if (!isa<SCEVCouldNotCompute>(UB)) {
909 if (SE->getTypeSizeInBits(Start->
getType()) <
910 SE->getTypeSizeInBits(UB->
getType())) {
918 return checkDstSubscript(Start, LoopNest, Loops);
925 DependenceInfo::Subscript::ClassificationKind
926 DependenceInfo::classifyPair(
const SCEV *Src,
const Loop *SrcLoopNest,
927 const SCEV *Dst,
const Loop *DstLoopNest,
931 if (!checkSrcSubscript(Src, SrcLoopNest, SrcLoops))
932 return Subscript::NonLinear;
933 if (!checkDstSubscript(Dst, DstLoopNest, DstLoops))
934 return Subscript::NonLinear;
937 unsigned N = Loops.
count();
939 return Subscript::ZIV;
941 return Subscript::SIV;
942 if (N == 2 && (SrcLoops.
count() == 0 ||
943 DstLoops.
count() == 0 ||
944 (SrcLoops.
count() == 1 && DstLoops.
count() == 1)))
945 return Subscript::RDIV;
946 return Subscript::MIV;
961 const SCEV *Y)
const {
964 if ((isa<SCEVSignExtendExpr>(X) &&
965 isa<SCEVSignExtendExpr>(Y)) ||
966 (isa<SCEVZeroExtendExpr>(X) &&
967 isa<SCEVZeroExtendExpr>(Y))) {
971 const SCEV *Yop = CY->getOperand();
972 if (Xop->getType() == Yop->
getType()) {
978 if (SE->isKnownPredicate(Pred, X, Y))
985 const SCEV *Delta = SE->getMinusSCEV(X, Y);
990 return SE->isKnownNonZero(Delta);
992 return SE->isKnownNonNegative(Delta);
994 return SE->isKnownNonPositive(Delta);
996 return SE->isKnownPositive(Delta);
998 return SE->isKnownNegative(Delta);
1007 bool DependenceInfo::isKnownLessThan(
const SCEV *S,
const SCEV *
Size)
const {
1011 if (!SType || !SizeType)
1014 (SType->getBitWidth() >= SizeType->getBitWidth()) ? SType : SizeType;
1015 S = SE->getTruncateOrZeroExtend(S, MaxType);
1016 Size = SE->getTruncateOrZeroExtend(Size, MaxType);
1019 const SCEV *Bound = SE->getMinusSCEV(S, Size);
1020 if (
const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(Bound)) {
1021 if (AddRec->isAffine()) {
1022 const SCEV *BECount = SE->getBackedgeTakenCount(AddRec->getLoop());
1023 if (!isa<SCEVCouldNotCompute>(BECount)) {
1024 const SCEV *Limit = AddRec->evaluateAtIteration(BECount, *SE);
1025 if (SE->isKnownNegative(Limit))
1032 const SCEV *LimitedBound =
1033 SE->getMinusSCEV(S, SE->getSMaxExpr(Size, SE->getOne(Size->
getType())));
1034 return SE->isKnownNegative(LimitedBound);
1037 bool DependenceInfo::isKnownNonNegative(
const SCEV *S,
const Value *Ptr)
const {
1038 bool Inbounds =
false;
1039 if (
auto *SrcGEP = dyn_cast<GetElementPtrInst>(Ptr))
1040 Inbounds = SrcGEP->isInBounds();
1042 if (
const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(S)) {
1043 if (AddRec->isAffine()) {
1046 if (SE->isKnownNonNegative(AddRec->getStart()) &&
1047 SE->isKnownNonNegative(AddRec->getOperand(1)))
1053 return SE->isKnownNonNegative(S);
1063 const SCEV *DependenceInfo::collectUpperBound(
const Loop *L,
Type *
T)
const {
1064 if (SE->hasLoopInvariantBackedgeTakenCount(L)) {
1065 const SCEV *UB = SE->getBackedgeTakenCount(L);
1066 return SE->getTruncateOrZeroExtend(UB, T);
1074 const SCEVConstant *DependenceInfo::collectConstantUpperBound(
const Loop *L,
1076 if (
const SCEV *UB = collectUpperBound(L, T))
1092 bool DependenceInfo::testZIV(
const SCEV *Src,
const SCEV *Dst,
1107 Result.Consistent =
false;
1139 bool DependenceInfo::strongSIVtest(
const SCEV *Coeff,
const SCEV *SrcConst,
1140 const SCEV *DstConst,
const Loop *CurLoop,
1142 Constraint &NewConstraint)
const {
1150 ++StrongSIVapplications;
1151 assert(0 < Level && Level <= CommonLevels &&
"level out of range");
1154 const SCEV *Delta = SE->getMinusSCEV(SrcConst, DstConst);
1159 if (
const SCEV *UpperBound = collectUpperBound(CurLoop, Delta->
getType())) {
1162 const SCEV *AbsDelta =
1163 SE->isKnownNonNegative(Delta) ? Delta : SE->getNegativeSCEV(Delta);
1164 const SCEV *AbsCoeff =
1165 SE->isKnownNonNegative(Coeff) ? Coeff : SE->getNegativeSCEV(Coeff);
1166 const SCEV *Product = SE->getMulExpr(UpperBound, AbsCoeff);
1169 ++StrongSIVindependence;
1170 ++StrongSIVsuccesses;
1176 if (isa<SCEVConstant>(Delta) && isa<SCEVConstant>(Coeff)) {
1177 APInt ConstDelta = cast<SCEVConstant>(Delta)->getAPInt();
1178 APInt ConstCoeff = cast<SCEVConstant>(Coeff)->getAPInt();
1179 APInt Distance = ConstDelta;
1180 APInt Remainder = ConstDelta;
1185 if (Remainder != 0) {
1187 ++StrongSIVindependence;
1188 ++StrongSIVsuccesses;
1191 Result.DV[
Level].Distance = SE->getConstant(Distance);
1192 NewConstraint.setDistance(SE->getConstant(Distance), CurLoop);
1193 if (Distance.
sgt(0))
1195 else if (Distance.
slt(0))
1199 ++StrongSIVsuccesses;
1201 else if (Delta->
isZero()) {
1203 Result.DV[
Level].Distance = Delta;
1204 NewConstraint.setDistance(Delta, CurLoop);
1206 ++StrongSIVsuccesses;
1209 if (Coeff->
isOne()) {
1211 Result.DV[
Level].Distance = Delta;
1212 NewConstraint.setDistance(Delta, CurLoop);
1215 Result.Consistent =
false;
1216 NewConstraint.setLine(Coeff,
1217 SE->getNegativeSCEV(Coeff),
1218 SE->getNegativeSCEV(Delta), CurLoop);
1222 bool DeltaMaybeZero = !SE->isKnownNonZero(Delta);
1223 bool DeltaMaybePositive = !SE->isKnownNonPositive(Delta);
1224 bool DeltaMaybeNegative = !SE->isKnownNonNegative(Delta);
1225 bool CoeffMaybePositive = !SE->isKnownNonPositive(Coeff);
1226 bool CoeffMaybeNegative = !SE->isKnownNonNegative(Coeff);
1231 if ((DeltaMaybePositive && CoeffMaybePositive) ||
1232 (DeltaMaybeNegative && CoeffMaybeNegative))
1236 if ((DeltaMaybeNegative && CoeffMaybePositive) ||
1237 (DeltaMaybePositive && CoeffMaybeNegative))
1239 if (NewDirection < Result.DV[Level].Direction)
1240 ++StrongSIVsuccesses;
1241 Result.DV[
Level].Direction &= NewDirection;
1275 bool DependenceInfo::weakCrossingSIVtest(
1276 const SCEV *Coeff,
const SCEV *SrcConst,
const SCEV *DstConst,
1278 Constraint &NewConstraint,
const SCEV *&SplitIter)
const {
1283 ++WeakCrossingSIVapplications;
1284 assert(0 < Level && Level <= CommonLevels &&
"Level out of range");
1286 Result.Consistent =
false;
1287 const SCEV *Delta = SE->getMinusSCEV(DstConst, SrcConst);
1289 NewConstraint.setLine(Coeff, Coeff, Delta, CurLoop);
1293 ++WeakCrossingSIVsuccesses;
1294 if (!Result.DV[Level].Direction) {
1295 ++WeakCrossingSIVindependence;
1298 Result.DV[
Level].Distance = Delta;
1305 Result.DV[
Level].Splitable =
true;
1306 if (SE->isKnownNegative(ConstCoeff)) {
1309 "dynamic cast of negative of ConstCoeff should yield constant");
1310 Delta = SE->getNegativeSCEV(Delta);
1312 assert(SE->isKnownPositive(ConstCoeff) &&
"ConstCoeff should be positive");
1315 SplitIter = SE->getUDivExpr(
1316 SE->getSMaxExpr(SE->getZero(Delta->
getType()), Delta),
1317 SE->getMulExpr(SE->getConstant(Delta->
getType(), 2), ConstCoeff));
1328 if (SE->isKnownNegative(Delta)) {
1330 ++WeakCrossingSIVindependence;
1331 ++WeakCrossingSIVsuccesses;
1337 if (
const SCEV *UpperBound = collectUpperBound(CurLoop, Delta->
getType())) {
1339 const SCEV *ConstantTwo = SE->getConstant(UpperBound->getType(), 2);
1340 const SCEV *ML = SE->getMulExpr(SE->getMulExpr(ConstCoeff, UpperBound),
1345 ++WeakCrossingSIVindependence;
1346 ++WeakCrossingSIVsuccesses;
1353 ++WeakCrossingSIVsuccesses;
1354 if (!Result.DV[Level].Direction) {
1355 ++WeakCrossingSIVindependence;
1358 Result.DV[
Level].Splitable =
false;
1359 Result.DV[
Level].Distance = SE->getZero(Delta->
getType());
1367 APInt Distance = APDelta;
1368 APInt Remainder = APDelta;
1371 if (Remainder != 0) {
1373 ++WeakCrossingSIVindependence;
1374 ++WeakCrossingSIVsuccesses;
1381 Remainder = Distance.
srem(Two);
1383 if (Remainder != 0) {
1386 ++WeakCrossingSIVsuccesses;
1404 APInt A0(Bits, 1,
true), A1(Bits, 0,
true);
1405 APInt B0(Bits, 0,
true),
B1(Bits, 1,
true);
1412 APInt A2 = A0 - Q*A1; A0 = A1; A1 = A2;
1413 APInt B2 = B0 - Q*B1; B0 = B1; B1 = B2;
1419 X = AM.
slt(0) ? -A1 : A1;
1420 Y = BM.
slt(0) ? B1 : -B1;
1438 if ((A.
sgt(0) && B.
sgt(0)) ||
1451 if ((A.
sgt(0) && B.
sgt(0)) ||
1461 return A.
sgt(B) ? A :
B;
1467 return A.
slt(B) ? A :
B;
1486 bool DependenceInfo::exactSIVtest(
const SCEV *SrcCoeff,
const SCEV *DstCoeff,
1487 const SCEV *SrcConst,
const SCEV *DstConst,
1488 const Loop *CurLoop,
unsigned Level,
1490 Constraint &NewConstraint)
const {
1492 LLVM_DEBUG(
dbgs() <<
"\t SrcCoeff = " << *SrcCoeff <<
" = AM\n");
1493 LLVM_DEBUG(
dbgs() <<
"\t DstCoeff = " << *DstCoeff <<
" = BM\n");
1496 ++ExactSIVapplications;
1497 assert(0 < Level && Level <= CommonLevels &&
"Level out of range");
1499 Result.Consistent =
false;
1500 const SCEV *Delta = SE->getMinusSCEV(DstConst, SrcConst);
1502 NewConstraint.setLine(SrcCoeff, SE->getNegativeSCEV(DstCoeff),
1507 if (!ConstDelta || !ConstSrcCoeff || !ConstDstCoeff)
1512 APInt AM = ConstSrcCoeff->getAPInt();
1513 APInt BM = ConstDstCoeff->getAPInt();
1517 ++ExactSIVindependence;
1518 ++ExactSIVsuccesses;
1525 APInt UM(Bits, 1,
true);
1526 bool UMvalid =
false;
1529 collectConstantUpperBound(CurLoop, Delta->
getType())) {
1530 UM = CUB->getAPInt();
1576 ++ExactSIVindependence;
1577 ++ExactSIVsuccesses;
1599 ++ExactSIVsuccesses;
1625 ++ExactSIVsuccesses;
1642 ++ExactSIVsuccesses;
1646 Result.DV[
Level].Direction &= NewDirection;
1648 ++ExactSIVindependence;
1660 return ConstDividend.
srem(ConstDivisor) == 0;
1695 bool DependenceInfo::weakZeroSrcSIVtest(
const SCEV *DstCoeff,
1696 const SCEV *SrcConst,
1697 const SCEV *DstConst,
1698 const Loop *CurLoop,
unsigned Level,
1700 Constraint &NewConstraint)
const {
1708 ++WeakZeroSIVapplications;
1709 assert(0 < Level && Level <= MaxLevels &&
"Level out of range");
1711 Result.Consistent =
false;
1712 const SCEV *Delta = SE->getMinusSCEV(SrcConst, DstConst);
1713 NewConstraint.setLine(SE->getZero(Delta->
getType()), DstCoeff, Delta,
1717 if (Level < CommonLevels) {
1719 Result.DV[
Level].PeelFirst =
true;
1720 ++WeakZeroSIVsuccesses;
1727 const SCEV *AbsCoeff =
1728 SE->isKnownNegative(ConstCoeff) ?
1729 SE->getNegativeSCEV(ConstCoeff) : ConstCoeff;
1730 const SCEV *NewDelta =
1731 SE->isKnownNegative(ConstCoeff) ? SE->getNegativeSCEV(Delta) : Delta;
1735 if (
const SCEV *UpperBound = collectUpperBound(CurLoop, Delta->
getType())) {
1737 const SCEV *Product = SE->getMulExpr(AbsCoeff, UpperBound);
1739 ++WeakZeroSIVindependence;
1740 ++WeakZeroSIVsuccesses;
1745 if (Level < CommonLevels) {
1747 Result.DV[
Level].PeelLast =
true;
1748 ++WeakZeroSIVsuccesses;
1756 if (SE->isKnownNegative(NewDelta)) {
1758 ++WeakZeroSIVindependence;
1759 ++WeakZeroSIVsuccesses;
1764 if (isa<SCEVConstant>(Delta) &&
1766 ++WeakZeroSIVindependence;
1767 ++WeakZeroSIVsuccesses;
1805 bool DependenceInfo::weakZeroDstSIVtest(
const SCEV *SrcCoeff,
1806 const SCEV *SrcConst,
1807 const SCEV *DstConst,
1808 const Loop *CurLoop,
unsigned Level,
1810 Constraint &NewConstraint)
const {
1817 ++WeakZeroSIVapplications;
1818 assert(0 < Level && Level <= SrcLevels &&
"Level out of range");
1820 Result.Consistent =
false;
1821 const SCEV *Delta = SE->getMinusSCEV(DstConst, SrcConst);
1822 NewConstraint.setLine(SrcCoeff, SE->getZero(Delta->
getType()), Delta,
1826 if (Level < CommonLevels) {
1828 Result.DV[
Level].PeelFirst =
true;
1829 ++WeakZeroSIVsuccesses;
1836 const SCEV *AbsCoeff =
1837 SE->isKnownNegative(ConstCoeff) ?
1838 SE->getNegativeSCEV(ConstCoeff) : ConstCoeff;
1839 const SCEV *NewDelta =
1840 SE->isKnownNegative(ConstCoeff) ? SE->getNegativeSCEV(Delta) : Delta;
1844 if (
const SCEV *UpperBound = collectUpperBound(CurLoop, Delta->
getType())) {
1846 const SCEV *Product = SE->getMulExpr(AbsCoeff, UpperBound);
1848 ++WeakZeroSIVindependence;
1849 ++WeakZeroSIVsuccesses;
1854 if (Level < CommonLevels) {
1856 Result.DV[
Level].PeelLast =
true;
1857 ++WeakZeroSIVsuccesses;
1865 if (SE->isKnownNegative(NewDelta)) {
1867 ++WeakZeroSIVindependence;
1868 ++WeakZeroSIVsuccesses;
1873 if (isa<SCEVConstant>(Delta) &&
1875 ++WeakZeroSIVindependence;
1876 ++WeakZeroSIVsuccesses;
1890 bool DependenceInfo::exactRDIVtest(
const SCEV *SrcCoeff,
const SCEV *DstCoeff,
1891 const SCEV *SrcConst,
const SCEV *DstConst,
1892 const Loop *SrcLoop,
const Loop *DstLoop,
1895 LLVM_DEBUG(
dbgs() <<
"\t SrcCoeff = " << *SrcCoeff <<
" = AM\n");
1896 LLVM_DEBUG(
dbgs() <<
"\t DstCoeff = " << *DstCoeff <<
" = BM\n");
1899 ++ExactRDIVapplications;
1900 Result.Consistent =
false;
1901 const SCEV *Delta = SE->getMinusSCEV(DstConst, SrcConst);
1906 if (!ConstDelta || !ConstSrcCoeff || !ConstDstCoeff)
1911 APInt AM = ConstSrcCoeff->getAPInt();
1912 APInt BM = ConstDstCoeff->getAPInt();
1916 ++ExactRDIVindependence;
1923 APInt SrcUM(Bits, 1,
true);
1924 bool SrcUMvalid =
false;
1927 collectConstantUpperBound(SrcLoop, Delta->
getType())) {
1928 SrcUM = UpperBound->getAPInt();
1933 APInt DstUM(Bits, 1,
true);
1934 bool DstUMvalid =
false;
1937 collectConstantUpperBound(DstLoop, Delta->
getType())) {
1938 DstUM = UpperBound->getAPInt();
1984 ++ExactRDIVindependence;
2031 bool DependenceInfo::symbolicRDIVtest(
const SCEV *A1,
const SCEV *A2,
2034 const Loop *Loop2)
const {
2035 ++SymbolicRDIVapplications;
2042 const SCEV *N1 = collectUpperBound(Loop1, A1->
getType());
2043 const SCEV *N2 = collectUpperBound(Loop2, A1->
getType());
2046 const SCEV *C2_C1 = SE->getMinusSCEV(C2, C1);
2047 const SCEV *C1_C2 = SE->getMinusSCEV(C1, C2);
2050 if (SE->isKnownNonNegative(A1)) {
2051 if (SE->isKnownNonNegative(A2)) {
2055 const SCEV *A1N1 = SE->getMulExpr(A1, N1);
2058 ++SymbolicRDIVindependence;
2064 const SCEV *A2N2 = SE->getMulExpr(A2, N2);
2067 ++SymbolicRDIVindependence;
2072 else if (SE->isKnownNonPositive(A2)) {
2076 const SCEV *A1N1 = SE->getMulExpr(A1, N1);
2077 const SCEV *A2N2 = SE->getMulExpr(A2, N2);
2078 const SCEV *A1N1_A2N2 = SE->getMinusSCEV(A1N1, A2N2);
2079 LLVM_DEBUG(
dbgs() <<
"\t A1*N1 - A2*N2 = " << *A1N1_A2N2 <<
"\n");
2081 ++SymbolicRDIVindependence;
2086 if (SE->isKnownNegative(C2_C1)) {
2087 ++SymbolicRDIVindependence;
2092 else if (SE->isKnownNonPositive(A1)) {
2093 if (SE->isKnownNonNegative(A2)) {
2097 const SCEV *A1N1 = SE->getMulExpr(A1, N1);
2098 const SCEV *A2N2 = SE->getMulExpr(A2, N2);
2099 const SCEV *A1N1_A2N2 = SE->getMinusSCEV(A1N1, A2N2);
2100 LLVM_DEBUG(
dbgs() <<
"\t A1*N1 - A2*N2 = " << *A1N1_A2N2 <<
"\n");
2102 ++SymbolicRDIVindependence;
2107 if (SE->isKnownPositive(C2_C1)) {
2108 ++SymbolicRDIVindependence;
2112 else if (SE->isKnownNonPositive(A2)) {
2116 const SCEV *A1N1 = SE->getMulExpr(A1, N1);
2119 ++SymbolicRDIVindependence;
2125 const SCEV *A2N2 = SE->getMulExpr(A2, N2);
2128 ++SymbolicRDIVindependence;
2146 bool DependenceInfo::testSIV(
const SCEV *Src,
const SCEV *Dst,
unsigned &Level,
2148 const SCEV *&SplitIter)
const {
2153 if (SrcAddRec && DstAddRec) {
2155 const SCEV *DstConst = DstAddRec->getStart();
2157 const SCEV *DstCoeff = DstAddRec->getStepRecurrence(*SE);
2159 assert(CurLoop == DstAddRec->getLoop() &&
2160 "both loops in SIV should be same");
2161 Level = mapSrcLoop(CurLoop);
2163 if (SrcCoeff == DstCoeff)
2164 disproven = strongSIVtest(SrcCoeff, SrcConst, DstConst, CurLoop,
2165 Level, Result, NewConstraint);
2166 else if (SrcCoeff == SE->getNegativeSCEV(DstCoeff))
2167 disproven = weakCrossingSIVtest(SrcCoeff, SrcConst, DstConst, CurLoop,
2168 Level, Result, NewConstraint, SplitIter);
2170 disproven = exactSIVtest(SrcCoeff, DstCoeff, SrcConst, DstConst, CurLoop,
2171 Level, Result, NewConstraint);
2173 gcdMIVtest(Src, Dst, Result) ||
2174 symbolicRDIVtest(SrcCoeff, DstCoeff, SrcConst, DstConst, CurLoop, CurLoop);
2179 const SCEV *DstConst = Dst;
2181 Level = mapSrcLoop(CurLoop);
2182 return weakZeroDstSIVtest(SrcCoeff, SrcConst, DstConst, CurLoop,
2183 Level, Result, NewConstraint) ||
2184 gcdMIVtest(Src, Dst, Result);
2187 const SCEV *DstConst = DstAddRec->getStart();
2188 const SCEV *DstCoeff = DstAddRec->getStepRecurrence(*SE);
2189 const SCEV *SrcConst = Src;
2190 const Loop *CurLoop = DstAddRec->getLoop();
2191 Level = mapDstLoop(CurLoop);
2192 return weakZeroSrcSIVtest(DstCoeff, SrcConst, DstConst,
2193 CurLoop, Level, Result, NewConstraint) ||
2194 gcdMIVtest(Src, Dst, Result);
2214 bool DependenceInfo::testRDIV(
const SCEV *Src,
const SCEV *Dst,
2222 const SCEV *SrcConst, *DstConst;
2223 const SCEV *SrcCoeff, *DstCoeff;
2224 const Loop *SrcLoop, *DstLoop;
2230 if (SrcAddRec && DstAddRec) {
2233 SrcLoop = SrcAddRec->
getLoop();
2234 DstConst = DstAddRec->getStart();
2235 DstCoeff = DstAddRec->getStepRecurrence(*SE);
2236 DstLoop = DstAddRec->getLoop();
2238 else if (SrcAddRec) {
2240 dyn_cast<SCEVAddRecExpr>(SrcAddRec->
getStart())) {
2241 SrcConst = tmpAddRec->getStart();
2242 SrcCoeff = tmpAddRec->getStepRecurrence(*SE);
2243 SrcLoop = tmpAddRec->getLoop();
2246 DstLoop = SrcAddRec->
getLoop();
2251 else if (DstAddRec) {
2253 dyn_cast<SCEVAddRecExpr>(DstAddRec->getStart())) {
2254 DstConst = tmpAddRec->getStart();
2255 DstCoeff = tmpAddRec->getStepRecurrence(*SE);
2256 DstLoop = tmpAddRec->getLoop();
2258 SrcCoeff = SE->getNegativeSCEV(DstAddRec->getStepRecurrence(*SE));
2259 SrcLoop = DstAddRec->getLoop();
2266 return exactRDIVtest(SrcCoeff, DstCoeff,
2270 gcdMIVtest(Src, Dst, Result) ||
2271 symbolicRDIVtest(SrcCoeff, DstCoeff,
2280 bool DependenceInfo::testMIV(
const SCEV *Src,
const SCEV *Dst,
2285 Result.Consistent =
false;
2286 return gcdMIVtest(Src, Dst, Result) ||
2287 banerjeeMIVtest(Src, Dst, Loops, Result);
2295 if (
const auto *
Constant = dyn_cast<SCEVConstant>(Expr))
2297 else if (
const auto *Product = dyn_cast<SCEVMulExpr>(Expr))
2298 if (
const auto *
Constant = dyn_cast<SCEVConstant>(Product->getOperand(0)))
2322 bool DependenceInfo::gcdMIVtest(
const SCEV *Src,
const SCEV *Dst,
2326 unsigned BitWidth = SE->getTypeSizeInBits(Src->
getType());
2333 const SCEV *Coefficients = Src;
2335 dyn_cast<SCEVAddRecExpr>(Coefficients)) {
2336 const SCEV *Coeff = AddRec->getStepRecurrence(*SE);
2344 Coefficients = AddRec->getStart();
2346 const SCEV *SrcConst = Coefficients;
2354 dyn_cast<SCEVAddRecExpr>(Coefficients)) {
2355 const SCEV *Coeff = AddRec->getStepRecurrence(*SE);
2363 Coefficients = AddRec->getStart();
2365 const SCEV *DstConst = Coefficients;
2368 const SCEV *Delta = SE->getMinusSCEV(DstConst, SrcConst);
2371 if (
const SCEVAddExpr *Sum = dyn_cast<SCEVAddExpr>(Delta)) {
2373 for (
unsigned Op = 0, Ops = Sum->getNumOperands();
Op < Ops;
Op++) {
2374 const SCEV *Operand = Sum->getOperand(
Op);
2375 if (isa<SCEVConstant>(Operand)) {
2376 assert(!Constant &&
"Surprised to find multiple constants");
2377 Constant = cast<SCEVConstant>(Operand);
2379 else if (
const SCEVMulExpr *Product = dyn_cast<SCEVMulExpr>(Operand)) {
2387 ConstOpValue.
abs());
2395 APInt ConstDelta = cast<SCEVConstant>(Constant)->getAPInt();
2397 if (ConstDelta == 0)
2401 APInt Remainder = ConstDelta.
srem(RunningGCD);
2402 if (Remainder != 0) {
2421 bool Improved =
false;
2424 dyn_cast<SCEVAddRecExpr>(Coefficients)) {
2425 Coefficients = AddRec->getStart();
2426 const Loop *CurLoop = AddRec->getLoop();
2427 RunningGCD = ExtraGCD;
2428 const SCEV *SrcCoeff = AddRec->getStepRecurrence(*SE);
2429 const SCEV *DstCoeff = SE->getMinusSCEV(SrcCoeff, SrcCoeff);
2430 const SCEV *Inner = Src;
2431 while (RunningGCD != 1 && isa<SCEVAddRecExpr>(Inner)) {
2432 AddRec = cast<SCEVAddRecExpr>(Inner);
2433 const SCEV *Coeff = AddRec->getStepRecurrence(*SE);
2434 if (CurLoop == AddRec->getLoop())
2445 Inner = AddRec->getStart();
2448 while (RunningGCD != 1 && isa<SCEVAddRecExpr>(Inner)) {
2449 AddRec = cast<SCEVAddRecExpr>(Inner);
2450 const SCEV *Coeff = AddRec->getStepRecurrence(*SE);
2451 if (CurLoop == AddRec->getLoop())
2462 Inner = AddRec->getStart();
2464 Delta = SE->getMinusSCEV(SrcCoeff, DstCoeff);
2475 if (RunningGCD != 0) {
2476 Remainder = ConstDelta.
srem(RunningGCD);
2478 if (Remainder != 0) {
2479 unsigned Level = mapSrcLoop(CurLoop);
2525 bool DependenceInfo::banerjeeMIVtest(
const SCEV *Src,
const SCEV *Dst,
2529 ++BanerjeeApplications;
2532 CoefficientInfo *A = collectCoeffInfo(Src,
true, A0);
2535 CoefficientInfo *
B = collectCoeffInfo(Dst,
false, B0);
2536 BoundInfo *Bound =
new BoundInfo[MaxLevels + 1];
2537 const SCEV *Delta = SE->getMinusSCEV(B0, A0);
2542 for (
unsigned K = 1; K <= MaxLevels; ++K) {
2543 Bound[K].Iterations = A[K].Iterations ? A[K].Iterations : B[K].Iterations;
2546 findBoundsALL(A, B, Bound, K);
2553 if (Bound[K].
Upper[Dependence::DVEntry::ALL])
2561 bool Disproved =
false;
2564 unsigned DepthExpanded = 0;
2565 unsigned NewDeps = exploreDirections(1, A, B, Bound,
2566 Loops, DepthExpanded, Delta);
2568 bool Improved =
false;
2569 for (
unsigned K = 1; K <= CommonLevels; ++K) {
2571 unsigned Old = Result.DV[K - 1].Direction;
2572 Result.DV[K - 1].Direction = Old & Bound[K].DirSet;
2573 Improved |= Old != Result.DV[K - 1].Direction;
2574 if (!Result.DV[K - 1].Direction) {
2582 ++BanerjeeSuccesses;
2585 ++BanerjeeIndependence;
2590 ++BanerjeeIndependence;
2605 unsigned DependenceInfo::exploreDirections(
unsigned Level, CoefficientInfo *A,
2606 CoefficientInfo *
B, BoundInfo *Bound,
2608 unsigned &DepthExpanded,
2609 const SCEV *Delta)
const {
2610 if (Level > CommonLevels) {
2613 for (
unsigned K = 1; K <= CommonLevels; ++K) {
2615 Bound[K].DirSet |= Bound[K].Direction;
2617 switch (Bound[K].Direction) {
2640 if (Level > DepthExpanded) {
2641 DepthExpanded =
Level;
2643 findBoundsLT(A, B, Bound, Level);
2644 findBoundsGT(A, B, Bound, Level);
2645 findBoundsEQ(A, B, Bound, Level);
2654 if (Bound[Level].
Upper[Dependence::DVEntry::LT])
2665 if (Bound[Level].
Upper[Dependence::DVEntry::EQ])
2676 if (Bound[Level].
Upper[Dependence::DVEntry::GT])
2684 unsigned NewDeps = 0;
2688 NewDeps += exploreDirections(Level + 1, A, B, Bound,
2689 Loops, DepthExpanded, Delta);
2693 NewDeps += exploreDirections(Level + 1, A, B, Bound,
2694 Loops, DepthExpanded, Delta);
2698 NewDeps += exploreDirections(Level + 1, A, B, Bound,
2699 Loops, DepthExpanded, Delta);
2705 return exploreDirections(Level + 1, A, B, Bound, Loops, DepthExpanded, Delta);
2710 bool DependenceInfo::testBounds(
unsigned char DirKind,
unsigned Level,
2711 BoundInfo *Bound,
const SCEV *Delta)
const {
2712 Bound[
Level].Direction = DirKind;
2713 if (
const SCEV *LowerBound = getLowerBound(Bound))
2716 if (
const SCEV *UpperBound = getUpperBound(Bound))
2738 void DependenceInfo::findBoundsALL(CoefficientInfo *A, CoefficientInfo *B,
2739 BoundInfo *Bound,
unsigned K)
const {
2742 if (Bound[K].Iterations) {
2744 SE->getMulExpr(SE->getMinusSCEV(A[K].NegPart, B[K].PosPart),
2745 Bound[K].Iterations);
2747 SE->getMulExpr(SE->getMinusSCEV(A[K].PosPart, B[K].NegPart),
2748 Bound[K].Iterations);
2754 SE->getZero(A[K].Coeff->getType());
2757 SE->getZero(A[K].Coeff->getType());
2777 void DependenceInfo::findBoundsEQ(CoefficientInfo *A, CoefficientInfo *B,
2778 BoundInfo *Bound,
unsigned K)
const {
2781 if (Bound[K].Iterations) {
2782 const SCEV *Delta = SE->getMinusSCEV(A[K].Coeff, B[K].Coeff);
2783 const SCEV *NegativePart = getNegativePart(Delta);
2785 SE->getMulExpr(NegativePart, Bound[K].Iterations);
2786 const SCEV *PositivePart = getPositivePart(Delta);
2788 SE->getMulExpr(PositivePart, Bound[K].Iterations);
2793 const SCEV *Delta = SE->getMinusSCEV(A[K].Coeff, B[K].Coeff);
2794 const SCEV *NegativePart = getNegativePart(Delta);
2795 if (NegativePart->
isZero())
2797 const SCEV *PositivePart = getPositivePart(Delta);
2798 if (PositivePart->
isZero())
2817 void DependenceInfo::findBoundsLT(CoefficientInfo *A, CoefficientInfo *B,
2818 BoundInfo *Bound,
unsigned K)
const {
2821 if (Bound[K].Iterations) {
2822 const SCEV *Iter_1 = SE->getMinusSCEV(
2823 Bound[K].Iterations, SE->getOne(Bound[K].Iterations->getType()));
2824 const SCEV *NegPart =
2825 getNegativePart(SE->getMinusSCEV(A[K].NegPart, B[K].Coeff));
2827 SE->getMinusSCEV(SE->getMulExpr(NegPart, Iter_1), B[K].Coeff);
2828 const SCEV *PosPart =
2829 getPositivePart(SE->getMinusSCEV(A[K].PosPart, B[K].Coeff));
2831 SE->getMinusSCEV(SE->getMulExpr(PosPart, Iter_1), B[K].Coeff);
2836 const SCEV *NegPart =
2837 getNegativePart(SE->getMinusSCEV(A[K].NegPart, B[K].Coeff));
2840 const SCEV *PosPart =
2841 getPositivePart(SE->getMinusSCEV(A[K].PosPart, B[K].Coeff));
2861 void DependenceInfo::findBoundsGT(CoefficientInfo *A, CoefficientInfo *B,
2862 BoundInfo *Bound,
unsigned K)
const {
2865 if (Bound[K].Iterations) {
2866 const SCEV *Iter_1 = SE->getMinusSCEV(
2867 Bound[K].Iterations, SE->getOne(Bound[K].Iterations->getType()));
2868 const SCEV *NegPart =
2869 getNegativePart(SE->getMinusSCEV(A[K].Coeff, B[K].PosPart));
2871 SE->getAddExpr(SE->getMulExpr(NegPart, Iter_1), A[K].Coeff);
2872 const SCEV *PosPart =
2873 getPositivePart(SE->getMinusSCEV(A[K].Coeff, B[K].NegPart));
2875 SE->getAddExpr(SE->getMulExpr(PosPart, Iter_1), A[K].Coeff);
2880 const SCEV *NegPart = getNegativePart(SE->getMinusSCEV(A[K].Coeff, B[K].PosPart));
2883 const SCEV *PosPart = getPositivePart(SE->getMinusSCEV(A[K].Coeff, B[K].NegPart));
2891 const SCEV *DependenceInfo::getPositivePart(
const SCEV *X)
const {
2892 return SE->getSMaxExpr(X, SE->getZero(X->
getType()));
2897 const SCEV *DependenceInfo::getNegativePart(
const SCEV *X)
const {
2898 return SE->getSMinExpr(X, SE->getZero(X->
getType()));
2905 DependenceInfo::CoefficientInfo *
2906 DependenceInfo::collectCoeffInfo(
const SCEV *Subscript,
bool SrcFlag,
2908 const SCEV *Zero = SE->getZero(Subscript->
getType());
2909 CoefficientInfo *CI =
new CoefficientInfo[MaxLevels + 1];
2910 for (
unsigned K = 1; K <= MaxLevels; ++K) {
2912 CI[K].PosPart = Zero;
2913 CI[K].NegPart = Zero;
2914 CI[K].Iterations =
nullptr;
2916 while (
const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(Subscript)) {
2917 const Loop *L = AddRec->getLoop();
2918 unsigned K = SrcFlag ? mapSrcLoop(L) : mapDstLoop(L);
2919 CI[K].Coeff = AddRec->getStepRecurrence(*SE);
2920 CI[K].PosPart = getPositivePart(CI[K].Coeff);
2921 CI[K].NegPart = getNegativePart(CI[K].Coeff);
2922 CI[K].Iterations = collectUpperBound(L, Subscript->
getType());
2923 Subscript = AddRec->getStart();
2925 Constant = Subscript;
2928 for (
unsigned K = 1; K <= MaxLevels; ++K) {
2935 if (CI[K].Iterations)
2951 const SCEV *DependenceInfo::getLowerBound(BoundInfo *Bound)
const {
2952 const SCEV *Sum = Bound[1].Lower[Bound[1].Direction];
2953 for (
unsigned K = 2; Sum && K <= MaxLevels; ++K) {
2954 if (Bound[K].
Lower[Bound[K].Direction])
2955 Sum = SE->getAddExpr(Sum, Bound[K].
Lower[Bound[K].Direction]);
2967 const SCEV *DependenceInfo::getUpperBound(BoundInfo *Bound)
const {
2968 const SCEV *Sum = Bound[1].Upper[Bound[1].Direction];
2969 for (
unsigned K = 2; Sum && K <= MaxLevels; ++K) {
2970 if (Bound[K].
Upper[Bound[K].Direction])
2971 Sum = SE->getAddExpr(Sum, Bound[K].
Upper[Bound[K].Direction]);
2988 const SCEV *DependenceInfo::findCoefficient(
const SCEV *Expr,
2989 const Loop *TargetLoop)
const {
2992 return SE->getZero(Expr->
getType());
2993 if (AddRec->
getLoop() == TargetLoop)
2995 return findCoefficient(AddRec->
getStart(), TargetLoop);
3004 const SCEV *DependenceInfo::zeroCoefficient(
const SCEV *Expr,
3005 const Loop *TargetLoop)
const {
3009 if (AddRec->
getLoop() == TargetLoop)
3011 return SE->getAddRecExpr(zeroCoefficient(AddRec->
getStart(), TargetLoop),
3023 const SCEV *DependenceInfo::addToCoefficient(
const SCEV *Expr,
3024 const Loop *TargetLoop,
3028 return SE->getAddRecExpr(Expr,
3032 if (AddRec->
getLoop() == TargetLoop) {
3036 return SE->getAddRecExpr(AddRec->
getStart(),
3041 if (SE->isLoopInvariant(AddRec, TargetLoop))
3043 return SE->getAddRecExpr(
3044 addToCoefficient(AddRec->
getStart(), TargetLoop, Value),
3060 bool DependenceInfo::propagate(
const SCEV *&Src,
const SCEV *&Dst,
3064 bool Result =
false;
3065 for (
unsigned LI : Loops.
set_bits()) {
3068 if (Constraints[LI].isDistance())
3069 Result |= propagateDistance(Src, Dst, Constraints[LI], Consistent);
3070 else if (Constraints[LI].isLine())
3071 Result |= propagateLine(Src, Dst, Constraints[LI], Consistent);
3072 else if (Constraints[LI].isPoint())
3073 Result |= propagatePoint(Src, Dst, Constraints[LI]);
3084 bool DependenceInfo::propagateDistance(
const SCEV *&Src,
const SCEV *&Dst,
3085 Constraint &CurConstraint,
3087 const Loop *CurLoop = CurConstraint.getAssociatedLoop();
3089 const SCEV *A_K = findCoefficient(Src, CurLoop);
3092 const SCEV *DA_K = SE->getMulExpr(A_K, CurConstraint.getD());
3093 Src = SE->getMinusSCEV(Src, DA_K);
3094 Src = zeroCoefficient(Src, CurLoop);
3097 Dst = addToCoefficient(Dst, CurLoop, SE->getNegativeSCEV(A_K));
3099 if (!findCoefficient(Dst, CurLoop)->
isZero())
3110 bool DependenceInfo::propagateLine(
const SCEV *&Src,
const SCEV *&Dst,
3111 Constraint &CurConstraint,
3113 const Loop *CurLoop = CurConstraint.getAssociatedLoop();
3114 const SCEV *A = CurConstraint.getA();
3115 const SCEV *B = CurConstraint.getB();
3116 const SCEV *
C = CurConstraint.getC();
3117 LLVM_DEBUG(
dbgs() <<
"\t\tA = " << *A <<
", B = " << *B <<
", C = " << *C
3124 if (!Bconst || !Cconst)
return false;
3126 APInt Charlie = Cconst->getAPInt();
3128 assert(Charlie.
srem(Beta) == 0 &&
"C should be evenly divisible by B");
3129 const SCEV *AP_K = findCoefficient(Dst, CurLoop);
3131 Src = SE->getMinusSCEV(Src, SE->getMulExpr(AP_K, SE->getConstant(CdivB)));
3132 Dst = zeroCoefficient(Dst, CurLoop);
3133 if (!findCoefficient(Src, CurLoop)->
isZero())
3139 if (!Aconst || !Cconst)
return false;
3141 APInt Charlie = Cconst->getAPInt();
3143 assert(Charlie.
srem(Alpha) == 0 &&
"C should be evenly divisible by A");
3144 const SCEV *A_K = findCoefficient(Src, CurLoop);
3145 Src = SE->getAddExpr(Src, SE->getMulExpr(A_K, SE->getConstant(CdivA)));
3146 Src = zeroCoefficient(Src, CurLoop);
3147 if (!findCoefficient(Dst, CurLoop)->
isZero())
3153 if (!Aconst || !Cconst)
return false;
3155 APInt Charlie = Cconst->getAPInt();
3157 assert(Charlie.
srem(Alpha) == 0 &&
"C should be evenly divisible by A");
3158 const SCEV *A_K = findCoefficient(Src, CurLoop);
3159 Src = SE->getAddExpr(Src, SE->getMulExpr(A_K, SE->getConstant(CdivA)));
3160 Src = zeroCoefficient(Src, CurLoop);
3161 Dst = addToCoefficient(Dst, CurLoop, A_K);
3162 if (!findCoefficient(Dst, CurLoop)->
isZero())
3167 const SCEV *A_K = findCoefficient(Src, CurLoop);
3168 Src = SE->getMulExpr(Src, A);
3169 Dst = SE->getMulExpr(Dst, A);
3170 Src = SE->getAddExpr(Src, SE->getMulExpr(A_K, C));
3171 Src = zeroCoefficient(Src, CurLoop);
3172 Dst = addToCoefficient(Dst, CurLoop, SE->getMulExpr(A_K, B));
3173 if (!findCoefficient(Dst, CurLoop)->isZero())
3185 bool DependenceInfo::propagatePoint(
const SCEV *&Src,
const SCEV *&Dst,
3186 Constraint &CurConstraint) {
3187 const Loop *CurLoop = CurConstraint.getAssociatedLoop();
3188 const SCEV *A_K = findCoefficient(Src, CurLoop);
3189 const SCEV *AP_K = findCoefficient(Dst, CurLoop);
3190 const SCEV *XA_K = SE->getMulExpr(A_K, CurConstraint.getX());
3191 const SCEV *YAP_K = SE->getMulExpr(AP_K, CurConstraint.getY());
3193 Src = SE->getAddExpr(Src, SE->getMinusSCEV(XA_K, YAP_K));
3194 Src = zeroCoefficient(Src, CurLoop);
3197 Dst = zeroCoefficient(Dst, CurLoop);
3205 const Constraint &CurConstraint)
const {
3208 if (CurConstraint.isAny())
3210 else if (CurConstraint.isDistance()) {
3213 Level.
Distance = CurConstraint.getD();
3215 if (!SE->isKnownNonZero(Level.
Distance))
3217 if (!SE->isKnownNonPositive(Level.
Distance))
3219 if (!SE->isKnownNonNegative(Level.
Distance))
3223 else if (CurConstraint.isLine()) {
3228 else if (CurConstraint.isPoint()) {
3233 CurConstraint.getY(),
3234 CurConstraint.getX()))
3238 CurConstraint.getY(),
3239 CurConstraint.getX()))
3243 CurConstraint.getY(),
3244 CurConstraint.getX()))
3268 const SCEV *SrcAccessFn =
3269 SE->getSCEVAtScope(SrcPtr, SrcLoop);
3270 const SCEV *DstAccessFn =
3271 SE->getSCEVAtScope(DstPtr, DstLoop);
3278 if (!SrcBase || !DstBase || SrcBase != DstBase)
3281 const SCEV *ElementSize = SE->getElementSize(Src);
3282 if (ElementSize != SE->getElementSize(Dst))
3285 const SCEV *SrcSCEV = SE->getMinusSCEV(SrcAccessFn, SrcBase);
3286 const SCEV *DstSCEV = SE->getMinusSCEV(DstAccessFn, DstBase);
3290 if (!SrcAR || !DstAR || !SrcAR->
isAffine() || !DstAR->isAffine())
3295 SE->collectParametricTerms(SrcAR, Terms);
3296 SE->collectParametricTerms(DstAR, Terms);
3300 SE->findArrayDimensions(Terms, Sizes, ElementSize);
3304 SE->computeAccessFunctions(SrcAR, SrcSubscripts, Sizes);
3305 SE->computeAccessFunctions(DstAR, DstSubscripts, Sizes);
3308 if (SrcSubscripts.
size() < 2 || DstSubscripts.
size() < 2 ||
3309 SrcSubscripts.
size() != DstSubscripts.
size())
3320 for (
int i = 1; i <
size; ++i) {
3324 if (!isKnownLessThan(SrcSubscripts[i], Sizes[i - 1]))
3330 if (!isKnownLessThan(DstSubscripts[i], Sizes[i - 1]))
3335 dbgs() <<
"\nSrcSubscripts: ";
3336 for (
int i = 0; i <
size; i++)
3337 dbgs() << *SrcSubscripts[i];
3338 dbgs() <<
"\nDstSubscripts: ";
3339 for (
int i = 0; i <
size; i++)
3340 dbgs() << *DstSubscripts[i];
3348 for (
int i = 0; i <
size; ++i) {
3349 Pair[i].Src = SrcSubscripts[i];
3350 Pair[i].Dst = DstSubscripts[i];
3351 unifySubscriptType(&Pair[i]);
3383 std::unique_ptr<Dependence>
3385 bool PossiblyLoopIndependent) {
3387 PossiblyLoopIndependent =
false;
3396 LLVM_DEBUG(
dbgs() <<
"can only handle simple loads and stores\n");
3397 return make_unique<Dependence>(Src, Dst);
3412 return make_unique<Dependence>(Src, Dst);
3422 establishNestingLevels(Src, Dst);
3423 LLVM_DEBUG(
dbgs() <<
" common nesting levels = " << CommonLevels <<
"\n");
3424 LLVM_DEBUG(
dbgs() <<
" maximum nesting levels = " << MaxLevels <<
"\n");
3426 FullDependence Result(Src, Dst, PossiblyLoopIndependent, CommonLevels);
3431 const SCEV *SrcSCEV = SE->getSCEV(SrcPtr);
3432 const SCEV *DstSCEV = SE->getSCEV(DstPtr);
3435 Pair[0].Src = SrcSCEV;
3436 Pair[0].Dst = DstSCEV;
3439 if (tryDelinearize(Src, Dst, Pair)) {
3441 Pairs = Pair.
size();
3445 for (
unsigned P = 0;
P < Pairs; ++
P) {
3446 Pair[
P].Loops.
resize(MaxLevels + 1);
3447 Pair[
P].GroupLoops.
resize(MaxLevels + 1);
3449 removeMatchingExtensions(&Pair[
P]);
3450 Pair[
P].Classification =
3451 classifyPair(Pair[P].Src, LI->getLoopFor(Src->getParent()),
3452 Pair[P].Dst, LI->getLoopFor(Dst->getParent()),
3454 Pair[
P].GroupLoops = Pair[
P].Loops;
3455 Pair[
P].Group.set(P);
3459 LLVM_DEBUG(
dbgs() <<
"\tclass = " << Pair[P].Classification <<
"\n");
3524 for (
unsigned SI = 0;
SI < Pairs; ++
SI) {
3525 if (Pair[
SI].Classification == Subscript::NonLinear) {
3527 ++NonlinearSubscriptPairs;
3528 collectCommonLoops(Pair[
SI].Src,
3529 LI->getLoopFor(Src->getParent()),
3531 collectCommonLoops(Pair[
SI].Dst,
3532 LI->getLoopFor(Dst->getParent()),
3534 Result.Consistent =
false;
3535 }
else if (Pair[
SI].Classification == Subscript::ZIV) {
3542 for (
unsigned SJ =
SI + 1; SJ < Pairs; ++SJ) {
3544 Intersection &= Pair[SJ].GroupLoops;
3545 if (Intersection.
any()) {
3547 Pair[SJ].GroupLoops |= Pair[
SI].GroupLoops;
3549 Pair[SJ].Group |= Pair[
SI].Group;
3554 if (Pair[
SI].Group.count() == 1) {
3556 ++SeparableSubscriptPairs;
3560 ++CoupledSubscriptPairs;
3571 Constraint NewConstraint;
3572 NewConstraint.setAny(SE);
3577 switch (Pair[
SI].Classification) {
3578 case Subscript::ZIV:
3580 if (testZIV(Pair[
SI].Src, Pair[
SI].Dst, Result))
3583 case Subscript::SIV: {
3586 const SCEV *SplitIter =
nullptr;
3587 if (testSIV(Pair[
SI].Src, Pair[
SI].Dst, Level, Result, NewConstraint,
3592 case Subscript::RDIV:
3594 if (testRDIV(Pair[
SI].Src, Pair[
SI].Dst, Result))
3597 case Subscript::MIV:
3599 if (testMIV(Pair[
SI].Src, Pair[
SI].Dst, Pair[
SI].Loops, Result))
3607 if (Coupled.
count()) {
3610 LLVM_DEBUG(
dbgs() <<
"MaxLevels + 1 = " << MaxLevels + 1 <<
"\n");
3612 for (
unsigned II = 0; II <= MaxLevels; ++II)
3613 Constraints[II].setAny(SE);
3621 for (
unsigned SJ : Group.
set_bits()) {
3623 if (Pair[SJ].Classification == Subscript::SIV)
3629 unifySubscriptType(PairsInGroup);
3631 while (Sivs.
any()) {
3632 bool Changed =
false;
3633 for (
unsigned SJ : Sivs.
set_bits()) {
3637 const SCEV *SplitIter =
nullptr;
3639 if (testSIV(Pair[SJ].Src, Pair[SJ].Dst, Level, Result, NewConstraint,
3642 ConstrainedLevels.
set(Level);
3643 if (intersectConstraints(&Constraints[Level], &NewConstraint)) {
3644 if (Constraints[Level].isEmpty()) {
3645 ++DeltaIndependence;
3657 for (
unsigned SJ : Mivs.
set_bits()) {
3660 if (
propagate(Pair[SJ].Src, Pair[SJ].Dst, Pair[SJ].Loops,
3661 Constraints, Result.Consistent)) {
3663 ++DeltaPropagations;
3664 Pair[SJ].Classification =
3665 classifyPair(Pair[SJ].Src, LI->getLoopFor(Src->getParent()),
3666 Pair[SJ].Dst, LI->getLoopFor(Dst->getParent()),
3668 switch (Pair[SJ].Classification) {
3669 case Subscript::ZIV:
3671 if (testZIV(Pair[SJ].Src, Pair[SJ].Dst, Result))
3675 case Subscript::SIV:
3679 case Subscript::RDIV:
3680 case Subscript::MIV:
3691 for (
unsigned SJ : Mivs.
set_bits()) {
3692 if (Pair[SJ].Classification == Subscript::RDIV) {
3694 if (testRDIV(Pair[SJ].Src, Pair[SJ].Dst, Result))
3704 for (
unsigned SJ : Mivs.
set_bits()) {
3705 if (Pair[SJ].Classification == Subscript::MIV) {
3707 if (testMIV(Pair[SJ].Src, Pair[SJ].Dst, Pair[SJ].Loops, Result))
3716 for (
unsigned SJ : ConstrainedLevels.
set_bits()) {
3717 if (SJ > CommonLevels)
3719 updateDirection(Result.DV[SJ - 1], Constraints[SJ]);
3728 for (
unsigned SI = 0;
SI < Pairs; ++
SI)
3729 CompleteLoops |= Pair[
SI].Loops;
3730 for (
unsigned II = 1; II <= CommonLevels; ++II)
3731 if (CompleteLoops[II])
3732 Result.DV[II - 1].Scalar =
false;
3734 if (PossiblyLoopIndependent) {
3738 for (
unsigned II = 1; II <= CommonLevels; ++II) {
3740 Result.LoopIndependent =
false;
3748 bool AllEqual =
true;
3749 for (
unsigned II = 1; II <= CommonLevels; ++II) {
3759 return make_unique<FullDependence>(std::move(Result));
3812 unsigned SplitLevel) {
3814 "Dep should be splitable at SplitLevel");
3817 assert(Src->mayReadFromMemory() || Src->mayWriteToMemory());
3828 establishNestingLevels(Src, Dst);
3834 const SCEV *SrcSCEV = SE->getSCEV(SrcPtr);
3835 const SCEV *DstSCEV = SE->getSCEV(DstPtr);
3836 Pair[0].Src = SrcSCEV;
3837 Pair[0].Dst = DstSCEV;
3840 if (tryDelinearize(Src, Dst, Pair)) {
3842 Pairs = Pair.
size();
3846 for (
unsigned P = 0;
P < Pairs; ++
P) {
3847 Pair[
P].Loops.
resize(MaxLevels + 1);
3848 Pair[
P].GroupLoops.
resize(MaxLevels + 1);
3850 removeMatchingExtensions(&Pair[
P]);
3851 Pair[
P].Classification =
3852 classifyPair(Pair[P].Src, LI->getLoopFor(Src->getParent()),
3853 Pair[P].Dst, LI->getLoopFor(Dst->getParent()),
3855 Pair[
P].GroupLoops = Pair[
P].Loops;
3856 Pair[
P].Group.set(P);
3863 for (
unsigned SI = 0;
SI < Pairs; ++
SI) {
3864 if (Pair[
SI].Classification == Subscript::NonLinear) {
3866 collectCommonLoops(Pair[
SI].Src,
3867 LI->getLoopFor(Src->getParent()),
3869 collectCommonLoops(Pair[
SI].Dst,
3870 LI->getLoopFor(Dst->getParent()),
3872 Result.Consistent =
false;
3874 else if (Pair[
SI].Classification == Subscript::ZIV)
3879 for (
unsigned SJ =
SI + 1; SJ < Pairs; ++SJ) {
3881 Intersection &= Pair[SJ].GroupLoops;
3882 if (Intersection.
any()) {
3884 Pair[SJ].GroupLoops |= Pair[
SI].GroupLoops;
3886 Pair[SJ].Group |= Pair[
SI].Group;
3891 if (Pair[
SI].Group.count() == 1)
3899 Constraint NewConstraint;
3900 NewConstraint.setAny(SE);
3904 switch (Pair[
SI].Classification) {
3905 case Subscript::SIV: {
3907 const SCEV *SplitIter =
nullptr;
3908 (void) testSIV(Pair[
SI].Src, Pair[
SI].Dst, Level,
3909 Result, NewConstraint, SplitIter);
3910 if (Level == SplitLevel) {
3911 assert(SplitIter !=
nullptr);
3916 case Subscript::ZIV:
3917 case Subscript::RDIV:
3918 case Subscript::MIV:
3925 if (Coupled.
count()) {
3928 for (
unsigned II = 0; II <= MaxLevels; ++II)
3929 Constraints[II].setAny(SE);
3935 for (
unsigned SJ : Group.
set_bits()) {
3936 if (Pair[SJ].Classification == Subscript::SIV)
3941 while (Sivs.
any()) {
3942 bool Changed =
false;
3943 for (
unsigned SJ : Sivs.
set_bits()) {
3946 const SCEV *SplitIter =
nullptr;
3947 (void) testSIV(Pair[SJ].Src, Pair[SJ].Dst, Level,
3948 Result, NewConstraint, SplitIter);
3949 if (Level == SplitLevel && SplitIter)
3951 ConstrainedLevels.
set(Level);
3952 if (intersectConstraints(&Constraints[Level], &NewConstraint))
3958 for (
unsigned SJ : Mivs.
set_bits()) {
3960 if (
propagate(Pair[SJ].Src, Pair[SJ].Dst,
3961 Pair[SJ].Loops, Constraints, Result.Consistent)) {
3962 Pair[SJ].Classification =
3963 classifyPair(Pair[SJ].Src, LI->getLoopFor(Src->getParent()),
3964 Pair[SJ].Dst, LI->getLoopFor(Dst->getParent()),
3966 switch (Pair[SJ].Classification) {
3967 case Subscript::ZIV:
3970 case Subscript::SIV:
3974 case Subscript::RDIV:
3975 case Subscript::MIV:
bool runOnFunction(Function &F) override
runOnFunction - Virtual method overriden by subclasses to do the per-function processing of the pass...
APInt abs() const
Get the absolute value;.
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...
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
static bool isLoopInvariant(Value *V, const Loop *L, const DominatorTree *DT)
Perform a quick domtree based check for loop invariance assuming that V is used within the loop...
This is a 'bitvector' (really, a variable-sized bit array), optimized for the case when the array is ...
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
AnalysisPass to compute dependence information in a function.
This class represents lattice values for constants.
const SCEV * getSplitIteration(const Dependence &Dep, unsigned Level)
getSplitIteration - Give a dependence that's splittable at some particular level, return the iteratio...
A Module instance is used to store all the information related to an LLVM module. ...
APInt sdiv(const APInt &RHS) const
Signed division function for APInt.
static cl::opt< bool > Delinearize("da-delinearize", cl::init(true), cl::Hidden, cl::ZeroOrMore, cl::desc("Try to delinearize array references."))
static constexpr LocationSize unknown()
Legacy pass manager pass to access dependence information.
unsigned getLoopDepth() const
Return the nesting level of this loop.
void push_back(const T &Elt)
The main scalar evolution driver.
bool slt(const APInt &RHS) const
Signed less than comparison.
bool isZero() const
Return true if the expression is a constant zero.
bool mayWriteToMemory() const
Return true if this instruction may modify memory.
The two locations do not alias at all.
static void sdivrem(const APInt &LHS, const APInt &RHS, APInt &Quotient, APInt &Remainder)
static void dumpSmallBitVector(SmallBitVector &BV)
bool sgt(const APInt &RHS) const
Signed greather than comparison.
static void dump(StringRef Title, SpillInfo const &Spills)
STATISTIC(NumFunctions, "Total number of functions")
An instruction for reading from memory.
const SCEV * getOperand() const
static AliasResult underlyingObjectsAlias(AliasAnalysis *AA, const DataLayout &DL, const MemoryLocation &LocA, const MemoryLocation &LocB)
DependenceInfo - This class is the main dependence-analysis driver.
bool sle(const APInt &RHS) const
Signed less or equal comparison.
void dump(raw_ostream &OS) const
dump - For debugging purposes, dumps a dependence to OS.
APInt GreatestCommonDivisor(APInt A, APInt B)
Compute GCD of two unsigned APInt values.
static APInt getSignedMaxValue(unsigned numBits)
Gets maximum signed value of APInt for a specific bit width.
This is the base class for unary cast operator classes.
unsigned getBitWidth() const
Return the number of bits in the APInt.
bool isConsistent() const override
isConsistent - Returns true if this dependence is consistent (occurs every time the source and destin...
static const SCEVConstant * getConstantPart(const SCEV *Expr)
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB)
The main low level interface to the alias analysis implementation.
#define INITIALIZE_PASS_DEPENDENCY(depName)
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)
const Loop * getLoop() const
bool isPeelLast(unsigned Level) const override
isPeelLast - Returns true if peeling the last iteration from this loop will break this dependence...
static AnalysisKey * ID()
Returns an opaque, unique ID for this analysis type.
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...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Analysis pass that exposes the LoopInfo for a function.
bool isFlow() const
isFlow - Returns true if this is a flow (aka true) dependence.
This node represents multiplication of some number of SCEVs.
const APInt & getAPInt() const
bool isIdentifiedObject(const Value *V)
Return true if this pointer refers to a distinct and identifiable object.
INITIALIZE_PASS_BEGIN(DependenceAnalysisWrapperPass, "da", "Dependence Analysis", true, true) INITIALIZE_PASS_END(DependenceAnalysisWrapperPass
This node represents a polynomial recurrence on the trip count of the specified loop.
iterator_range< const_set_bits_iterator > set_bits() const
Instruction * getSrc() const
getSrc - Returns the source instruction for this dependence.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
static APInt ceilingOfQuotient(const APInt &A, const APInt &B)
Value * getLoadStorePointerOperand(Value *V)
A helper function that returns the pointer operand of a load or store instruction.
An instruction for storing to memory.
unsigned getLevels() const override
getLevels - Returns the number of common loops surrounding the source and destination of the dependen...
bool isKnownNonNegative(const Value *V, const DataLayout &DL, unsigned Depth=0, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true)
Returns true if the give value is known to be non-negative.
bool isLoopIndependent() const override
isLoopIndependent - Returns true if this is a loop-independent dependence.
const SCEV * getStepRecurrence(ScalarEvolution &SE) const
Constructs and returns the recurrence indicating how much this expression steps by.
unsigned getBitWidth() const
Get the number of bits in this IntegerType.
bool isOutput() const
isOutput - Returns true if this is an output dependence.
AliasResult
The possible results of an alias query.
unsigned getDirection(unsigned Level) const override
getDirection - Returns the direction associated with a particular level.
static MemoryLocation get(const LoadInst *LI)
Return a location with information about the memory reference by the given instruction.
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.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
A set of analyses that are preserved following a run of a transformation pass.
* 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...
This is an important base class in LLVM.
static bool isLoadOrStore(const Instruction *I)
A manager for alias analyses.
bool isConfused() const override
isConfused - Returns true if this dependence is confused (the compiler understands nothing and makes ...
bool isSplitable(unsigned Level) const override
isSplitable - Returns true if splitting the loop will break the dependence.
Represent the analysis usage information of a pass.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
FunctionPass class - This class is used to implement most global optimizations.
bool isAffine() const
Return true if this represents an expression A + B*x where A and B are loop invariant values...
bool isPeelFirst(unsigned Level) const override
isPeelFirst - Returns true if peeling the first iteration from this loop will break this dependence...
const SCEV * getStart() const
Class to represent integer types.
static APInt minAPInt(APInt A, APInt B)
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
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...
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false) RegBankSelect
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
The two locations may or may not alias. This is the least precise result.
const Value * Ptr
The address of the start of the location.
Representation for a specific memory location.
The two locations precisely alias each other.
static bool findGCD(unsigned Bits, const APInt &AM, const APInt &BM, const APInt &Delta, APInt &G, APInt &X, APInt &Y)
auto size(R &&Range, typename std::enable_if< std::is_same< typename std::iterator_traits< decltype(Range.begin())>::iterator_category, std::random_access_iterator_tag >::value, void >::type *=nullptr) -> decltype(std::distance(Range.begin(), Range.end()))
Get the size of a range.
Type * getType() const
Return the LLVM type of this SCEV expression.
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.
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
int find_next(unsigned Prev) const
Returns the index of the next set bit following the "Prev" bit.
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.
FullDependence(Instruction *Src, Instruction *Dst, bool LoopIndependent, unsigned Levels)
void setPreservesAll()
Set by analyses that do not transform their input at all.
PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM)
static void propagate(InstantiatedValue From, InstantiatedValue To, MatchState State, ReachabilitySet &ReachSet, std::vector< WorkListItem > &WorkList)
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.
Function * getFunction() const
bool isAnti() const
isAnti - Returns true if this is an anti dependence.
LoopT * getParentLoop() const
static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT, AssumptionCache *AC)
AAMDNodes AATags
The metadata nodes which describes the aliasing of the location (each member is null if that kind of ...
This class represents an analyzed expression in the program.
Represents a single loop in the control flow graph.
virtual bool isSplitable(unsigned Level) const
isSplitable - Returns true if splitting this loop will break the dependence.
APInt srem(const APInt &RHS) const
Function for signed remainder operation.
StringRef getName() const
Return a constant reference to the value's name.
bool mayReadFromMemory() const
Return true if this instruction may read memory.
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()
Dependence::DVEntry - Each level in the distance/direction vector has a direction (or perhaps a union...
Instruction * getDst() const
getDst - Returns the destination instruction for this dependence.
static APInt maxAPInt(APInt A, APInt B)
bool isInput() const
isInput - Returns true if this is an input dependence.
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.
bool isOne() const
Return true if the expression is a constant one.
LLVM Value Representation.
bool any() const
Returns true if any bit is set.
This class implements an extremely fast bulk output stream that can only output to a stream...
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.
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...
DependenceInfo & getDI() const
The two locations alias, but only due to a partial overlap.
Dependence - This class represents a dependence between two memory memory references in a function...
NoWrapFlags getNoWrapFlags(NoWrapFlags Mask=NoWrapMask) const
A special type used by analysis passes to provide an address that identifies that particular analysis...
size_type count() const
Returns the number of bits which are set.
const BasicBlock * getParent() const
This class represents a constant integer value.