57#define DEBUG_TYPE "loop-interchange"
59STATISTIC(LoopsInterchanged,
"Number of loops interchanged");
63 cl::desc(
"Interchange if you gain more than this number"));
67 cl::desc(
"Maximum number of load/store instructions squared in relation to "
68 "the total number of instructions. Higher value may lead to more "
69 "interchanges at the cost of compile-time"));
83using CharMatrix = std::vector<std::vector<char>>;
98 cl::desc(
"Minimum depth of loop nest considered for the transform"));
103 cl::desc(
"Maximum depth of loop nest considered for the transform"));
109 cl::desc(
"List of profitability heuristics to be used. They are applied in "
112 RuleTy::ForVectorization}),
114 "Prioritize loop cache cost"),
115 clEnumValN(RuleTy::PerInstrOrderCost,
"instorder",
116 "Prioritize the IVs order of each instruction"),
117 clEnumValN(RuleTy::ForVectorization,
"vectorize",
118 "Prioritize vectorization"),
120 "Ignore profitability, force interchange (does not "
121 "work with other options)")));
126 cl::desc(
"Support for the inner-loop reduction pattern."));
131 for (RuleTy Rule : Rules) {
132 if (!Set.insert(Rule).second)
134 if (Rule == RuleTy::Ignore)
141 for (
auto &Row : DepMatrix) {
154 assert(Src->getParent() == Dst->getParent() && Src != Dst &&
155 "Expected Src and Dst to be different instructions in the same BB");
157 bool FoundSrc =
false;
178 unsigned NumInsts = 0;
204 unsigned NumMemInstr = MemInstr.
size();
206 <<
" Loads and Stores to analyze\n");
208 static_cast<uint64_t>(NumMemInstr) * NumMemInstr) {
211 L->getStartLoc(), L->getHeader())
212 <<
"Number of loads/stores exceeded, the supported maximum can be "
213 "increased with option -loop-interchange-max-mem-instr-ratio.";
223 for (
I = MemInstr.
begin(), IE = MemInstr.
end();
I != IE; ++
I) {
224 for (J =
I, JE = MemInstr.
end(); J != JE; ++J) {
225 std::vector<char> Dep;
232 if (
auto D = DI->
depends(Src, Dst)) {
233 assert(
D->isOrdered() &&
"Expected an output, flow or anti dep.");
236 if (
D->normalize(SE))
239 D->isFlow() ?
"flow" :
D->isAnti() ?
"anti" :
"output";
240 dbgs() <<
"Found " << DepType
241 <<
" dependency between Src and Dst\n"
242 <<
" Src:" << *Src <<
"\n Dst:" << *Dst <<
'\n');
243 unsigned Levels =
D->getLevels();
245 for (
unsigned II = 1;
II <= Levels; ++
II) {
252 unsigned Dir =
D->getDirection(
II);
266 if (
D->isConfused()) {
267 assert(Dep.empty() &&
"Expected empty dependency vector");
268 Dep.assign(L->getLoopDepth() + Level - 1,
'*');
271 while (Dep.size() < L->getLoopDepth() + Level - 1) {
278 if (Dep.size() > Level)
279 Dep.erase(Dep.begin(), Dep.end() - Level);
286 L->getStartLoc(), L->getHeader())
287 <<
"All loops have dependencies in all directions.";
293 bool IsKnownForward =
true;
294 if (Src->getParent() != Dst->getParent()) {
298 IsKnownForward =
false;
304 "Unexpected instructions");
309 bool IsReversed =
D->getSrc() != Src;
311 IsKnownForward =
false;
327 DepMatrix.push_back(Dep);
334 DepMatrix[Ite->second].back() =
'*';
346 for (
auto &Row : DepMatrix)
355static std::optional<bool>
368 unsigned InnerLoopId,
369 unsigned OuterLoopId) {
370 unsigned NumRows = DepMatrix.size();
371 std::vector<char> Cur;
373 for (
unsigned Row = 0; Row < NumRows; ++Row) {
376 Cur = DepMatrix[Row];
389 std::swap(Cur[InnerLoopId], Cur[OuterLoopId]);
398 << L.getHeader()->getParent()->getName() <<
" Loop: %"
399 << L.getHeader()->getName() <<
'\n');
400 assert(LoopList.
empty() &&
"LoopList should initially be empty!");
401 Loop *CurrentLoop = &L;
402 const std::vector<Loop *> *Vec = &CurrentLoop->
getSubLoops();
403 while (!Vec->empty()) {
407 if (Vec->size() != 1) {
413 CurrentLoop = Vec->front();
421 unsigned LoopNestDepth = LoopList.
size();
423 LLVM_DEBUG(
dbgs() <<
"Unsupported depth of loop nest " << LoopNestDepth
431 <<
"Unsupported depth of loop nest, the supported range is ["
442 for (
Loop *L : LoopList) {
448 if (L->getNumBackEdges() != 1) {
452 if (!L->getExitingBlock()) {
463class LoopInterchangeLegality {
465 LoopInterchangeLegality(
Loop *Outer,
Loop *Inner, ScalarEvolution *SE,
466 OptimizationRemarkEmitter *ORE, DominatorTree *DT)
467 : OuterLoop(
Outer), InnerLoop(Inner), SE(SE), DT(DT), ORE(ORE) {}
470 bool canInterchangeLoops(
unsigned InnerLoopId,
unsigned OuterLoopId,
471 CharMatrix &DepMatrix);
475 bool isLoopStructureUnderstood();
477 bool currentLimitations();
479 const SmallPtrSetImpl<PHINode *> &getOuterInnerReductions()
const {
480 return OuterInnerReductions;
484 return InnerLoopInductions;
487 ArrayRef<Instruction *> getHasNoWrapReductions()
const {
488 return HasNoWrapReductions;
491 ArrayRef<Instruction *> getHasNoInfInsts()
const {
return HasNoInfInsts; }
497 struct InnerReduction {
505 StoreInst *LcssaStore;
512 return InnerReductions;
516 bool tightlyNested(
Loop *Outer,
Loop *Inner);
517 bool containsUnsafeInstructions(BasicBlock *BB, Instruction *Skip);
529 bool checkInductionsAndReductions(
Loop *OuterLoop);
541 bool isInnerReduction(
Loop *L, PHINode *Phi,
542 SmallVectorImpl<Instruction *> &HasNoWrapInsts);
551 OptimizationRemarkEmitter *ORE;
555 SmallPtrSet<PHINode *, 4> OuterInnerReductions;
563 SmallVector<Instruction *, 4> HasNoWrapReductions;
567 SmallVector<Instruction *, 4> HasNoInfInsts;
576class CacheCostManager {
578 LoopStandardAnalysisResults *AR;
583 std::optional<std::unique_ptr<CacheCost>> CC;
587 DenseMap<const Loop *, unsigned> CostMap;
589 void computeIfUnitinialized();
592 CacheCostManager(
Loop *OutermostLoop, LoopStandardAnalysisResults *AR,
594 : OutermostLoop(OutermostLoop), AR(AR), DI(DI) {}
595 CacheCost *getCacheCost();
596 const DenseMap<const Loop *, unsigned> &getCostMap();
601class LoopInterchangeProfitability {
603 LoopInterchangeProfitability(
Loop *Outer,
Loop *Inner, ScalarEvolution *SE,
604 OptimizationRemarkEmitter *ORE)
605 : OuterLoop(
Outer), InnerLoop(Inner), SE(SE), ORE(ORE) {}
609 unsigned InnerLoopId,
unsigned OuterLoopId,
610 CharMatrix &DepMatrix, CacheCostManager &CCM);
613 int getInstrOrderCost();
614 std::optional<bool> isProfitablePerLoopCacheAnalysis(
615 const DenseMap<const Loop *, unsigned> &CostMap, CacheCost *CC);
616 std::optional<bool> isProfitablePerInstrOrderCost();
617 std::optional<bool> isProfitableForVectorization(
unsigned InnerLoopId,
618 unsigned OuterLoopId,
619 CharMatrix &DepMatrix);
627 OptimizationRemarkEmitter *ORE;
631class LoopInterchangeTransform {
633 LoopInterchangeTransform(
Loop *Outer,
Loop *Inner, ScalarEvolution *SE,
634 LoopInfo *LI, DominatorTree *DT,
635 const LoopInterchangeLegality &LIL)
636 : OuterLoop(
Outer), InnerLoop(Inner), SE(SE), LI(LI), DT(DT), LIL(LIL) {}
639 void transform(ArrayRef<Instruction *> DropNoWrapInsts,
640 ArrayRef<Instruction *> DropNoInfInsts);
641 void reduction2Memory();
642 void restructureLoops(
Loop *NewInner,
Loop *NewOuter,
643 BasicBlock *OrigInnerPreHeader,
644 BasicBlock *OrigOuterPreHeader);
645 void removeChildLoop(
Loop *OuterLoop,
Loop *InnerLoop);
648 void adjustLoopBranches();
659 const LoopInterchangeLegality &LIL;
662struct LoopInterchange {
663 ScalarEvolution *SE =
nullptr;
664 LoopInfo *LI =
nullptr;
665 DependenceInfo *DI =
nullptr;
666 DominatorTree *DT =
nullptr;
667 LoopStandardAnalysisResults *AR =
nullptr;
670 OptimizationRemarkEmitter *ORE;
672 LoopInterchange(ScalarEvolution *SE, LoopInfo *LI, DependenceInfo *DI,
673 DominatorTree *DT, LoopStandardAnalysisResults *AR,
674 OptimizationRemarkEmitter *ORE)
675 : SE(SE), LI(LI), DI(DI), DT(DT), AR(AR), ORE(ORE) {}
678 if (
L->getParentLoop())
680 SmallVector<Loop *, 8> LoopList;
682 return processLoopList(LoopList);
702 collectPerfectNests(LoopNest &LN) {
705 if (!
L->isInnermost())
708 SmallVector<Loop *, 8> LoopList;
717 std::reverse(LoopList.
begin(), LoopList.
end());
718 if (LoopList.
size() >= 2)
719 LoopLists.
push_back(std::move(LoopList));
724 bool run(LoopNest &LN) {
726 if (LoopLists.
empty()) {
727 LLVM_DEBUG(
dbgs() <<
"No Valid candidates for loop interchange.\n");
731 for (SmallVector<Loop *, 8> &LoopList : LoopLists) {
737 LLVM_DEBUG(
dbgs() <<
"Not valid loop candidate for interchange\n");
740 Changed |= processLoopList(LoopList);
748 return LoopList.
size() - 1;
751 bool processLoopList(SmallVectorImpl<Loop *> &LoopList) {
756 "Unsupported depth of loop nest.");
758 unsigned LoopNestDepth = LoopList.
size();
761 dbgs() <<
"Processing LoopList of size = " << LoopNestDepth
762 <<
" containing the following loops:\n";
763 for (
auto *L : LoopList) {
769 CharMatrix DependencyMatrix;
770 Loop *OuterMostLoop = *(LoopList.begin());
772 OuterMostLoop, DI, SE, ORE)) {
784 <<
"' needs an unique exit block");
788 unsigned SelecLoopId = selectLoopForInterchange(LoopList);
789 CacheCostManager CCM(LoopList[0], AR, DI);
794 for (
unsigned j = SelecLoopId;
j > 0;
j--) {
795 bool ChangedPerIter =
false;
796 for (
unsigned i = SelecLoopId; i > SelecLoopId -
j; i--) {
798 processLoop(LoopList, i, i - 1, DependencyMatrix, CCM);
799 ChangedPerIter |= Interchanged;
810 bool processLoop(SmallVectorImpl<Loop *> &LoopList,
unsigned InnerLoopId,
811 unsigned OuterLoopId,
812 std::vector<std::vector<char>> &DependencyMatrix,
813 CacheCostManager &CCM) {
814 Loop *OuterLoop = LoopList[OuterLoopId];
815 Loop *InnerLoop = LoopList[InnerLoopId];
817 <<
" and OuterLoopId = " << OuterLoopId <<
"\n");
818 LoopInterchangeLegality LIL(OuterLoop, InnerLoop, SE, ORE, DT);
819 if (!LIL.canInterchangeLoops(InnerLoopId, OuterLoopId, DependencyMatrix)) {
820 LLVM_DEBUG(
dbgs() <<
"Cannot prove legality, not interchanging loops '"
821 << OuterLoop->
getName() <<
"' and '"
822 << InnerLoop->
getName() <<
"'\n");
827 <<
"' are legal to interchange\n");
828 LoopInterchangeProfitability LIP(OuterLoop, InnerLoop, SE, ORE);
829 if (!LIP.isProfitable(InnerLoop, OuterLoop, InnerLoopId, OuterLoopId,
830 DependencyMatrix, CCM)) {
832 <<
"' and '" << InnerLoop->
getName()
833 <<
"' not profitable.\n");
838 return OptimizationRemark(
DEBUG_TYPE,
"Interchanged",
841 <<
"Loop interchanged with enclosing loop.";
844 LoopInterchangeTransform LIT(OuterLoop, InnerLoop, SE, LI, DT, LIL);
845 LIT.transform(LIL.getHasNoWrapReductions(), LIL.getHasNoInfInsts());
847 << OuterLoop->
getName() <<
"' and inner loop '"
848 << InnerLoop->
getName() <<
"'\n");
854 std::swap(LoopList[OuterLoopId], LoopList[InnerLoopId]);
867bool LoopInterchangeLegality::containsUnsafeInstructions(
BasicBlock *BB,
869 return any_of(*BB, [Skip](
const Instruction &
I) {
872 return I.mayHaveSideEffects() ||
I.mayReadFromMemory();
901 auto IsDirectInnerLoopBlock = [InnerLoop](
BasicBlock *BB) {
904 [BB](
Loop *SubLoop) { return SubLoop->contains(BB); });
910 Worklist.
insert(Condition);
912 for (
PHINode *Induction : InnerLoopInductions) {
914 Induction->getIncomingValueForBlock(InnerLoop->
getLoopLatch()));
915 if (Incoming && !
is_contained(InnerLoopInductions, Incoming))
916 Worklist.
insert(Incoming);
919 for (
unsigned I = 0;
I < Worklist.
size(); ++
I) {
925 if (!OperandI || !IsDirectInnerLoopBlock(OperandI->getParent()) ||
928 Worklist.
insert(OperandI);
934bool LoopInterchangeLegality::tightlyNested(
Loop *OuterLoop,
Loop *InnerLoop) {
940 <<
"' and '" << InnerLoop->
getName()
941 <<
"' are tightly nested\n");
961 for (BasicBlock *Succ :
successors(OuterLoopHeader))
962 if (Succ != InnerLoopPreHeader && Succ != InnerLoop->
getHeader())
965 LLVM_DEBUG(
dbgs() <<
"Checking instructions in Loop header and Loop latch\n");
971 assert(InnerReductions.size() <= 1 &&
972 "So far we only support at most one reduction.");
973 if (InnerReductions.size() == 1)
974 Skip = InnerReductions[0].LcssaStore;
978 if (containsUnsafeInstructions(OuterLoopHeader, Skip) ||
979 containsUnsafeInstructions(OuterLoopLatch, Skip))
985 if (InnerLoopPreHeader != OuterLoopHeader &&
986 containsUnsafeInstructions(InnerLoopPreHeader, Skip))
994 if (&SuccInner != OuterLoopLatch) {
996 <<
" does not lead to the outer loop latch.\n";);
1002 if (containsUnsafeInstructions(InnerLoopExit, Skip))
1010bool LoopInterchangeLegality::isLoopStructureUnderstood() {
1012 for (PHINode *InnerInduction : InnerLoopInductions) {
1013 unsigned Num = InnerInduction->getNumOperands();
1014 for (
unsigned i = 0; i < Num; ++i) {
1015 Value *Val = InnerInduction->getOperand(i);
1025 if (InnerInduction->getIncomingBlock(IncomBlockIndx) ==
1026 InnerLoopPreheader &&
1040 CondBrInst *InnerLoopLatchBI =
1042 if (!InnerLoopLatchBI)
1061 std::function<bool(
Value *)> IsPathToInnerIndVar;
1062 IsPathToInnerIndVar = [
this, &IsPathToInnerIndVar](
const Value *
V) ->
bool {
1071 return IsPathToInnerIndVar(
I->getOperand(0));
1073 return IsPathToInnerIndVar(
I->getOperand(0)) &&
1074 IsPathToInnerIndVar(
I->getOperand(1));
1080 if (IsPathToInnerIndVar(Op0) && IsPathToInnerIndVar(Op1))
1088 }
else if (IsPathToInnerIndVar(Op1) && !
isa<Constant>(Op1)) {
1093 if (
Left ==
nullptr)
1110 if (
PHI->getNumIncomingValues() != 1)
1198 assert(
I->getOpcode() == OpCode &&
1199 "Expected the instruction to be the reduction operation");
1204 if (
I->hasNoSignedWrap() ||
I->hasNoUnsignedWrap())
1228 if (
PHI->getNumIncomingValues() == 1)
1241bool LoopInterchangeLegality::isInnerReduction(
1242 Loop *L, PHINode *Phi, SmallVectorImpl<Instruction *> &HasNoWrapInsts) {
1246 if (!
L->isInnermost()) {
1247 LLVM_DEBUG(
dbgs() <<
"Only supported when the loop is the innermost.\n");
1249 return OptimizationRemarkMissed(
DEBUG_TYPE,
"UnsupportedInnerReduction",
1250 L->getStartLoc(),
L->getHeader())
1251 <<
"Only supported when the loop is the innermost.";
1256 if (
Phi->getNumIncomingValues() != 2)
1259 Value *Init =
Phi->getIncomingValueForBlock(
L->getLoopPreheader());
1260 Value *
Next =
Phi->getIncomingValueForBlock(
L->getLoopLatch());
1266 <<
"Only supported for the reduction with a constant initial value.\n");
1268 return OptimizationRemarkMissed(
DEBUG_TYPE,
"UnsupportedInnerReduction",
1269 L->getStartLoc(),
L->getHeader())
1270 <<
"Only supported for the reduction with a constant initial "
1279 if (!
L->contains(BB))
1284 if (!
Phi->hasOneUser())
1296 PHINode *Lcssa = NULL;
1297 for (
auto *U :
Next->users()) {
1302 if (Lcssa == NULL &&
P->getParent() == ExitBlock &&
1303 P->getIncomingValueForBlock(
L->getLoopLatch()) ==
Next)
1314 LLVM_DEBUG(
dbgs() <<
"Only supported when the reduction is used once in "
1315 "the outer loop.\n");
1317 return OptimizationRemarkMissed(
DEBUG_TYPE,
"UnsupportedInnerReduction",
1318 L->getStartLoc(),
L->getHeader())
1319 <<
"Only supported when the reduction is used once in the outer "
1325 StoreInst *LcssaStore =
1327 if (!LcssaStore || LcssaStore->
getParent() != ExitBlock)
1340 LLVM_DEBUG(
dbgs() <<
"Only supported when memory reference dominate "
1341 "the inner loop.\n");
1343 return OptimizationRemarkMissed(
DEBUG_TYPE,
"UnsupportedInnerReduction",
1344 L->getStartLoc(),
L->getHeader())
1345 <<
"Only supported when memory reference dominate the inner "
1356 SR.LcssaPhi = Lcssa;
1357 SR.LcssaStore = LcssaStore;
1361 InnerReductions.push_back(SR);
1365bool LoopInterchangeLegality::checkInductionsAndReductions(
Loop *OuterLoop) {
1366 auto ChildLoop = [](
Loop *
L) {
1367 assert(
L->getSubLoops().size() <= 1 &&
1368 "Expect at most one child loop for now.");
1369 return L->getSubLoops().empty() ? nullptr :
L->getSubLoops().front();
1372 Loop *InnerLoop = ChildLoop(OuterLoop);
1373 for (
Loop *CurLoop = OuterLoop; CurLoop; CurLoop = ChildLoop(CurLoop)) {
1374 for (PHINode &
PHI : CurLoop->getHeader()->phis()) {
1375 InductionDescriptor
ID;
1377 if (CurLoop == InnerLoop) {
1378 const SCEV *Step =
ID.getStep();
1381 InnerLoopInductions.push_back(&
PHI);
1386 if (CurLoop == OuterLoop) {
1388 if (
PHI.getNumIncomingValues() != 2) {
1389 LLVM_DEBUG(
dbgs() <<
"Only PHI nodes in the outer loop header with 2 "
1390 "incoming values are supported.\n");
1398 InnerLoop, V, HasNoWrapReductions, HasNoInfInsts);
1418 [InnerRedPhi](User *U) { return U == InnerRedPhi; })) {
1421 <<
"Failed to recognize PHI as an induction or reduction.\n");
1423 return OptimizationRemarkMissed(
DEBUG_TYPE,
"UnsupportedPHIOuter",
1426 <<
"Only outer loops with induction or reduction PHI nodes "
1427 "can be interchanged currently.";
1432 OuterInnerReductions.insert(&
PHI);
1433 OuterInnerReductions.insert(InnerRedPhi);
1435 if (OuterInnerReductions.count(&
PHI)) {
1436 LLVM_DEBUG(
dbgs() <<
"Found a reduction across the outer loop.\n");
1438 isInnerReduction(CurLoop, &
PHI, HasNoWrapReductions)) {
1443 return OptimizationRemarkMissed(
DEBUG_TYPE,
"UnsupportedPHIInner",
1444 CurLoop->getStartLoc(),
1445 CurLoop->getHeader())
1446 <<
"Only inner loops with induction or reduction PHI nodes "
1447 "can be interchanged currently.";
1455 if (InnerReductions.size() > 1) {
1458 return OptimizationRemarkMissed(
DEBUG_TYPE,
"UnsupportedInnerReduction",
1459 CurLoop->getStartLoc(),
1460 CurLoop->getHeader())
1461 <<
"Only supports at most one reduction.";
1467 return !InnerLoopInductions.empty();
1472bool LoopInterchangeLegality::currentLimitations() {
1482 dbgs() <<
"Loops where the latch is not the exiting block are not"
1483 <<
" supported currently.\n");
1485 return OptimizationRemarkMissed(
DEBUG_TYPE,
"ExitingNotLatch",
1488 <<
"Loops where the latch is not the exiting block cannot be"
1489 " interchange currently.";
1495 if (!isLoopStructureUnderstood()) {
1498 return OptimizationRemarkMissed(
DEBUG_TYPE,
"UnsupportedStructureInner",
1501 <<
"Inner loop structure not understood currently.";
1508 for (
Loop *L : {OuterLoop, InnerLoop}) {
1511 if (
L->contains(Pred))
1515 dbgs() <<
"Indirect branch found in the loop predecessor.\n");
1517 return OptimizationRemarkMissed(
DEBUG_TYPE,
"IndirectBranchPreheader",
1518 L->getStartLoc(),
L->getHeader())
1519 <<
"Indirect branch found in the loop predecessor.";
1528 SmallPtrSet<BasicBlock *, 2> InnerLoopHeaderSuccs;
1530 if (!InnerLoopHeaderSuccs.
insert(Succ).second)
1553 if (
PHI.getNumIncomingValues() > 1)
1557 if (&
PHI == LcssaReduction)
1560 PHINode *PN = dyn_cast<PHINode>(U);
1563 if (Reductions.count(PN))
1565 BasicBlock *PB = PN->getParent();
1566 if (!OuterL->contains(PB))
1568 return PB != OuterL->getLoopLatch();
1585 for (
Value *Incoming :
PHI.incoming_values()) {
1626 for (
PHINode *InductionPHI : InductionPHIs) {
1628 InductionPHI->getIncomingValueForBlock(InnerLoopLatch)))
1630 Worklist.
insert(IncomingI);
1636 InductionPHIs.
end());
1637 for (
unsigned I = 0;
I < Worklist.
size(); ++
I) {
1649bool LoopInterchangeLegality::canInterchangeLoops(
unsigned InnerLoopId,
1650 unsigned OuterLoopId,
1651 CharMatrix &DepMatrix) {
1653 LLVM_DEBUG(
dbgs() <<
"Failed interchange InnerLoopId = " << InnerLoopId
1654 <<
" and OuterLoopId = " << OuterLoopId
1655 <<
" due to dependence\n");
1657 return OptimizationRemarkMissed(
DEBUG_TYPE,
"Dependence",
1660 <<
"Cannot interchange loops due to dependences.";
1665 for (
auto *BB : OuterLoop->
blocks())
1666 for (Instruction &
I : *BB) {
1673 if (!
I.mayHaveSideEffects() && !
I.mayReadFromMemory())
1678 <<
"Loops contain instructions that cannot be safely interchanged\n");
1680 return OptimizationRemarkMissed(
DEBUG_TYPE,
"UnsafeInst",
1681 I.getDebugLoc(),
I.getParent())
1682 <<
"Cannot interchange loops due to instruction that is "
1683 "potentially unsafe to interchange.";
1689 if (!checkInductionsAndReductions(OuterLoop)) {
1690 LLVM_DEBUG(
dbgs() <<
"Failed to find inner loop inductions or found "
1691 "unsupported reductions.\n");
1696 LLVM_DEBUG(
dbgs() <<
"Found unsupported PHI nodes in inner loop latch.\n");
1698 return OptimizationRemarkMissed(
DEBUG_TYPE,
"UnsupportedInnerLatchPHI",
1701 <<
"Cannot interchange loops because unsupported PHI nodes found "
1702 "in inner loop latch.";
1711 LLVM_DEBUG(
dbgs() <<
"Interchange would re-nest or duplicate freeze\n");
1713 return OptimizationRemarkMissed(
DEBUG_TYPE,
"UnsafeInst",
1716 <<
"Cannot interchange loops because re-nesting or duplicating "
1717 "freeze may change its sampling behavior.";
1724 if (currentLimitations()) {
1725 LLVM_DEBUG(
dbgs() <<
"Not legal because of current transform limitation\n");
1730 if (!tightlyNested(OuterLoop, InnerLoop)) {
1733 return OptimizationRemarkMissed(
DEBUG_TYPE,
"NotTightlyNested",
1736 <<
"Cannot interchange loops because they are not tightly "
1744 PHINode *LcssaReduction =
nullptr;
1745 assert(InnerReductions.size() <= 1 &&
1746 "So far we only support at most one reduction.");
1747 if (InnerReductions.size() == 1)
1748 LcssaReduction = InnerReductions[0].LcssaPhi;
1752 LLVM_DEBUG(
dbgs() <<
"Found unsupported PHI nodes in inner loop exit.\n");
1754 return OptimizationRemarkMissed(
DEBUG_TYPE,
"UnsupportedExitPHI",
1757 <<
"Found unsupported PHI node in loop exit.";
1763 LLVM_DEBUG(
dbgs() <<
"Found unsupported PHI nodes in outer loop exit.\n");
1765 return OptimizationRemarkMissed(
DEBUG_TYPE,
"UnsupportedExitPHI",
1768 <<
"Found unsupported PHI node in loop exit.";
1774 [](PHINode &
PHI) { return PHI.getNumIncomingValues() != 1; })) {
1775 LLVM_DEBUG(
dbgs() <<
"Only outer loop latch PHI nodes with one incoming "
1776 "value are supported.\n");
1778 return OptimizationRemarkMissed(
DEBUG_TYPE,
"UnsupportedLatchPHI",
1781 <<
"Only outer loop latch PHI nodes with one incoming value are "
1795 if (
any_of(
PHI.users(), [](
const User *U) { return !isa<PHINode>(U); })) {
1796 LLVM_DEBUG(
dbgs() <<
"Outer loop latch PHI has a non-PHI user.\n");
1798 return OptimizationRemarkMissed(
DEBUG_TYPE,
"UnsupportedLatchPHI",
1801 <<
"Cannot interchange loops because an outer loop latch PHI "
1802 "node has a non-PHI user.";
1810void CacheCostManager::computeIfUnitinialized() {
1825 for (
const auto &[Idx,
Cost] :
enumerate((*CC)->getLoopCosts()))
1826 CostMap[
Cost.first] = Idx;
1829CacheCost *CacheCostManager::getCacheCost() {
1830 computeIfUnitinialized();
1834const DenseMap<const Loop *, unsigned> &CacheCostManager::getCostMap() {
1835 computeIfUnitinialized();
1845static std::optional<const SCEV *>
1851 return std::nullopt;
1856 return std::nullopt;
1859 std::optional<const SCEV *> Coeff =
1861 if (!Coeff.has_value())
1862 return std::nullopt;
1865 assert(!*Coeff &&
"Found more than one addrec for the same loop");
1871int LoopInterchangeProfitability::getInstrOrderCost() {
1872 SmallPtrSet<const SCEV *, 4> GoodBasePtrs, BadBasePtrs;
1873 for (BasicBlock *BB : InnerLoop->
blocks()) {
1874 for (Instruction &Ins : *BB) {
1879 std::optional<const SCEV *> OuterCoeff =
1881 std::optional<const SCEV *> InnerCoeff =
1884 if (!OuterCoeff.has_value() || !*OuterCoeff || !InnerCoeff.has_value() ||
1894 const SCEV *OuterStep = SE->
getAbsExpr(*OuterCoeff,
false);
1895 const SCEV *InnerStep = SE->
getAbsExpr(*InnerCoeff,
false);
1915 GoodBasePtrs.
insert(BasePtr);
1917 BadBasePtrs.
insert(BasePtr);
1921 int GoodOrder = GoodBasePtrs.
size();
1922 int BadOrder = BadBasePtrs.
size();
1923 return GoodOrder - BadOrder;
1927LoopInterchangeProfitability::isProfitablePerLoopCacheAnalysis(
1928 const DenseMap<const Loop *, unsigned> &CostMap, CacheCost *CC) {
1932 auto InnerLoopIt = CostMap.
find(InnerLoop);
1933 if (InnerLoopIt == CostMap.
end())
1934 return std::nullopt;
1935 auto OuterLoopIt = CostMap.
find(OuterLoop);
1936 if (OuterLoopIt == CostMap.
end())
1937 return std::nullopt;
1940 return std::nullopt;
1941 unsigned InnerIndex = InnerLoopIt->second;
1942 unsigned OuterIndex = OuterLoopIt->second;
1944 <<
", OuterIndex = " << OuterIndex <<
"\n");
1945 assert(InnerIndex != OuterIndex &&
"CostMap should assign unique "
1946 "numbers to each loop");
1947 return std::optional<bool>(InnerIndex < OuterIndex);
1951LoopInterchangeProfitability::isProfitablePerInstrOrderCost() {
1955 int Cost = getInstrOrderCost();
1958 return std::optional<bool>(
true);
1960 return std::nullopt;
1965 for (
const auto &Dep : DepMatrix) {
1966 char Dir = Dep[LoopId];
1967 char DepType = Dep.back();
1968 assert((DepType ==
'<' || DepType ==
'*') &&
1969 "Unexpected element in dependency vector");
1972 if (Dir ==
'=' || Dir ==
'I')
1978 if (Dir ==
'<' && DepType ==
'<')
1987std::optional<bool> LoopInterchangeProfitability::isProfitableForVectorization(
1988 unsigned InnerLoopId,
unsigned OuterLoopId, CharMatrix &DepMatrix) {
2004 return std::nullopt;
2007bool LoopInterchangeProfitability::isProfitable(
2008 const Loop *InnerLoop,
const Loop *OuterLoop,
unsigned InnerLoopId,
2009 unsigned OuterLoopId, CharMatrix &DepMatrix, CacheCostManager &CCM) {
2018 if (InnerBTC && InnerBTC->
isZero()) {
2019 LLVM_DEBUG(
dbgs() <<
"Inner loop back-edge isn't taken, rejecting "
2020 "single iteration loop\n");
2023 if (OuterBTC && OuterBTC->
isZero()) {
2024 LLVM_DEBUG(
dbgs() <<
"Outer loop back-edge isn't taken, rejecting "
2025 "single iteration loop\n");
2033 "Duplicate rules and option 'ignore' are not allowed");
2043 std::optional<bool> shouldInterchange;
2046 case RuleTy::PerLoopCacheAnalysis: {
2047 CacheCost *CC = CCM.getCacheCost();
2048 const DenseMap<const Loop *, unsigned> &CostMap = CCM.getCostMap();
2049 shouldInterchange = isProfitablePerLoopCacheAnalysis(CostMap, CC);
2052 case RuleTy::PerInstrOrderCost:
2053 shouldInterchange = isProfitablePerInstrOrderCost();
2055 case RuleTy::ForVectorization:
2057 isProfitableForVectorization(InnerLoopId, OuterLoopId, DepMatrix);
2059 case RuleTy::Ignore:
2066 if (shouldInterchange.has_value())
2070 if (!shouldInterchange.has_value()) {
2072 return OptimizationRemarkMissed(
DEBUG_TYPE,
"InterchangeNotProfitable",
2075 <<
"Insufficient information to calculate the cost of loop for "
2079 }
else if (!shouldInterchange.value()) {
2081 return OptimizationRemarkMissed(
DEBUG_TYPE,
"InterchangeNotProfitable",
2084 <<
"Interchanging loops is not considered to improve cache "
2085 "locality nor vectorization.";
2092void LoopInterchangeTransform::removeChildLoop(
Loop *OuterLoop,
2094 for (
Loop *L : *OuterLoop)
2095 if (L == InnerLoop) {
2096 OuterLoop->removeChildLoop(L);
2125void LoopInterchangeTransform::restructureLoops(
2126 Loop *NewInner,
Loop *NewOuter, BasicBlock *OrigInnerPreHeader,
2127 BasicBlock *OrigOuterPreHeader) {
2128 Loop *OuterLoopParent = OuterLoop->getParentLoop();
2135 removeChildLoop(NewInner, NewOuter);
2144 SmallVector<BasicBlock *, 8> OrigInnerBBs(NewOuter->
blocks());
2148 for (BasicBlock *BB : NewInner->
blocks())
2156 for (BasicBlock *BB : OrigInnerBBs) {
2161 if (BB == OuterHeader || BB == OuterLatch)
2199void LoopInterchangeTransform::reduction2Memory() {
2201 LIL.getInnerReductions();
2204 "So far we only support at most one reduction.");
2206 LoopInterchangeLegality::InnerReduction SR = InnerReductions[0];
2212 PHINode *FirstIter =
2213 Builder.CreatePHI(Type::getInt1Ty(
Context), 2,
"first.iter");
2218 assert(FirstIter->
isComplete() &&
"The FirstIter PHI node is not complete.");
2223 Instruction *LoadMem = Builder.CreateLoad(SR.ElemTy, SR.MemRef);
2226 Value *NewVar = Builder.CreateSelect(FirstIter, SR.Init, LoadMem,
"new.var");
2237void LoopInterchangeTransform::transform(
2238 ArrayRef<Instruction *> DropNoWrapInsts,
2239 ArrayRef<Instruction *> DropNoInfInsts) {
2242 LIL.getInnerReductions();
2243 if (InnerReductions.
size() == 1)
2247 auto &InductionPHIs = LIL.getInnerLoopInductions();
2248 assert(!InductionPHIs.empty() &&
2249 "Expected at least one induction variable in the inner loop");
2251 SmallVector<Instruction *, 8> InnerIndexVarList;
2252 for (PHINode *CurInductionPHI : InductionPHIs) {
2254 CurInductionPHI->getIncomingValueForBlock(InnerLoop->
getLoopLatch()));
2256 "Incoming value from loop latch isn't an instruction");
2259 InnerIndexVarList.
push_back(IncomingValue);
2272 SmallSetVector<Instruction *, 4> WorkList;
2274 auto MoveInstructions = [&i, &WorkList,
this, &InductionPHIs, NewLatch]() {
2275 for (; i < WorkList.
size(); i++) {
2279 "MoveInstructions does not support PHI nodes");
2285 "Moving instructions with side-effects may change behavior of "
2296 for (
Value *
Op : WorkList[i]->operands()) {
2313 for (Instruction *InnerIndexVar : InnerIndexVarList)
2328 BasicBlock *OuterLoopHeader = OuterLoop->getHeader();
2330 if (InnerLoopPreHeader != OuterLoopHeader) {
2334 "Expected equivalent incoming values in inner loop preheader");
2335 P.replaceAllUsesWith(
P.getIncomingValue(0));
2336 P.eraseFromParent();
2338 for (Instruction &
I :
2340 std::prev(InnerLoopPreHeader->
end()))))
2344 adjustLoopBranches();
2348 for (Instruction *
Reduction : DropNoWrapInsts) {
2352 for (Instruction *
I : DropNoInfInsts)
2353 I->setHasNoInfs(
false);
2372 I->removeFromParent();
2387 std::vector<DominatorTree::UpdateType> &DTUpdates,
2388 bool MustUpdateOnce =
true) {
2390 "BI must jump to OldBB exactly once.");
2392 for (
Use &
Op : Term->operands())
2399 DTUpdates.push_back(
2400 {DominatorTree::UpdateKind::Insert, Term->getParent(), NewBB});
2401 DTUpdates.push_back(
2402 {DominatorTree::UpdateKind::Delete, Term->getParent(), OldBB});
2421 assert(
P.getNumIncomingValues() == 1 &&
2422 "Only loops with a single exit are supported!");
2424 Value *IncomingValue =
P.getIncomingValueForBlock(InnerLatch);
2431 "Expected non-instruction incoming value to be loop invariant");
2432 P.replaceAllUsesWith(IncomingValue);
2433 P.eraseFromParent();
2444 if (!IncIInnerMost || (IncIInnerMost->getParent() != InnerLatch &&
2445 IncIInnerMost->
getParent() != InnerHeader))
2449 [OuterHeader, OuterExit, IncI, InnerHeader](
User *U) {
2450 return (cast<PHINode>(U)->getParent() == OuterHeader &&
2451 IncI->getParent() == InnerHeader) ||
2452 cast<PHINode>(U)->getParent() == OuterExit;
2454 "Can only replace phis iff the uses are in the loop nest exit or "
2455 "the incoming value is defined in the inner header (it will "
2456 "dominate all loop blocks after interchanging)");
2457 P.replaceAllUsesWith(IncI);
2458 P.eraseFromParent();
2486 if (
P.getNumIncomingValues() != 1)
2500 if (Pred == OuterLatch)
2505 P.setIncomingValue(0, NewPhi);
2545 if (OuterLoopLatch == InnerLoopExit)
2552 assert(Phi->getNumIncomingValues() == 1 &&
"Single input phi expected");
2553 LLVM_DEBUG(
dbgs() <<
"Removing 1-input phi in non-exit block: " << *Phi
2555 Phi->replaceAllUsesWith(Phi->getIncomingValue(0));
2556 Phi->eraseFromParent();
2560void LoopInterchangeTransform::adjustLoopBranches() {
2562 std::vector<DominatorTree::UpdateType> DTUpdates;
2564 BasicBlock *OuterLoopPreHeader = OuterLoop->getLoopPreheader();
2567 assert(OuterLoopPreHeader != OuterLoop->getHeader() &&
2568 InnerLoopPreHeader != InnerLoop->
getHeader() && OuterLoopPreHeader &&
2569 InnerLoopPreHeader &&
"Guaranteed by loop-simplify form");
2579 OuterLoopPreHeader =
2581 if (InnerLoopPreHeader == OuterLoop->getHeader())
2582 InnerLoopPreHeader =
2587 BasicBlock *OuterLoopHeader = OuterLoop->getHeader();
2589 BasicBlock *OuterLoopLatch = OuterLoop->getLoopLatch();
2596 CondBrInst *OuterLoopLatchBI =
2598 CondBrInst *InnerLoopLatchBI =
2603 assert(OuterLoopPredecessor && InnerLoopLatchPredecessor &&
2604 "Failed to find a unique predecessor");
2605 assert(OuterLoopLatchBI && InnerLoopLatchBI &&
2606 "Failed to find a conditional branch");
2613 assert(InnerLoopHeaderSuccessor &&
2614 "Failed to find a unique successor for the inner loop header");
2621 InnerLoopPreHeader, DTUpdates,
false);
2631 InnerLoopHeaderSuccessor, DTUpdates,
2639 OuterLoopPreHeader, DTUpdates);
2642 if (InnerLoopLatchBI->
getSuccessor(0) == InnerLoopHeader)
2643 InnerLoopLatchSuccessor = InnerLoopLatchBI->
getSuccessor(1);
2645 InnerLoopLatchSuccessor = InnerLoopLatchBI->
getSuccessor(0);
2648 InnerLoopLatchSuccessor, DTUpdates);
2650 if (OuterLoopLatchBI->
getSuccessor(0) == OuterLoopHeader)
2651 OuterLoopLatchSuccessor = OuterLoopLatchBI->
getSuccessor(1);
2653 OuterLoopLatchSuccessor = OuterLoopLatchBI->
getSuccessor(0);
2656 OuterLoopLatchSuccessor, DTUpdates);
2657 updateSuccessor(OuterLoopLatchBI, OuterLoopLatchSuccessor, InnerLoopLatch,
2661 restructureLoops(OuterLoop, InnerLoop, InnerLoopPreHeader,
2662 OuterLoopPreHeader);
2664 moveLCSSAPhis(InnerLoopLatchSuccessor, InnerLoopHeader, InnerLoopLatch,
2665 OuterLoopHeader, OuterLoopLatch, InnerLoop->
getExitBlock(),
2671 auto &OuterInnerReductions = LIL.getOuterInnerReductions();
2674 for (PHINode &
PHI : InnerLoopHeader->
phis())
2675 if (OuterInnerReductions.contains(&
PHI))
2678 for (PHINode &
PHI : OuterLoopHeader->
phis())
2679 if (OuterInnerReductions.contains(&
PHI))
2685 for (PHINode *
PHI : OuterLoopPHIs) {
2688 assert(OuterInnerReductions.count(
PHI) &&
"Expected a reduction PHI node");
2690 for (PHINode *
PHI : InnerLoopPHIs) {
2693 assert(OuterInnerReductions.count(
PHI) &&
"Expected a reduction PHI node");
2712 SmallVector<Instruction *, 4> MayNeedLCSSAPhis;
2713 for (Instruction &
I :
2719 "LoopInterchange handed dominance-broken IR to LCSSA rebuild");
2737 <<
"Computed dependence info, invoking the transform.";
2741 if (!LoopInterchange(&AR.
SE, &AR.
LI, &DI, &AR.
DT, &AR, &ORE).run(LN))
2743 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.
LoopT * getParentLoop() const
Return the parent loop if it exists or nullptr for top level loops.
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 replaceLoop(LoopT *Old, LoopT *New)
Replace a loop among its siblings (a parent loop's child list or the top-level list) with a new 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...
typename SuperClass::iterator iterator
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)
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the 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...