56#define DEBUG_TYPE "loop-interchange"
58STATISTIC(LoopsInterchanged,
"Number of loops interchanged");
62 cl::desc(
"Interchange if you gain more than this number"));
66 cl::desc(
"Maximum number of load/store instructions squared in relation to "
67 "the total number of instructions. Higher value may lead to more "
68 "interchanges at the cost of compile-time"));
82using CharMatrix = std::vector<std::vector<char>>;
97 cl::desc(
"Minimum depth of loop nest considered for the transform"));
102 cl::desc(
"Maximum depth of loop nest considered for the transform"));
108 cl::desc(
"List of profitability heuristics to be used. They are applied in "
111 RuleTy::ForVectorization}),
113 "Prioritize loop cache cost"),
114 clEnumValN(RuleTy::PerInstrOrderCost,
"instorder",
115 "Prioritize the IVs order of each instruction"),
116 clEnumValN(RuleTy::ForVectorization,
"vectorize",
117 "Prioritize vectorization"),
119 "Ignore profitability, force interchange (does not "
120 "work with other options)")));
125 cl::desc(
"Support for the inner-loop reduction pattern."));
130 for (RuleTy Rule : Rules) {
131 if (!Set.insert(Rule).second)
133 if (Rule == RuleTy::Ignore)
140 for (
auto &Row : DepMatrix) {
153 assert(Src->getParent() == Dst->getParent() && Src != Dst &&
154 "Expected Src and Dst to be different instructions in the same BB");
156 bool FoundSrc =
false;
177 unsigned NumInsts = 0;
203 unsigned NumMemInstr = MemInstr.
size();
205 <<
" Loads and Stores to analyze\n");
209 L->getStartLoc(), L->getHeader())
210 <<
"Number of loads/stores exceeded, the supported maximum can be "
211 "increased with option -loop-interchange-max-mem-instr-ratio.";
221 for (
I = MemInstr.
begin(), IE = MemInstr.
end();
I != IE; ++
I) {
222 for (J =
I, JE = MemInstr.
end(); J != JE; ++J) {
223 std::vector<char> Dep;
230 if (
auto D = DI->
depends(Src, Dst)) {
231 assert(
D->isOrdered() &&
"Expected an output, flow or anti dep.");
234 if (
D->normalize(SE))
237 D->isFlow() ?
"flow" :
D->isAnti() ?
"anti" :
"output";
238 dbgs() <<
"Found " << DepType
239 <<
" dependency between Src and Dst\n"
240 <<
" Src:" << *Src <<
"\n Dst:" << *Dst <<
'\n');
241 unsigned Levels =
D->getLevels();
243 for (
unsigned II = 1;
II <= Levels; ++
II) {
250 unsigned Dir =
D->getDirection(
II);
264 if (
D->isConfused()) {
265 assert(Dep.empty() &&
"Expected empty dependency vector");
266 Dep.assign(Level,
'*');
269 while (Dep.size() != Level) {
278 L->getStartLoc(), L->getHeader())
279 <<
"All loops have dependencies in all directions.";
285 bool IsKnownForward =
true;
286 if (Src->getParent() != Dst->getParent()) {
290 IsKnownForward =
false;
296 "Unexpected instructions");
301 bool IsReversed =
D->getSrc() != Src;
303 IsKnownForward =
false;
319 DepMatrix.push_back(Dep);
326 DepMatrix[Ite->second].back() =
'*';
338 for (
auto &Row : DepMatrix)
347static std::optional<bool>
360 unsigned InnerLoopId,
361 unsigned OuterLoopId) {
362 unsigned NumRows = DepMatrix.size();
363 std::vector<char> Cur;
365 for (
unsigned Row = 0; Row < NumRows; ++Row) {
368 Cur = DepMatrix[Row];
381 std::swap(Cur[InnerLoopId], Cur[OuterLoopId]);
390 << L.getHeader()->getParent()->getName() <<
" Loop: %"
391 << L.getHeader()->getName() <<
'\n');
392 assert(LoopList.
empty() &&
"LoopList should initially be empty!");
393 Loop *CurrentLoop = &L;
394 const std::vector<Loop *> *Vec = &CurrentLoop->
getSubLoops();
395 while (!Vec->empty()) {
399 if (Vec->size() != 1) {
405 CurrentLoop = Vec->front();
413 unsigned LoopNestDepth = LoopList.
size();
415 LLVM_DEBUG(
dbgs() <<
"Unsupported depth of loop nest " << LoopNestDepth
423 <<
"Unsupported depth of loop nest, the supported range is ["
434 for (
Loop *L : LoopList) {
440 if (L->getNumBackEdges() != 1) {
444 if (!L->getExitingBlock()) {
455class LoopInterchangeLegality {
457 LoopInterchangeLegality(
Loop *Outer,
Loop *Inner, ScalarEvolution *SE,
458 OptimizationRemarkEmitter *ORE, DominatorTree *DT)
459 : OuterLoop(
Outer), InnerLoop(Inner), SE(SE), DT(DT), ORE(ORE) {}
462 bool canInterchangeLoops(
unsigned InnerLoopId,
unsigned OuterLoopId,
463 CharMatrix &DepMatrix);
467 bool isLoopStructureUnderstood();
469 bool currentLimitations();
471 const SmallPtrSetImpl<PHINode *> &getOuterInnerReductions()
const {
472 return OuterInnerReductions;
476 return InnerLoopInductions;
480 return HasNoWrapReductions;
489 struct InnerReduction {
497 StoreInst *LcssaStore;
504 return InnerReductions;
508 bool tightlyNested(
Loop *Outer,
Loop *Inner);
509 bool containsUnsafeInstructions(BasicBlock *BB, Instruction *Skip);
521 bool checkInductionsAndReductions(
Loop *OuterLoop);
533 bool isInnerReduction(
Loop *L, PHINode *Phi,
534 SmallVectorImpl<Instruction *> &HasNoWrapInsts);
543 OptimizationRemarkEmitter *ORE;
547 SmallPtrSet<PHINode *, 4> OuterInnerReductions;
555 SmallVector<Instruction *, 4> HasNoWrapReductions;
559 SmallVector<Instruction *, 4> HasNoInfInsts;
568class CacheCostManager {
570 LoopStandardAnalysisResults *AR;
575 std::optional<std::unique_ptr<CacheCost>> CC;
579 DenseMap<const Loop *, unsigned> CostMap;
581 void computeIfUnitinialized();
584 CacheCostManager(
Loop *OutermostLoop, LoopStandardAnalysisResults *AR,
586 : OutermostLoop(OutermostLoop), AR(AR), DI(DI) {}
587 CacheCost *getCacheCost();
588 const DenseMap<const Loop *, unsigned> &getCostMap();
593class LoopInterchangeProfitability {
595 LoopInterchangeProfitability(
Loop *Outer,
Loop *Inner, ScalarEvolution *SE,
596 OptimizationRemarkEmitter *ORE)
597 : OuterLoop(
Outer), InnerLoop(Inner), SE(SE), ORE(ORE) {}
601 unsigned InnerLoopId,
unsigned OuterLoopId,
602 CharMatrix &DepMatrix, CacheCostManager &CCM);
605 int getInstrOrderCost();
606 std::optional<bool> isProfitablePerLoopCacheAnalysis(
607 const DenseMap<const Loop *, unsigned> &CostMap, CacheCost *CC);
608 std::optional<bool> isProfitablePerInstrOrderCost();
609 std::optional<bool> isProfitableForVectorization(
unsigned InnerLoopId,
610 unsigned OuterLoopId,
611 CharMatrix &DepMatrix);
619 OptimizationRemarkEmitter *ORE;
623class LoopInterchangeTransform {
625 LoopInterchangeTransform(
Loop *Outer,
Loop *Inner, ScalarEvolution *SE,
626 LoopInfo *LI, DominatorTree *DT,
627 const LoopInterchangeLegality &LIL)
628 : OuterLoop(
Outer), InnerLoop(Inner), SE(SE), LI(LI), DT(DT), LIL(LIL) {}
633 void reduction2Memory();
634 void restructureLoops(
Loop *NewInner,
Loop *NewOuter,
635 BasicBlock *OrigInnerPreHeader,
636 BasicBlock *OrigOuterPreHeader);
637 void removeChildLoop(
Loop *OuterLoop,
Loop *InnerLoop);
640 void adjustLoopBranches();
651 const LoopInterchangeLegality &LIL;
654struct LoopInterchange {
655 ScalarEvolution *SE =
nullptr;
656 LoopInfo *LI =
nullptr;
657 DependenceInfo *DI =
nullptr;
658 DominatorTree *DT =
nullptr;
659 LoopStandardAnalysisResults *AR =
nullptr;
662 OptimizationRemarkEmitter *ORE;
664 LoopInterchange(ScalarEvolution *SE, LoopInfo *LI, DependenceInfo *DI,
665 DominatorTree *DT, LoopStandardAnalysisResults *AR,
666 OptimizationRemarkEmitter *ORE)
667 : SE(SE), LI(LI), DI(DI), DT(DT), AR(AR), ORE(ORE) {}
670 if (
L->getParentLoop())
672 SmallVector<Loop *, 8> LoopList;
674 return processLoopList(LoopList);
677 bool run(LoopNest &LN) {
678 SmallVector<Loop *, 8> LoopList(LN.
getLoops());
679 for (
unsigned I = 1;
I < LoopList.size(); ++
I)
680 if (LoopList[
I]->getParentLoop() != LoopList[
I - 1])
682 return processLoopList(LoopList);
688 return LoopList.
size() - 1;
691 bool processLoopList(SmallVectorImpl<Loop *> &LoopList) {
696 "Unsupported depth of loop nest.");
698 unsigned LoopNestDepth = LoopList.
size();
701 dbgs() <<
"Processing LoopList of size = " << LoopNestDepth
702 <<
" containing the following loops:\n";
703 for (
auto *L : LoopList) {
709 CharMatrix DependencyMatrix;
710 Loop *OuterMostLoop = *(LoopList.begin());
712 OuterMostLoop, DI, SE, ORE)) {
724 <<
"' needs an unique exit block");
728 unsigned SelecLoopId = selectLoopForInterchange(LoopList);
729 CacheCostManager CCM(LoopList[0], AR, DI);
734 for (
unsigned j = SelecLoopId;
j > 0;
j--) {
735 bool ChangedPerIter =
false;
736 for (
unsigned i = SelecLoopId; i > SelecLoopId -
j; i--) {
738 processLoop(LoopList, i, i - 1, DependencyMatrix, CCM);
739 ChangedPerIter |= Interchanged;
750 bool processLoop(SmallVectorImpl<Loop *> &LoopList,
unsigned InnerLoopId,
751 unsigned OuterLoopId,
752 std::vector<std::vector<char>> &DependencyMatrix,
753 CacheCostManager &CCM) {
754 Loop *OuterLoop = LoopList[OuterLoopId];
755 Loop *InnerLoop = LoopList[InnerLoopId];
757 <<
" and OuterLoopId = " << OuterLoopId <<
"\n");
758 LoopInterchangeLegality LIL(OuterLoop, InnerLoop, SE, ORE, DT);
759 if (!LIL.canInterchangeLoops(InnerLoopId, OuterLoopId, DependencyMatrix)) {
760 LLVM_DEBUG(
dbgs() <<
"Cannot prove legality, not interchanging loops '"
761 << OuterLoop->
getName() <<
"' and '"
762 << InnerLoop->
getName() <<
"'\n");
767 <<
"' are legal to interchange\n");
768 LoopInterchangeProfitability LIP(OuterLoop, InnerLoop, SE, ORE);
769 if (!LIP.isProfitable(InnerLoop, OuterLoop, InnerLoopId, OuterLoopId,
770 DependencyMatrix, CCM)) {
772 <<
"' and '" << InnerLoop->
getName()
773 <<
"' not profitable.\n");
778 return OptimizationRemark(
DEBUG_TYPE,
"Interchanged",
781 <<
"Loop interchanged with enclosing loop.";
784 LoopInterchangeTransform LIT(OuterLoop, InnerLoop, SE, LI, DT, LIL);
785 LIT.transform(LIL.getHasNoWrapReductions(), LIL.getHasNoInfInsts());
787 << OuterLoop->
getName() <<
"' and inner loop '"
788 << InnerLoop->
getName() <<
"'\n");
794 std::swap(LoopList[OuterLoopId], LoopList[InnerLoopId]);
807bool LoopInterchangeLegality::containsUnsafeInstructions(
BasicBlock *BB,
809 return any_of(*BB, [Skip](
const Instruction &
I) {
812 return I.mayHaveSideEffects() ||
I.mayReadFromMemory();
841 auto IsDirectInnerLoopBlock = [InnerLoop](
BasicBlock *BB) {
844 [BB](
Loop *SubLoop) { return SubLoop->contains(BB); });
850 Worklist.
insert(Condition);
852 for (
PHINode *Induction : InnerLoopInductions) {
854 Induction->getIncomingValueForBlock(InnerLoop->
getLoopLatch()));
855 if (Incoming && !
is_contained(InnerLoopInductions, Incoming))
856 Worklist.
insert(Incoming);
859 for (
unsigned I = 0;
I < Worklist.
size(); ++
I) {
865 if (!OperandI || !IsDirectInnerLoopBlock(OperandI->getParent()) ||
868 Worklist.
insert(OperandI);
874bool LoopInterchangeLegality::tightlyNested(
Loop *OuterLoop,
Loop *InnerLoop) {
880 <<
"' and '" << InnerLoop->
getName()
881 <<
"' are tightly nested\n");
901 for (BasicBlock *Succ :
successors(OuterLoopHeader))
902 if (Succ != InnerLoopPreHeader && Succ != InnerLoop->
getHeader())
905 LLVM_DEBUG(
dbgs() <<
"Checking instructions in Loop header and Loop latch\n");
911 assert(InnerReductions.size() <= 1 &&
912 "So far we only support at most one reduction.");
913 if (InnerReductions.size() == 1)
914 Skip = InnerReductions[0].LcssaStore;
918 if (containsUnsafeInstructions(OuterLoopHeader, Skip) ||
919 containsUnsafeInstructions(OuterLoopLatch, Skip))
925 if (InnerLoopPreHeader != OuterLoopHeader &&
926 containsUnsafeInstructions(InnerLoopPreHeader, Skip))
934 if (&SuccInner != OuterLoopLatch) {
936 <<
" does not lead to the outer loop latch.\n";);
942 if (containsUnsafeInstructions(InnerLoopExit, Skip))
950bool LoopInterchangeLegality::isLoopStructureUnderstood() {
952 for (PHINode *InnerInduction : InnerLoopInductions) {
953 unsigned Num = InnerInduction->getNumOperands();
954 for (
unsigned i = 0; i < Num; ++i) {
955 Value *Val = InnerInduction->getOperand(i);
965 if (InnerInduction->getIncomingBlock(IncomBlockIndx) ==
966 InnerLoopPreheader &&
980 CondBrInst *InnerLoopLatchBI =
982 if (!InnerLoopLatchBI)
1001 std::function<bool(
Value *)> IsPathToInnerIndVar;
1002 IsPathToInnerIndVar = [
this, &IsPathToInnerIndVar](
const Value *
V) ->
bool {
1011 return IsPathToInnerIndVar(
I->getOperand(0));
1013 return IsPathToInnerIndVar(
I->getOperand(0)) &&
1014 IsPathToInnerIndVar(
I->getOperand(1));
1020 if (IsPathToInnerIndVar(Op0) && IsPathToInnerIndVar(Op1))
1028 }
else if (IsPathToInnerIndVar(Op1) && !
isa<Constant>(Op1)) {
1033 if (
Left ==
nullptr)
1050 if (
PHI->getNumIncomingValues() != 1)
1138 assert(
I->getOpcode() == OpCode &&
1139 "Expected the instruction to be the reduction operation");
1144 if (
I->hasNoSignedWrap() ||
I->hasNoUnsignedWrap())
1168 if (
PHI->getNumIncomingValues() == 1)
1181bool LoopInterchangeLegality::isInnerReduction(
1182 Loop *L, PHINode *Phi, SmallVectorImpl<Instruction *> &HasNoWrapInsts) {
1186 if (!
L->isInnermost()) {
1187 LLVM_DEBUG(
dbgs() <<
"Only supported when the loop is the innermost.\n");
1189 return OptimizationRemarkMissed(
DEBUG_TYPE,
"UnsupportedInnerReduction",
1190 L->getStartLoc(),
L->getHeader())
1191 <<
"Only supported when the loop is the innermost.";
1196 if (
Phi->getNumIncomingValues() != 2)
1199 Value *Init =
Phi->getIncomingValueForBlock(
L->getLoopPreheader());
1200 Value *
Next =
Phi->getIncomingValueForBlock(
L->getLoopLatch());
1206 <<
"Only supported for the reduction with a constant initial value.\n");
1208 return OptimizationRemarkMissed(
DEBUG_TYPE,
"UnsupportedInnerReduction",
1209 L->getStartLoc(),
L->getHeader())
1210 <<
"Only supported for the reduction with a constant initial "
1219 if (!
L->contains(BB))
1224 if (!
Phi->hasOneUser())
1236 PHINode *Lcssa = NULL;
1237 for (
auto *U :
Next->users()) {
1242 if (Lcssa == NULL &&
P->getParent() == ExitBlock &&
1243 P->getIncomingValueForBlock(
L->getLoopLatch()) ==
Next)
1254 LLVM_DEBUG(
dbgs() <<
"Only supported when the reduction is used once in "
1255 "the outer loop.\n");
1257 return OptimizationRemarkMissed(
DEBUG_TYPE,
"UnsupportedInnerReduction",
1258 L->getStartLoc(),
L->getHeader())
1259 <<
"Only supported when the reduction is used once in the outer "
1265 StoreInst *LcssaStore =
1267 if (!LcssaStore || LcssaStore->
getParent() != ExitBlock)
1280 LLVM_DEBUG(
dbgs() <<
"Only supported when memory reference dominate "
1281 "the inner loop.\n");
1283 return OptimizationRemarkMissed(
DEBUG_TYPE,
"UnsupportedInnerReduction",
1284 L->getStartLoc(),
L->getHeader())
1285 <<
"Only supported when memory reference dominate the inner "
1296 SR.LcssaPhi = Lcssa;
1297 SR.LcssaStore = LcssaStore;
1301 InnerReductions.push_back(SR);
1305bool LoopInterchangeLegality::checkInductionsAndReductions(
Loop *OuterLoop) {
1306 auto ChildLoop = [](
Loop *
L) {
1307 assert(
L->getSubLoops().size() <= 1 &&
1308 "Expect at most one child loop for now.");
1309 return L->getSubLoops().empty() ? nullptr :
L->getSubLoops().front();
1312 Loop *InnerLoop = ChildLoop(OuterLoop);
1313 for (
Loop *CurLoop = OuterLoop; CurLoop; CurLoop = ChildLoop(CurLoop)) {
1314 for (PHINode &
PHI : CurLoop->getHeader()->phis()) {
1315 InductionDescriptor
ID;
1317 if (CurLoop == InnerLoop) {
1318 const SCEV *Step =
ID.getStep();
1321 InnerLoopInductions.push_back(&
PHI);
1326 if (CurLoop == OuterLoop) {
1328 if (
PHI.getNumIncomingValues() != 2) {
1329 LLVM_DEBUG(
dbgs() <<
"Only PHI nodes in the outer loop header with 2 "
1330 "incoming values are supported.\n");
1338 InnerLoop, V, HasNoWrapReductions, HasNoInfInsts);
1358 [InnerRedPhi](User *U) { return U == InnerRedPhi; })) {
1361 <<
"Failed to recognize PHI as an induction or reduction.\n");
1363 return OptimizationRemarkMissed(
DEBUG_TYPE,
"UnsupportedPHIOuter",
1366 <<
"Only outer loops with induction or reduction PHI nodes "
1367 "can be interchanged currently.";
1372 OuterInnerReductions.insert(&
PHI);
1373 OuterInnerReductions.insert(InnerRedPhi);
1375 if (OuterInnerReductions.count(&
PHI)) {
1376 LLVM_DEBUG(
dbgs() <<
"Found a reduction across the outer loop.\n");
1378 isInnerReduction(CurLoop, &
PHI, HasNoWrapReductions)) {
1383 return OptimizationRemarkMissed(
DEBUG_TYPE,
"UnsupportedPHIInner",
1384 CurLoop->getStartLoc(),
1385 CurLoop->getHeader())
1386 <<
"Only inner loops with induction or reduction PHI nodes "
1387 "can be interchanged currently.";
1395 if (InnerReductions.size() > 1) {
1398 return OptimizationRemarkMissed(
DEBUG_TYPE,
"UnsupportedInnerReduction",
1399 CurLoop->getStartLoc(),
1400 CurLoop->getHeader())
1401 <<
"Only supports at most one reduction.";
1407 return !InnerLoopInductions.empty();
1412bool LoopInterchangeLegality::currentLimitations() {
1422 dbgs() <<
"Loops where the latch is not the exiting block are not"
1423 <<
" supported currently.\n");
1425 return OptimizationRemarkMissed(
DEBUG_TYPE,
"ExitingNotLatch",
1428 <<
"Loops where the latch is not the exiting block cannot be"
1429 " interchange currently.";
1435 if (!isLoopStructureUnderstood()) {
1438 return OptimizationRemarkMissed(
DEBUG_TYPE,
"UnsupportedStructureInner",
1441 <<
"Inner loop structure not understood currently.";
1448 for (
Loop *L : {OuterLoop, InnerLoop}) {
1451 if (
L->contains(Pred))
1455 dbgs() <<
"Indirect branch found in the loop predecessor.\n");
1457 return OptimizationRemarkMissed(
DEBUG_TYPE,
"IndirectBranchPreheader",
1458 L->getStartLoc(),
L->getHeader())
1459 <<
"Indirect branch found in the loop predecessor.";
1468 SmallPtrSet<BasicBlock *, 2> InnerLoopHeaderSuccs;
1470 if (!InnerLoopHeaderSuccs.
insert(Succ).second)
1493 if (
PHI.getNumIncomingValues() > 1)
1497 if (&
PHI == LcssaReduction)
1500 PHINode *PN = dyn_cast<PHINode>(U);
1503 if (Reductions.count(PN))
1505 BasicBlock *PB = PN->getParent();
1506 if (!OuterL->contains(PB))
1508 return PB != OuterL->getLoopLatch();
1525 for (
Value *Incoming :
PHI.incoming_values()) {
1566 for (
PHINode *InductionPHI : InductionPHIs) {
1568 InductionPHI->getIncomingValueForBlock(InnerLoopLatch)))
1570 Worklist.
insert(IncomingI);
1576 InductionPHIs.
end());
1577 for (
unsigned I = 0;
I < Worklist.
size(); ++
I) {
1589bool LoopInterchangeLegality::canInterchangeLoops(
unsigned InnerLoopId,
1590 unsigned OuterLoopId,
1591 CharMatrix &DepMatrix) {
1593 LLVM_DEBUG(
dbgs() <<
"Failed interchange InnerLoopId = " << InnerLoopId
1594 <<
" and OuterLoopId = " << OuterLoopId
1595 <<
" due to dependence\n");
1597 return OptimizationRemarkMissed(
DEBUG_TYPE,
"Dependence",
1600 <<
"Cannot interchange loops due to dependences.";
1605 for (
auto *BB : OuterLoop->
blocks())
1606 for (Instruction &
I : *BB) {
1613 if (!
I.mayHaveSideEffects() && !
I.mayReadFromMemory())
1618 <<
"Loops contain instructions that cannot be safely interchanged\n");
1620 return OptimizationRemarkMissed(
DEBUG_TYPE,
"UnsafeInst",
1621 I.getDebugLoc(),
I.getParent())
1622 <<
"Cannot interchange loops due to instruction that is "
1623 "potentially unsafe to interchange.";
1629 if (!checkInductionsAndReductions(OuterLoop)) {
1630 LLVM_DEBUG(
dbgs() <<
"Failed to find inner loop inductions or found "
1631 "unsupported reductions.\n");
1636 LLVM_DEBUG(
dbgs() <<
"Found unsupported PHI nodes in inner loop latch.\n");
1638 return OptimizationRemarkMissed(
DEBUG_TYPE,
"UnsupportedInnerLatchPHI",
1641 <<
"Cannot interchange loops because unsupported PHI nodes found "
1642 "in inner loop latch.";
1651 LLVM_DEBUG(
dbgs() <<
"Interchange would re-nest or duplicate freeze\n");
1653 return OptimizationRemarkMissed(
DEBUG_TYPE,
"UnsafeInst",
1656 <<
"Cannot interchange loops because re-nesting or duplicating "
1657 "freeze may change its sampling behavior.";
1664 if (currentLimitations()) {
1665 LLVM_DEBUG(
dbgs() <<
"Not legal because of current transform limitation\n");
1670 if (!tightlyNested(OuterLoop, InnerLoop)) {
1673 return OptimizationRemarkMissed(
DEBUG_TYPE,
"NotTightlyNested",
1676 <<
"Cannot interchange loops because they are not tightly "
1684 PHINode *LcssaReduction =
nullptr;
1685 assert(InnerReductions.size() <= 1 &&
1686 "So far we only support at most one reduction.");
1687 if (InnerReductions.size() == 1)
1688 LcssaReduction = InnerReductions[0].LcssaPhi;
1692 LLVM_DEBUG(
dbgs() <<
"Found unsupported PHI nodes in inner loop exit.\n");
1694 return OptimizationRemarkMissed(
DEBUG_TYPE,
"UnsupportedExitPHI",
1697 <<
"Found unsupported PHI node in loop exit.";
1703 LLVM_DEBUG(
dbgs() <<
"Found unsupported PHI nodes in outer loop exit.\n");
1705 return OptimizationRemarkMissed(
DEBUG_TYPE,
"UnsupportedExitPHI",
1708 <<
"Found unsupported PHI node in loop exit.";
1714 [](PHINode &
PHI) { return PHI.getNumIncomingValues() != 1; })) {
1715 LLVM_DEBUG(
dbgs() <<
"Only outer loop latch PHI nodes with one incoming "
1716 "value are supported.\n");
1718 return OptimizationRemarkMissed(
DEBUG_TYPE,
"UnsupportedLatchPHI",
1721 <<
"Only outer loop latch PHI nodes with one incoming value are "
1735 if (
any_of(
PHI.users(), [](
const User *U) { return !isa<PHINode>(U); })) {
1736 LLVM_DEBUG(
dbgs() <<
"Outer loop latch PHI has a non-PHI user.\n");
1738 return OptimizationRemarkMissed(
DEBUG_TYPE,
"UnsupportedLatchPHI",
1741 <<
"Cannot interchange loops because an outer loop latch PHI "
1742 "node has a non-PHI user.";
1750void CacheCostManager::computeIfUnitinialized() {
1765 for (
const auto &[Idx,
Cost] :
enumerate((*CC)->getLoopCosts()))
1766 CostMap[
Cost.first] = Idx;
1769CacheCost *CacheCostManager::getCacheCost() {
1770 computeIfUnitinialized();
1774const DenseMap<const Loop *, unsigned> &CacheCostManager::getCostMap() {
1775 computeIfUnitinialized();
1785static std::optional<const SCEV *>
1791 return std::nullopt;
1796 return std::nullopt;
1799 std::optional<const SCEV *> Coeff =
1801 if (!Coeff.has_value())
1802 return std::nullopt;
1805 assert(!*Coeff &&
"Found more than one addrec for the same loop");
1811int LoopInterchangeProfitability::getInstrOrderCost() {
1812 SmallPtrSet<const SCEV *, 4> GoodBasePtrs, BadBasePtrs;
1813 for (BasicBlock *BB : InnerLoop->
blocks()) {
1814 for (Instruction &Ins : *BB) {
1819 std::optional<const SCEV *> OuterCoeff =
1821 std::optional<const SCEV *> InnerCoeff =
1824 if (!OuterCoeff.has_value() || !*OuterCoeff || !InnerCoeff.has_value() ||
1834 const SCEV *OuterStep = SE->
getAbsExpr(*OuterCoeff,
false);
1835 const SCEV *InnerStep = SE->
getAbsExpr(*InnerCoeff,
false);
1855 GoodBasePtrs.
insert(BasePtr);
1857 BadBasePtrs.
insert(BasePtr);
1861 int GoodOrder = GoodBasePtrs.
size();
1862 int BadOrder = BadBasePtrs.
size();
1863 return GoodOrder - BadOrder;
1867LoopInterchangeProfitability::isProfitablePerLoopCacheAnalysis(
1868 const DenseMap<const Loop *, unsigned> &CostMap, CacheCost *CC) {
1872 auto InnerLoopIt = CostMap.
find(InnerLoop);
1873 if (InnerLoopIt == CostMap.
end())
1874 return std::nullopt;
1875 auto OuterLoopIt = CostMap.
find(OuterLoop);
1876 if (OuterLoopIt == CostMap.
end())
1877 return std::nullopt;
1880 return std::nullopt;
1881 unsigned InnerIndex = InnerLoopIt->second;
1882 unsigned OuterIndex = OuterLoopIt->second;
1884 <<
", OuterIndex = " << OuterIndex <<
"\n");
1885 assert(InnerIndex != OuterIndex &&
"CostMap should assign unique "
1886 "numbers to each loop");
1887 return std::optional<bool>(InnerIndex < OuterIndex);
1891LoopInterchangeProfitability::isProfitablePerInstrOrderCost() {
1895 int Cost = getInstrOrderCost();
1898 return std::optional<bool>(
true);
1900 return std::nullopt;
1905 for (
const auto &Dep : DepMatrix) {
1906 char Dir = Dep[LoopId];
1907 char DepType = Dep.back();
1908 assert((DepType ==
'<' || DepType ==
'*') &&
1909 "Unexpected element in dependency vector");
1912 if (Dir ==
'=' || Dir ==
'I')
1918 if (Dir ==
'<' && DepType ==
'<')
1927std::optional<bool> LoopInterchangeProfitability::isProfitableForVectorization(
1928 unsigned InnerLoopId,
unsigned OuterLoopId, CharMatrix &DepMatrix) {
1944 return std::nullopt;
1947bool LoopInterchangeProfitability::isProfitable(
1948 const Loop *InnerLoop,
const Loop *OuterLoop,
unsigned InnerLoopId,
1949 unsigned OuterLoopId, CharMatrix &DepMatrix, CacheCostManager &CCM) {
1958 if (InnerBTC && InnerBTC->
isZero()) {
1959 LLVM_DEBUG(
dbgs() <<
"Inner loop back-edge isn't taken, rejecting "
1960 "single iteration loop\n");
1963 if (OuterBTC && OuterBTC->
isZero()) {
1964 LLVM_DEBUG(
dbgs() <<
"Outer loop back-edge isn't taken, rejecting "
1965 "single iteration loop\n");
1973 "Duplicate rules and option 'ignore' are not allowed");
1983 std::optional<bool> shouldInterchange;
1986 case RuleTy::PerLoopCacheAnalysis: {
1987 CacheCost *CC = CCM.getCacheCost();
1988 const DenseMap<const Loop *, unsigned> &CostMap = CCM.getCostMap();
1989 shouldInterchange = isProfitablePerLoopCacheAnalysis(CostMap, CC);
1992 case RuleTy::PerInstrOrderCost:
1993 shouldInterchange = isProfitablePerInstrOrderCost();
1995 case RuleTy::ForVectorization:
1997 isProfitableForVectorization(InnerLoopId, OuterLoopId, DepMatrix);
1999 case RuleTy::Ignore:
2006 if (shouldInterchange.has_value())
2010 if (!shouldInterchange.has_value()) {
2012 return OptimizationRemarkMissed(
DEBUG_TYPE,
"InterchangeNotProfitable",
2015 <<
"Insufficient information to calculate the cost of loop for "
2019 }
else if (!shouldInterchange.value()) {
2021 return OptimizationRemarkMissed(
DEBUG_TYPE,
"InterchangeNotProfitable",
2024 <<
"Interchanging loops is not considered to improve cache "
2025 "locality nor vectorization.";
2032void LoopInterchangeTransform::removeChildLoop(
Loop *OuterLoop,
2034 for (
Loop *L : *OuterLoop)
2035 if (L == InnerLoop) {
2036 OuterLoop->removeChildLoop(L);
2065void LoopInterchangeTransform::restructureLoops(
2066 Loop *NewInner,
Loop *NewOuter, BasicBlock *OrigInnerPreHeader,
2067 BasicBlock *OrigOuterPreHeader) {
2068 Loop *OuterLoopParent = OuterLoop->getParentLoop();
2075 if (OuterLoopParent) {
2077 removeChildLoop(OuterLoopParent, NewInner);
2078 removeChildLoop(NewInner, NewOuter);
2081 removeChildLoop(NewInner, NewOuter);
2089 SmallVector<BasicBlock *, 8> OrigInnerBBs(NewOuter->
blocks());
2093 for (BasicBlock *BB : NewInner->
blocks())
2101 for (BasicBlock *BB : OrigInnerBBs) {
2106 if (BB == OuterHeader || BB == OuterLatch)
2144void LoopInterchangeTransform::reduction2Memory() {
2146 LIL.getInnerReductions();
2149 "So far we only support at most one reduction.");
2151 LoopInterchangeLegality::InnerReduction SR = InnerReductions[0];
2157 PHINode *FirstIter =
2158 Builder.CreatePHI(Type::getInt1Ty(
Context), 2,
"first.iter");
2163 assert(FirstIter->
isComplete() &&
"The FirstIter PHI node is not complete.");
2168 Instruction *LoadMem = Builder.CreateLoad(SR.ElemTy, SR.MemRef);
2171 Value *NewVar = Builder.CreateSelect(FirstIter, SR.Init, LoadMem,
"new.var");
2182void LoopInterchangeTransform::transform(
2187 LIL.getInnerReductions();
2188 if (InnerReductions.
size() == 1)
2192 auto &InductionPHIs = LIL.getInnerLoopInductions();
2193 assert(!InductionPHIs.empty() &&
2194 "Expected at least one induction variable in the inner loop");
2196 SmallVector<Instruction *, 8> InnerIndexVarList;
2197 for (PHINode *CurInductionPHI : InductionPHIs) {
2199 CurInductionPHI->getIncomingValueForBlock(InnerLoop->
getLoopLatch()));
2201 "Incoming value from loop latch isn't an instruction");
2204 InnerIndexVarList.
push_back(IncomingValue);
2217 SmallSetVector<Instruction *, 4> WorkList;
2219 auto MoveInstructions = [&i, &WorkList,
this, &InductionPHIs, NewLatch]() {
2220 for (; i < WorkList.
size(); i++) {
2224 "MoveInstructions does not support PHI nodes");
2230 "Moving instructions with side-effects may change behavior of "
2241 for (
Value *
Op : WorkList[i]->operands()) {
2258 for (Instruction *InnerIndexVar : InnerIndexVarList)
2273 BasicBlock *OuterLoopHeader = OuterLoop->getHeader();
2275 if (InnerLoopPreHeader != OuterLoopHeader) {
2279 "Expected equivalent incoming values in inner loop preheader");
2280 P.replaceAllUsesWith(
P.getIncomingValue(0));
2281 P.eraseFromParent();
2283 for (Instruction &
I :
2285 std::prev(InnerLoopPreHeader->
end()))))
2289 adjustLoopBranches();
2293 for (Instruction *
Reduction : DropNoWrapInsts) {
2297 for (Instruction *
I : DropNoInfInsts)
2298 I->setHasNoInfs(
false);
2317 I->removeFromParent();
2332 std::vector<DominatorTree::UpdateType> &DTUpdates,
2333 bool MustUpdateOnce =
true) {
2335 "BI must jump to OldBB exactly once.");
2337 for (
Use &
Op : Term->operands())
2344 DTUpdates.push_back(
2345 {DominatorTree::UpdateKind::Insert, Term->getParent(), NewBB});
2346 DTUpdates.push_back(
2347 {DominatorTree::UpdateKind::Delete, Term->getParent(), OldBB});
2366 assert(
P.getNumIncomingValues() == 1 &&
2367 "Only loops with a single exit are supported!");
2369 Value *IncomingValue =
P.getIncomingValueForBlock(InnerLatch);
2376 "Expected non-instruction incoming value to be loop invariant");
2377 P.replaceAllUsesWith(IncomingValue);
2378 P.eraseFromParent();
2389 if (!IncIInnerMost || (IncIInnerMost->getParent() != InnerLatch &&
2390 IncIInnerMost->
getParent() != InnerHeader))
2394 [OuterHeader, OuterExit, IncI, InnerHeader](
User *U) {
2395 return (cast<PHINode>(U)->getParent() == OuterHeader &&
2396 IncI->getParent() == InnerHeader) ||
2397 cast<PHINode>(U)->getParent() == OuterExit;
2399 "Can only replace phis iff the uses are in the loop nest exit or "
2400 "the incoming value is defined in the inner header (it will "
2401 "dominate all loop blocks after interchanging)");
2402 P.replaceAllUsesWith(IncI);
2403 P.eraseFromParent();
2431 if (
P.getNumIncomingValues() != 1)
2445 if (Pred == OuterLatch)
2450 P.setIncomingValue(0, NewPhi);
2490 if (OuterLoopLatch == InnerLoopExit)
2497 assert(Phi->getNumIncomingValues() == 1 &&
"Single input phi expected");
2498 LLVM_DEBUG(
dbgs() <<
"Removing 1-input phi in non-exit block: " << *Phi
2500 Phi->replaceAllUsesWith(Phi->getIncomingValue(0));
2501 Phi->eraseFromParent();
2505void LoopInterchangeTransform::adjustLoopBranches() {
2507 std::vector<DominatorTree::UpdateType> DTUpdates;
2509 BasicBlock *OuterLoopPreHeader = OuterLoop->getLoopPreheader();
2512 assert(OuterLoopPreHeader != OuterLoop->getHeader() &&
2513 InnerLoopPreHeader != InnerLoop->
getHeader() && OuterLoopPreHeader &&
2514 InnerLoopPreHeader &&
"Guaranteed by loop-simplify form");
2524 OuterLoopPreHeader =
2526 if (InnerLoopPreHeader == OuterLoop->getHeader())
2527 InnerLoopPreHeader =
2532 BasicBlock *OuterLoopHeader = OuterLoop->getHeader();
2534 BasicBlock *OuterLoopLatch = OuterLoop->getLoopLatch();
2541 CondBrInst *OuterLoopLatchBI =
2543 CondBrInst *InnerLoopLatchBI =
2548 assert(OuterLoopPredecessor && InnerLoopLatchPredecessor &&
2549 "Failed to find a unique predecessor");
2550 assert(OuterLoopLatchBI && InnerLoopLatchBI &&
2551 "Failed to find a conditional branch");
2558 assert(InnerLoopHeaderSuccessor &&
2559 "Failed to find a unique successor for the inner loop header");
2566 InnerLoopPreHeader, DTUpdates,
false);
2576 InnerLoopHeaderSuccessor, DTUpdates,
2584 OuterLoopPreHeader, DTUpdates);
2587 if (InnerLoopLatchBI->
getSuccessor(0) == InnerLoopHeader)
2588 InnerLoopLatchSuccessor = InnerLoopLatchBI->
getSuccessor(1);
2590 InnerLoopLatchSuccessor = InnerLoopLatchBI->
getSuccessor(0);
2593 InnerLoopLatchSuccessor, DTUpdates);
2595 if (OuterLoopLatchBI->
getSuccessor(0) == OuterLoopHeader)
2596 OuterLoopLatchSuccessor = OuterLoopLatchBI->
getSuccessor(1);
2598 OuterLoopLatchSuccessor = OuterLoopLatchBI->
getSuccessor(0);
2601 OuterLoopLatchSuccessor, DTUpdates);
2602 updateSuccessor(OuterLoopLatchBI, OuterLoopLatchSuccessor, InnerLoopLatch,
2606 restructureLoops(OuterLoop, InnerLoop, InnerLoopPreHeader,
2607 OuterLoopPreHeader);
2609 moveLCSSAPhis(InnerLoopLatchSuccessor, InnerLoopHeader, InnerLoopLatch,
2610 OuterLoopHeader, OuterLoopLatch, InnerLoop->
getExitBlock(),
2616 auto &OuterInnerReductions = LIL.getOuterInnerReductions();
2619 for (PHINode &
PHI : InnerLoopHeader->
phis())
2620 if (OuterInnerReductions.contains(&
PHI))
2623 for (PHINode &
PHI : OuterLoopHeader->
phis())
2624 if (OuterInnerReductions.contains(&
PHI))
2630 for (PHINode *
PHI : OuterLoopPHIs) {
2633 assert(OuterInnerReductions.count(
PHI) &&
"Expected a reduction PHI node");
2635 for (PHINode *
PHI : InnerLoopPHIs) {
2638 assert(OuterInnerReductions.count(
PHI) &&
"Expected a reduction PHI node");
2657 SmallVector<Instruction *, 4> MayNeedLCSSAPhis;
2658 for (Instruction &
I :
2664 "LoopInterchange handed dominance-broken IR to LCSSA rebuild");
2684 LLVM_DEBUG(
dbgs() <<
"Not valid loop candidate for interchange\n");
2692 <<
"Computed dependence info, invoking the transform.";
2696 if (!LoopInterchange(&AR.
SE, &AR.
LI, &DI, &AR.
DT, &AR, &ORE).run(LN))
2698 U.markLoopNestChanged(
true);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file defines the StringMap class.
ReachingDefInfo InstSet InstSet & Ignore
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
This file defines the interface for the loop cache analysis.
SmallVector< Loop *, 4 > LoopVector
Loop::LoopBounds::Direction Direction
static cl::list< RuleTy > Profitabilities("loop-interchange-profitabilities", cl::MiscFlags::CommaSeparated, cl::Hidden, cl::desc("List of profitability heuristics to be used. They are applied in " "the given order"), cl::list_init< RuleTy >({RuleTy::PerInstrOrderCost, RuleTy::ForVectorization}), cl::values(clEnumValN(RuleTy::PerLoopCacheAnalysis, "cache", "Prioritize loop cache cost"), clEnumValN(RuleTy::PerInstrOrderCost, "instorder", "Prioritize the IVs order of each instruction"), clEnumValN(RuleTy::ForVectorization, "vectorize", "Prioritize vectorization"), clEnumValN(RuleTy::Ignore, "ignore", "Ignore profitability, force interchange (does not " "work with other options)")))
static cl::opt< int > LoopInterchangeCostThreshold("loop-interchange-threshold", cl::init(0), cl::Hidden, cl::desc("Interchange if you gain more than this number"))
static FreezeInst * findFreezeInInnerLatchCloneSet(Loop *InnerLoop, ArrayRef< PHINode * > InnerLoopInductions)
static cl::opt< unsigned int > MinLoopNestDepth("loop-interchange-min-loop-nest-depth", cl::init(2), cl::Hidden, cl::desc("Minimum depth of loop nest considered for the transform"))
static void updateSuccessor(Instruction *Term, BasicBlock *OldBB, BasicBlock *NewBB, std::vector< DominatorTree::UpdateType > &DTUpdates, bool MustUpdateOnce=true)
static cl::opt< bool > EnableReduction2Memory("loop-interchange-reduction-to-mem", cl::init(false), cl::Hidden, cl::desc("Support for the inner-loop reduction pattern."))
static bool areInnerLoopLatchPHIsSupported(Loop *InnerLoop, ArrayRef< PHINode * > InductionPHIs)
The transform partially clones the inner loop's latch block, but PHI nodes cannot be cloned this way.
static bool isComputableLoopNest(ScalarEvolution *SE, ArrayRef< Loop * > LoopList)
static bool areOuterLoopExitPHIsSupported(Loop *OuterLoop, Loop *InnerLoop)
static FreezeInst * findFreezeInReNestedBlocks(Loop *OuterLoop, Loop *InnerLoop)
static void moveBBContents(BasicBlock *FromBB, Instruction *InsertBefore)
Move all instructions except the terminator from FromBB right before InsertBefore.
static void simplifyLCSSAPhis(Loop *OuterLoop, Loop *InnerLoop)
This deals with a corner case when a LCSSA phi node appears in a non-exit block: the outer loop latch...
static void interChangeDependencies(CharMatrix &DepMatrix, unsigned FromIndx, unsigned ToIndx)
static void moveLCSSAPhis(BasicBlock *InnerExit, BasicBlock *InnerHeader, BasicBlock *InnerLatch, BasicBlock *OuterHeader, BasicBlock *OuterLatch, BasicBlock *OuterExit, Loop *InnerLoop, LoopInfo *LI)
static void printDepMatrix(CharMatrix &DepMatrix)
static cl::opt< unsigned int > MaxMemInstrRatio("loop-interchange-max-mem-instr-ratio", cl::init(4), cl::Hidden, cl::desc("Maximum number of load/store instructions squared in relation to " "the total number of instructions. Higher value may lead to more " "interchanges at the cost of compile-time"))
static void swapBBContents(BasicBlock *BB1, BasicBlock *BB2)
Swap instructions between BB1 and BB2 but keep terminators intact.
static PHINode * findInnerReductionPhi(Loop *L, Value *V, SmallVectorImpl< Instruction * > &HasNoWrapInsts, SmallVectorImpl< Instruction * > &HasNoInfInsts)
static bool areInnerLoopExitPHIsSupported(Loop *OuterL, Loop *InnerL, SmallPtrSetImpl< PHINode * > &Reductions, PHINode *LcssaReduction)
We currently only support LCSSA PHI nodes in the inner loop exit if their users are either of the fol...
static cl::opt< unsigned int > MaxLoopNestDepth("loop-interchange-max-loop-nest-depth", cl::init(10), cl::Hidden, cl::desc("Maximum depth of loop nest considered for the transform"))
static bool hasSupportedLoopDepth(ArrayRef< Loop * > LoopList, OptimizationRemarkEmitter &ORE)
static bool inThisOrder(const Instruction *Src, const Instruction *Dst)
Return true if Src appears before Dst in the same basic block.
static bool canVectorize(const CharMatrix &DepMatrix, unsigned LoopId)
Return true if we can vectorize the loop specified by LoopId.
static bool isLegalToInterChangeLoops(CharMatrix &DepMatrix, unsigned InnerLoopId, unsigned OuterLoopId)
static Value * followLCSSA(Value *SV)
static void populateWorklist(Loop &L, LoopVector &LoopList)
static bool populateDependencyMatrix(CharMatrix &DepMatrix, unsigned Level, Loop *L, DependenceInfo *DI, ScalarEvolution *SE, OptimizationRemarkEmitter *ORE)
static std::optional< bool > isLexicographicallyPositive(ArrayRef< char > DV, unsigned Begin, unsigned End)
static bool checkReductionKind(Loop *L, PHINode *PHI, SmallVectorImpl< Instruction * > &HasNoWrapInsts, SmallVectorImpl< Instruction * > &HasNoInfInsts)
static std::optional< const SCEV * > getAddRecCoefficient(ScalarEvolution &SE, const SCEV *S, const Loop *L)
If \S contains an affine addrec for L, return the step recurrence of it.
static bool noDuplicateRulesAndIgnore(ArrayRef< RuleTy > Rules)
This file defines the interface for the loop nest analysis.
This header provides classes for managing a pipeline of passes over loops in LLVM IR.
loop Loop Strength Reduction
uint64_t IntrinsicInst * II
static bool processLoop(Loop &L, const AArch64Subtarget &ST, DataLayout DL)
SmallVector< Value *, 8 > ValueVector
This file defines the SmallSet class.
This file defines the SmallVector class.
static bool isProfitable(const StableFunctionMap::StableFunctionEntries &SFS)
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Represent a constant reference to an array (0 or more elements consecutively in memory),...
const T & front() const
Get the first element.
size_t size() const
Get the array size.
ArrayRef< T > slice(size_t N, size_t M) const
slice(n, m) - Chop off the first N elements of the array, and keep M elements in the array.
LLVM Basic Block Representation.
iterator begin()
Instruction iterator methods.
iterator_range< const_phi_iterator > phis() const
Returns a range that iterates over the phis in the basic block.
const Function * getParent() const
Return the enclosing method, or null if none.
LLVM_ABI InstListType::const_iterator getFirstNonPHIIt() const
Returns an iterator to the first instruction in this block that is not a PHINode instruction.
LLVM_ABI const BasicBlock * getUniqueSuccessor() const
Return the successor of this block if it has a unique successor.
LLVM_ABI void replacePhiUsesWith(BasicBlock *Old, BasicBlock *New)
Update all phi nodes in this basic block to refer to basic block New instead of basic block Old.
LLVM_ABI const BasicBlock * getUniquePredecessor() const
Return the predecessor of this block if it has a unique predecessor block.
LLVM_ABI LLVMContext & getContext() const
Get the context in which this basic block lives.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
void splice(BasicBlock::iterator ToIt, BasicBlock *FromBB)
Transfer all instructions from FromBB to this basic block at ToIt.
static LLVM_ABI std::unique_ptr< CacheCost > getCacheCost(Loop &Root, LoopStandardAnalysisResults &AR, DependenceInfo &DI, std::optional< unsigned > TRT=std::nullopt)
Create a CacheCost for the loop nest rooted by Root.
CacheCostTy getLoopCost(const Loop &L) const
Return the estimated cost of loop L if the given loop is part of the loop nest associated with this o...
Value * getCondition() const
BasicBlock * getSuccessor(unsigned i) const
iterator find(const_arg_type_t< KeyT > Val)
DependenceInfo - This class is the main dependence-analysis driver.
LLVM_ABI std::unique_ptr< Dependence > depends(Instruction *Src, Instruction *Dst, bool UnderRuntimeAssumptions=false)
depends - Tests for a dependence between the Src and Dst instructions.
void applyUpdates(ArrayRef< UpdateType > Updates)
Inform the dominator tree about a sequence of CFG edge insertions and deletions and perform a batch u...
LLVM_ABI bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
This class represents a freeze function that returns random concrete value if an operand is either a ...
static LLVM_ABI bool isInductionPHI(PHINode *Phi, const Loop *L, ScalarEvolution *SE, InductionDescriptor &D, ArrayRef< const SCEVPredicate * > NoWrapPreds={}, const SCEV *Expr=nullptr, SmallVectorImpl< Instruction * > *CastsToIgnore=nullptr)
Returns true if Phi is an induction in the loop L.
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
LLVM_ABI void moveAfter(Instruction *MovePos)
Unlink this instruction from its current basic block and insert it into the basic block that MovePos ...
LLVM_ABI void insertBefore(InstListType::iterator InsertPos)
Insert an unlinked instruction into a basic block immediately before the specified position.
LLVM_ABI bool mayHaveSideEffects() const LLVM_READONLY
Return true if the instruction may have side effects.
This class provides an interface for updating the loop pass manager based on mutations to the loop ne...
bool contains(const LoopT *L) const
Return true if the specified loop is contained within this loop.
BlockT * getLoopLatch() const
If there is a single latch block for this loop, return it.
bool isInnermost() const
Return true if the loop does not contain any (natural) loops.
void removeBlockFromLoop(BlockT *BB)
This removes the specified basic block from the current loop, updating the Blocks as appropriate.
const std::vector< LoopT * > & getSubLoops() const
Return the loops contained entirely within this loop.
BlockT * getHeader() const
iterator_range< block_iterator > blocks() const
void addChildLoop(LoopT *NewChild)
Add the specified loop to be a child of this loop.
void addBlockEntry(BlockT *BB)
This adds a basic block directly to the basic block list.
BlockT * getExitBlock() const
If getExitBlocks would return exactly one block, return that block.
BlockT * getLoopPreheader() const
If there is a preheader for this loop, return it.
BlockT * getExitingBlock() const
If getExitingBlocks would return exactly one block, return that block.
BlockT * getUniqueExitBlock() const
If getUniqueExitBlocks would return exactly one block, return that block.
LoopT * removeChildLoop(iterator I)
This removes the specified child from being a subloop of this loop.
void changeTopLevelLoop(LoopT *OldLoop, LoopT *NewLoop)
Replace the specified loop in the top-level loops list with the indicated loop.
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
void changeLoopFor(const BlockT *BB, LoopT *L)
Change the top-level loop that contains BB to the specified loop.
This class represents a loop nest and can be used to query its properties.
static const BasicBlock & skipEmptyBlockUntil(const BasicBlock *From, const BasicBlock *End, bool CheckUniquePred=false)
Recursivelly traverse all empty 'single successor' basic blocks of From (if there are any).
ArrayRef< Loop * > getLoops() const
Get the loops in the nest.
Function * getParent() const
Return the function to which the loop-nest belongs.
Loop & getOutermostLoop() const
Return the outermost loop in the loop nest.
Represents a single loop in the control flow graph.
DebugLoc getStartLoc() const
Return the debug location of the start of this loop.
bool isLoopInvariant(const Value *V) const
Return true if the specified value is loop invariant.
StringRef getName() const
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
bool isComplete() const
If the PHI node is complete which means all of its parent's predecessors have incoming value in this ...
op_range incoming_values()
void setIncomingBlock(unsigned i, BasicBlock *BB)
void setIncomingValue(unsigned i, Value *V)
static unsigned getIncomingValueNumForOperand(unsigned i)
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
The RecurrenceDescriptor is used to identify recurrences variables in a loop.
Instruction * getExactFPMathInst() const
Returns 1st non-reassociative FP instruction in the PHI node's use-chain.
unsigned getOpcode() const
static LLVM_ABI bool isReductionPHI(PHINode *Phi, Loop *TheLoop, RecurrenceDescriptor &RedDes, DemandedBits *DB=nullptr, AssumptionCache *AC=nullptr, DominatorTree *DT=nullptr, ScalarEvolution *SE=nullptr)
Returns true if Phi is a reduction in TheLoop.
bool hasUsesOutsideReductionChain() const
Returns true if the reduction PHI has any uses outside the reduction chain.
LLVM_ABI SmallVector< Instruction *, 4 > getReductionOpChain(PHINode *Phi, Loop *L) const
Attempts to find a chain of operations from Phi to LoopExitInst that can be treated as a set of reduc...
RecurKind getRecurrenceKind() const
This node represents a polynomial recurrence on the trip count of the specified loop.
bool isAffine() const
Return true if this represents an expression A + B*x where A and B are loop invariant values.
const Loop * getLoop() const
SCEVUse getStepRecurrence(ScalarEvolution &SE) const
Constructs and returns the recurrence indicating how much this expression steps by.
This class represents an analyzed expression in the program.
LLVM_ABI bool isZero() const
Return true if the expression is a constant zero.
The main scalar evolution driver.
LLVM_ABI const SCEV * getAbsExpr(const SCEV *Op, bool IsNSW)
LLVM_ABI const SCEV * getBackedgeTakenCount(const Loop *L, ExitCountKind Kind=Exact)
If the specified loop has a predictable backedge-taken count, return it, otherwise return a SCEVCould...
LLVM_ABI const SCEV * getSCEV(Value *V)
Return a SCEV expression for the full generality of the specified expression.
LLVM_ABI void forgetLoop(const Loop *L)
This method should be called by the client when it has changed a loop in a way that may effect Scalar...
LLVM_ABI bool isLoopInvariant(const SCEV *S, const Loop *L)
Return true if the value of the given SCEV is unchanging in the specified loop.
LLVM_ABI const SCEV * getPointerBase(const SCEV *V)
Transitively follow the chain of pointer-type operands until reaching a SCEV that does not have a sin...
LLVM_ABI bool isKnownPredicate(CmpPredicate Pred, SCEVUse LHS, SCEVUse RHS)
Test if the given expression is known to satisfy the condition described by Pred, LHS,...
size_type size() const
Determine the number of elements in the SetVector.
bool insert(const value_type &X)
Insert a new element into the SetVector.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
bool contains(ConstPtrType Ptr) const
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
A SetVector that performs no allocations if smaller than a certain size.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
std::pair< iterator, bool > try_emplace(StringRef Key, ArgsTy &&...Args)
Emplace a new element for the specified key into the map if the key isn't already in the map.
Represent a constant reference to a string, i.e.
constexpr size_t size() const
Get the string size.
A Use represents the edge between a Value definition and its users.
void setOperand(unsigned i, Value *Val)
Value * getOperand(unsigned i) const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
LLVM_ABI bool hasOneUser() const
Return true if there is exactly one user of this value.
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
iterator_range< user_iterator > users()
LLVM_ABI User * getUniqueUndroppableUser()
Return true if there is exactly one unique user of this value that cannot be dropped (that user can h...
const ParentTy * getParent() const
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ BasicBlock
Various leaf nodes.
list_initializer< Ty > list_init(ArrayRef< Ty > Vals)
ValuesClass values(OptsTy... Options)
Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...
initializer< Ty > init(const Ty &Val)
DXILDebugInfoMap run(Module &M)
NodeAddr< PhiNode * > Phi
friend class Instruction
Iterator for Instructions in a `BasicBlock.
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI BasicBlock * InsertPreheaderForLoop(Loop *L, DominatorTree *DT, LoopInfo *LI, MemorySSAUpdater *MSSAU, bool PreserveLCSSA)
InsertPreheaderForLoop - Once we discover that a loop doesn't have a preheader, this method is called...
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI bool verifyFunction(const Function &F, raw_ostream *OS=nullptr)
Check a function for errors, useful for use when debugging a pass.
auto successors(const MachineBasicBlock *BB)
const Value * getLoadStorePointerOperand(const Value *V)
A helper function that returns the pointer operand of a load or store instruction.
LLVM_ABI bool formLCSSARecursively(Loop &L, const DominatorTree &DT, const LoopInfo *LI, ScalarEvolution *SE)
Put a loop nest into LCSSA form.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
constexpr auto equal_to(T &&Arg)
Functor variant of std::equal_to that can be used as a UnaryPredicate in functional algorithms like a...
auto map_range(ContainerTy &&C, FuncTy F)
Return a range that applies F to the elements of C.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
AnalysisManager< Loop, LoopStandardAnalysisResults & > LoopAnalysisManager
The loop analysis manager.
OutputIt transform(R &&Range, OutputIt d_first, UnaryFunction F)
Wrapper function around std::transform to apply a function to a range and store the result elsewhere.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
auto drop_end(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the last N elements excluded.
IRBuilder(LLVMContext &, FolderTy, InserterTy, MDNode *, ArrayRef< OperandBundleDef >) -> IRBuilder< FolderTy, InserterTy >
RecurKind
These are the kinds of recurrences that we support.
@ UMin
Unsigned integer min implemented in terms of select(cmp()).
@ FMinimumNum
FP min with llvm.minimumnum semantics.
@ Or
Bitwise or logical OR of integers.
@ FMinimum
FP min with llvm.minimum semantics.
@ Mul
Product of integers.
@ AnyOf
AnyOf reduction with select(cmp(),x,y) where one of (x,y) is loop invariant, and both x and y are int...
@ Xor
Bitwise or logical XOR of integers.
@ FMax
FP max implemented in terms of select(cmp()).
@ FMaximum
FP max with llvm.maximum semantics.
@ FMulAdd
Sum of float products with llvm.fmuladd(a * b + sum).
@ SMax
Signed integer max implemented in terms of select(cmp()).
@ And
Bitwise or logical AND of integers.
@ SMin
Signed integer min implemented in terms of select(cmp()).
@ FMin
FP min implemented in terms of select(cmp()).
@ FMaximumNum
FP max with llvm.maximumnum semantics.
@ UMax
Unsigned integer max implemented in terms of select(cmp()).
LLVM_ABI BasicBlock * SplitBlock(BasicBlock *Old, BasicBlock::iterator SplitPt, DominatorTree *DT, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, const Twine &BBName="")
Split the specified block at the specified instruction.
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
LLVM_ABI bool formLCSSAForInstructions(SmallVectorImpl< Instruction * > &Worklist, const DominatorTree &DT, const LoopInfo &LI, ScalarEvolution *SE, SmallVectorImpl< PHINode * > *PHIsToRemove=nullptr, SmallVectorImpl< PHINode * > *InsertedPHIs=nullptr)
Ensures LCSSA form for every instruction from the Worklist in the scope of innermost containing loop.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI PreservedAnalyses getLoopPassPreservedAnalyses()
Returns the minimum set of Analyses that all loop passes must preserve.
auto predecessors(const MachineBasicBlock *BB)
iterator_range< pointer_iterator< WrappedIteratorT > > make_pointer_range(RangeT &&Range)
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Next
bool all_equal(std::initializer_list< T > Values)
Returns true if all Values in the initializer lists are equal or the list.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
LLVM_ABI PreservedAnalyses run(LoopNest &L, LoopAnalysisManager &AM, LoopStandardAnalysisResults &AR, LPMUpdater &U)
The adaptor from a function pass to a loop pass computes these analyses and makes them available to t...