80#define DEBUG_TYPE "loop-unroll"
83STATISTIC(NumCompletelyUnrolled,
"Number of loops completely unrolled");
84STATISTIC(NumUnrolled,
"Number of loops unrolled (completely or otherwise)");
85STATISTIC(NumUnrolledNotLatch,
"Number of loops unrolled without a conditional "
86 "latch (completely or otherwise)");
90 cl::desc(
"Allow runtime unrolled loops to be unrolled "
91 "with epilog instead of prolog."));
95 cl::desc(
"If new branch weights must be found, work harder to keep them "
100 cl::desc(
"Verify domtree after unrolling"),
101#ifdef EXPENSIVE_CHECKS
110 cl::desc(
"Verify loopinfo after unrolling"),
111#ifdef EXPENSIVE_CHECKS
120 cl::desc(
"Allow unrolling to add parallel reduction phis."));
132 const std::vector<BasicBlock *> &Blocks,
138 for (
Use &U :
I.operands()) {
161 assert(OldLoop &&
"Should (at least) be in the loop being unrolled!");
163 Loop *&NewLoop = NewLoops[OldLoop];
167 "Header should be first in RPO");
211 BasicBlock *PreHeader = L->getLoopPreheader();
213 assert(PreHeader && Header);
214 for (
const PHINode &PN : Header->phis()) {
231 unsigned CurrentGeneration;
232 unsigned ChildGeneration;
234 DomTreeNode::const_iterator ChildIter;
235 DomTreeNode::const_iterator EndIter;
236 bool Processed =
false;
240 unsigned cg,
DomTreeNode *
N, DomTreeNode::const_iterator Child,
241 DomTreeNode::const_iterator
End)
242 : LoadScope(AvailableLoads), CurrentGeneration(cg), ChildGeneration(cg),
243 Node(
N), ChildIter(Child), EndIter(
End) {}
249 DomTreeNode::const_iterator
childIter()
const {
return ChildIter; }
257 DomTreeNode::const_iterator
end()
const {
return EndIter; }
276 if (!MSSA->
dominates(LaterDef, EarlierMA))
290 unsigned CurrentGeneration = 0;
291 while (!NodesToProcess.
empty()) {
312 if (
I.mayWriteToMemory())
324 Load->replaceAllUsesWith(M);
325 Load->eraseFromParent();
333 }
else if (NodeToProcess->
childIter() != NodeToProcess->
end()) {
336 if (!L->contains(Child->
getBlock()))
361 if (SE && SimplifyIVs) {
367 while (!DeadInsts.
empty()) {
374 std::unique_ptr<MemorySSA> MSSA =
nullptr;
389 if (BB->getParent()->getSubprogram())
394 &Inst, {BB->getDataLayout(),
nullptr, DT, AC}))
396 Inst.replaceAllUsesWith(V);
406 const APInt *C1, *C2;
412 Inst.setOperand(0,
X);
413 Inst.setOperand(1, ConstantInt::get(Inst.getType(), NewC));
414 Inst.setHasNoUnsignedWrap(Inst.hasNoUnsignedWrap() &&
415 InnerOBO->hasNoUnsignedWrap());
416 Inst.setHasNoSignedWrap(Inst.hasNoSignedWrap() &&
417 InnerOBO->hasNoSignedWrap() &&
491 bool CompletelyUnroll,
492 std::vector<unsigned> &IterCounts,
493 const std::vector<BasicBlock *> &CondLatches,
494 std::vector<BasicBlock *> &CondLatchNexts) {
536 if (CondLatches.empty())
544 "Expected to have loop probability to fix");
545 if (OriginalLoopProb.
isOne())
549 double FreqDesired = 1 / (1 - OriginalLoopProb.
toDouble());
552 auto GetProb = [&](
unsigned I) {
554 bool FirstTargetIsNext =
B->getSuccessor(0) == CondLatchNexts[
I];
559 auto SetProb = [&](
unsigned I,
double Prob) {
561 bool FirstTargetIsNext =
B->getSuccessor(0) == CondLatchNexts[
I];
567 auto SetAllProbs = [&](
double Prob) {
568 for (
unsigned I = 0,
E = CondLatches.size();
I <
E; ++
I)
620 const double FreqPrec = 1e-6;
623 auto ComputeFreq = [&](
double Prob) {
624 double ProbReaching = 1;
625 double FreqOne = IterCounts[0];
626 for (
unsigned I = 0,
E = CondLatches.size();
I <
E; ++
I) {
627 ProbReaching *= Prob;
628 FreqOne += IterCounts[
I + 1] * ProbReaching;
630 double ProbReachingBackedge = CompletelyUnroll ? 0 : ProbReaching;
631 assert(FreqOne > 0 &&
"Expected at least one iteration before first latch");
632 if (ProbReachingBackedge == 1)
633 return std::numeric_limits<double>::infinity();
634 return FreqOne / (1 - ProbReachingBackedge);
639 auto ComputeProbForLinear = [&]() {
641 double A = IterCounts[1] + (CompletelyUnroll ? 0 : FreqDesired);
642 double B = IterCounts[0] - FreqDesired;
643 assert(
A > 0 &&
"Expected iterations after last conditional latch");
644 double Prob = -
B /
A;
647 assert((Prob < 0 || Prob > 1 ||
648 fabs(ComputeFreq(Prob) - FreqDesired) / FreqDesired < FreqPrec) &&
649 "Expected accurate frequency when linear case is possible");
650 Prob = std::max(Prob, 0.);
651 Prob = std::min(Prob, 1.);
657 auto ComputeProbForQuadratic = [&]() {
659 double A = IterCounts[2] + (CompletelyUnroll ? 0 : FreqDesired);
660 double B = IterCounts[1];
661 double C = IterCounts[0] - FreqDesired;
662 assert(
A > 0 &&
"Expected iterations after last conditional latch");
663 double Prob = (-
B + sqrt(
B *
B - 4 *
A *
C)) / (2 *
A);
666 assert((Prob < 0 || Prob > 1 ||
667 fabs(ComputeFreq(Prob) - FreqDesired) / FreqDesired < FreqPrec) &&
668 "Expected accurate frequency when quadratic case is possible");
669 Prob = std::max(Prob, 0.);
670 Prob = std::min(Prob, 1.);
689 auto AdjustProb = [&](
unsigned ComputeIdx,
double &ProbBefore,
690 double &ProbAfter,
double &FreqBefore,
692 assert(ComputeIdx < CondLatches.size() &&
693 "Expected valid CondLatches index");
696 auto ComputeAfter = [&]() {
698 FreqAfter = IterCounts[ComputeIdx + 1];
699 for (
unsigned I = ComputeIdx + 1,
E = CondLatches.size();
I <
E; ++
I) {
700 double Prob = GetProb(
I);
705 FreqAfter += IterCounts[
I + 1] * ProbAfter;
708 if (ComputeIdx == 0) {
710 FreqBefore = IterCounts[0];
715 double ProbOld = GetProb(ComputeIdx);
717 FreqAfter -= IterCounts[ComputeIdx] * ProbBefore;
718 ProbAfter /= ProbOld;
719 FreqAfter /= ProbOld;
726 ProbBefore *= GetProb(ComputeIdx - 1);
727 FreqBefore += IterCounts[ComputeIdx] * ProbBefore;
733 double ProbReachingBackedge = CompletelyUnroll ? 0 : ProbBefore * ProbAfter;
734 double ProbComputeNumerator = FreqDesired - FreqBefore;
735 double ProbComputeDenominator =
736 FreqAfter + FreqDesired * ProbReachingBackedge;
737 double ProbCompute = -1;
738 if (ProbComputeNumerator <= 0) {
745 }
else if (ProbComputeDenominator == 0) {
769 ProbCompute = ProbComputeNumerator / ProbComputeDenominator;
770 ProbCompute = std::max(ProbCompute, 0.);
771 ProbCompute = std::min(ProbCompute, 1.);
773 SetProb(ComputeIdx, ProbCompute);
776 double FreqCompute = -1;
777 if (ProbReachingBackedge * ProbCompute == 1) {
788 FreqCompute = std::numeric_limits<double>::infinity();
792 L->getStartLoc(), L->getHeader());
797 "Expected at least one iteration before first latch");
800 FreqCompute = (FreqBefore + FreqAfter * ProbCompute) /
801 (1 - ProbReachingBackedge * ProbCompute);
803 assert(FreqCompute > 0 &&
"Expected valid frequency");
813 if (CondLatches.size() == 1) {
814 SetAllProbs(ComputeProbForLinear());
815 }
else if (CondLatches.size() == 2) {
816 SetAllProbs(ComputeProbForQuadratic());
825 double ProbBefore = -1, ProbAfter = -1;
826 double FreqBefore = -1, FreqAfter = -1;
827 for (
unsigned I = 0;
I != CondLatches.size(); ++
I) {
828 double Freq = AdjustProb(
I, ProbBefore, ProbAfter, FreqBefore, FreqAfter);
829 if (fabs(Freq - FreqDesired) / FreqDesired < FreqPrec)
835 double ProbMin = -1, ProbMax = -1;
836 double ProbPrev = -1;
837 auto TryProb = [&](
double Prob) {
839 double FreqDelta = ComputeFreq(Prob) - FreqDesired;
840 if (fabs(FreqDelta) / FreqDesired < FreqPrec)
855 if (TryProb(0.) < 0 && TryProb(1.) > 0) {
856 assert(ProbMin == 0 && ProbMax == 1 &&
857 "expected probability bounds to be initialized");
858 const double ProbPrec = 1e-12;
859 double Prob, ProbDelta;
861 Prob = (ProbMin + ProbMax) / 2;
862 ProbDelta = Prob - ProbPrev;
863 }
while (TryProb(Prob) != 0 && fabs(ProbDelta) > ProbPrec);
865 SetAllProbs(ProbPrev);
915 assert(DT &&
"DomTree is required");
917 if (!L->getLoopPreheader()) {
918 LLVM_DEBUG(
dbgs() <<
" Can't unroll; loop preheader-insertion failed.\n");
922 if (!L->getLoopLatch()) {
923 LLVM_DEBUG(
dbgs() <<
" Can't unroll; loop exit-block-insertion failed.\n");
928 if (!L->isSafeToClone()) {
929 LLVM_DEBUG(
dbgs() <<
" Can't unroll; Loop body cannot be cloned.\n");
933 if (L->getHeader()->hasAddressTaken()) {
936 dbgs() <<
" Won't unroll loop: address of header block is taken.\n");
944 BasicBlock *Preheader = L->getLoopPreheader();
948 L->getExitBlocks(ExitBlocks);
952 std::optional<unsigned> OriginalTripCount =
958 if (MaxTripCount && ULO.
Count > MaxTripCount)
959 ULO.
Count = MaxTripCount;
963 unsigned TripMultiple;
964 unsigned BreakoutTrip;
971 L->getExitingBlocks(ExitingBlocks);
972 for (
auto *ExitingBlock : ExitingBlocks) {
979 ExitInfo &Info = ExitInfos[ExitingBlock];
982 if (Info.TripCount != 0) {
983 Info.BreakoutTrip = Info.TripCount % ULO.
Count;
984 Info.TripMultiple = 0;
986 Info.BreakoutTrip = Info.TripMultiple =
989 Info.ExitOnTrue = !L->contains(BI->getSuccessor(0));
990 Info.ExitingBlocks.push_back(ExitingBlock);
991 LLVM_DEBUG(
dbgs() <<
" Exiting block %" << ExitingBlock->getName()
992 <<
": TripCount=" << Info.TripCount
993 <<
", TripMultiple=" << Info.TripMultiple
994 <<
", BreakoutTrip=" << Info.BreakoutTrip <<
"\n");
1000 const bool CompletelyUnroll = ULO.
Count == MaxTripCount;
1002 const bool PreserveOnlyFirst = CompletelyUnroll && MaxOrZero;
1006 if (CompletelyUnroll)
1015 bool NeedToFixLCSSA =
1016 PreserveLCSSA && CompletelyUnroll &&
1030 bool LatchIsExiting = L->isLoopExiting(LatchBlock);
1034 dbgs() <<
"Can't unroll; a conditional latch must exit the loop");
1038 bool EpilogProfitability =
1047 RemainderLoop, OriginalTripCount, OriginalLoopProb)) {
1051 LLVM_DEBUG(
dbgs() <<
"Won't unroll; remainder loop could not be "
1052 "generated when assuming runtime trip count\n");
1057 using namespace ore;
1064 if (CompletelyUnroll) {
1065 LLVM_DEBUG(
dbgs() <<
"COMPLETELY UNROLLING loop %" << Header->getName()
1066 <<
" with trip count " << ULO.
Count <<
"!\n");
1071 <<
"completely unrolled " + LoopKind.
str() +
"loop with "
1072 << NV(
"UnrollCount", ULO.
Count) <<
" iterations";
1076 dbgs() <<
"UNROLLING loop %" << Header->getName() <<
" by " << ULO.
Count;
1078 dbgs() <<
" with run-time trip count";
1080 dbgs() <<
" (remainder unrolled)";
1089 Diag <<
"unrolled " + LoopKind.
str() +
"loop by a factor of "
1090 << NV(
"UnrollCount", ULO.
Count);
1092 Diag <<
" with run-time trip count"
1115 if (!LatchIsExiting)
1116 ++NumUnrolledNotLatch;
1121 std::vector<PHINode*> OrigPHINode;
1132 bool CanAddAdditionalAccumulators =
1136 !CompletelyUnroll && L->getNumBlocks() == 1 &&
1138 (ExitInfos.
contains(Header) && ((ExitInfos[Header].TripCount != 0 &&
1139 ExitInfos[Header].BreakoutTrip == 0))));
1146 if (CanAddAdditionalAccumulators && ULO.
Count <= 4) {
1147 for (
PHINode &Phi : Header->phis()) {
1161 std::vector<BasicBlock *> Headers;
1162 std::vector<BasicBlock *> Latches;
1163 Headers.push_back(Header);
1164 Latches.push_back(LatchBlock);
1176 std::vector<BasicBlock*> UnrolledLoopBlocks = L->getBlocks();
1180 const std::vector<BasicBlock *> PostRemainderLoopBlocks = L->getBlocks();
1191 if (Header->getParent()->shouldEmitDebugInfoForProfiling() &&
1197 auto NewDIL = DIL->cloneByMultiplyingDuplicationFactor(ULO.
Count);
1199 I.setDebugLoc(*NewDIL);
1202 <<
"Failed to create new discriminator: "
1203 << DIL->getFilename() <<
" Line: " << DIL->getLine());
1214 auto BlockInsertPt = std::next(LatchBlock->
getIterator());
1216 for (
unsigned It = 1; It != ULO.
Count; ++It) {
1224 Header->getParent()->insert(BlockInsertPt, New);
1227 "Header should not be in a sub-loop");
1231 LoopsToSimplify.
insert(NewLoops[OldLoop]);
1233 if (*BB == Header) {
1236 for (
PHINode *OrigPHI : OrigPHINode) {
1244 if (PartialReductions.
empty())
1252 L->getLoopPreheader(),
1265 if (It > 1 && L->contains(InValI))
1266 InVal = LastValueMap[InValI];
1267 VMap[OrigPHI] = InVal;
1290 LastValueMap[*BB] = New;
1293 LastValueMap[VI->first] = VI->second;
1297 if (L->contains(Succ))
1300 Value *Incoming =
PHI.getIncomingValueForBlock(*BB);
1302 if (It != LastValueMap.
end())
1304 PHI.addIncoming(Incoming, New);
1311 Headers.push_back(New);
1312 if (*BB == LatchBlock)
1313 Latches.push_back(New);
1317 auto ExitInfoIt = ExitInfos.
find(*BB);
1318 if (ExitInfoIt != ExitInfos.
end())
1319 ExitInfoIt->second.ExitingBlocks.push_back(New);
1322 UnrolledLoopBlocks.push_back(New);
1331 auto BBDomNode = DT->
getNode(*BB);
1332 auto BBIDom = BBDomNode->
getIDom();
1333 BasicBlock *OriginalBBIDom = BBIDom->getBlock();
1351 std::string ext = (
Twine(
"It") +
Twine(It)).str();
1353 Header->getContext(), ext);
1358 for (
PHINode *PN : OrigPHINode) {
1359 if (CompletelyUnroll) {
1364 PN->replaceAllUsesWith(PN->getIncomingValueForBlock(Preheader));
1365 PN->eraseFromParent();
1366 }
else if (ULO.
Count > 1) {
1370 Value *InVal = PN->removeIncomingValue(LatchBlock,
false);
1374 if (L->contains(InValI))
1375 InVal = LastValueMap[InVal];
1377 assert(Latches.back() == LastValueMap[LatchBlock] &&
"bad last latch");
1378 PN->addIncoming(InVal, Latches.back());
1384 for (
unsigned i = 0, e = Latches.size(); i != e; ++i) {
1385 unsigned j = (i + 1) % e;
1386 Latches[i]->getTerminator()->replaceSuccessorWith(Headers[i], Headers[j]);
1391 for (
unsigned I = 0, E = Latches.size() - (CompletelyUnroll ? 0 : 1);
I < E;
1393 Latches[
I]->getTerminator()->setMetadata(LLVMContext::MD_loop,
nullptr);
1399 if (ULO.
Count > 1) {
1400 for (
auto *BB : PostRemainderLoopBlocks) {
1401 auto *BBDomNode = DT->
getNode(BB);
1403 for (
auto *ChildDomNode : BBDomNode->children()) {
1404 auto *ChildBB = ChildDomNode->getBlock();
1405 if (!L->contains(ChildBB))
1413 for (
auto *ChildBB : ChildrenToUpdate)
1419 DT->
verify(DominatorTree::VerificationLevel::Fast));
1422 auto SetDest = [&](
BasicBlock *Src,
bool WillExit,
bool ExitOnTrue) {
1424 const unsigned Idx = ExitOnTrue ^ WillExit;
1426 BasicBlock *DeadSucc = Term->getSuccessor(1-Idx);
1433 BI->setDebugLoc(Term->getDebugLoc());
1434 Term->eraseFromParent();
1439 auto WillExit = [&](
const ExitInfo &Info,
unsigned i,
unsigned j,
1440 bool IsLatch) -> std::optional<bool> {
1441 if (CompletelyUnroll) {
1442 if (PreserveOnlyFirst) {
1444 return std::nullopt;
1450 if (Info.TripCount && j != Info.TripCount)
1452 return std::nullopt;
1458 if (IsLatch && j != 0)
1460 return std::nullopt;
1463 if (j != Info.BreakoutTrip &&
1464 (Info.TripMultiple == 0 || j % Info.TripMultiple != 0)) {
1469 return std::nullopt;
1475 bool ProbUpdateRequired =
false;
1476 for (
auto &Pair : ExitInfos) {
1477 ExitInfo &Info = Pair.second;
1478 for (
unsigned i = 0, e = Info.ExitingBlocks.size(); i != e; ++i) {
1480 unsigned j = (i + 1) % e;
1481 bool IsLatch = Pair.first == LatchBlock;
1482 std::optional<bool> KnownWillExit = WillExit(Info, i, j, IsLatch);
1483 if (!KnownWillExit) {
1484 if (!Info.FirstExitingBlock)
1485 Info.FirstExitingBlock = Info.ExitingBlocks[i];
1494 if (*KnownWillExit && !IsLatch) {
1495 if (!Info.FirstExitingBlock)
1496 Info.FirstExitingBlock = Info.ExitingBlocks[i];
1501 if (!OriginalLoopProb.
isUnknown() && IsLatch) {
1505 ProbUpdateRequired |= OriginalLoopProb != ActualProb;
1508 SetDest(Info.ExitingBlocks[i], *KnownWillExit, Info.ExitOnTrue);
1514 if (ExitingBlocks.
size() == 1 && ExitInfos.
size() == 1) {
1522 auto &[OriginalExit, Info] = *ExitInfos.
begin();
1523 if (!Info.FirstExitingBlock)
1524 Info.FirstExitingBlock = Info.ExitingBlocks.back();
1526 if (L->contains(
C->getBlock()))
1528 C->setIDom(DT->
getNode(Info.FirstExitingBlock));
1535 if (!LatchIsExiting && CompletelyUnroll) {
1556 "Expected one latch block per unrolled iteration");
1557 std::vector<unsigned> IterCounts(1, 0);
1558 std::vector<BasicBlock *> CondLatches;
1559 std::vector<BasicBlock *> CondLatchNexts;
1560 IterCounts.reserve(Latches.size() + 1);
1561 CondLatches.reserve(Latches.size());
1562 CondLatchNexts.reserve(Latches.size());
1566 ++IterCounts.back();
1568 (CompletelyUnroll && !LatchIsExiting && Latch == Latches.back())) &&
1569 "Need a branch as terminator, except when fully unrolling with "
1570 "unconditional latch");
1577 DTUToUse ?
nullptr : DT)) {
1583 IterCounts.push_back(0);
1584 CondLatches.push_back(Latch);
1585 CondLatchNexts.push_back(Headers[(
I + 1) % Latches.size()]);
1590 if (ProbUpdateRequired) {
1592 IterCounts, CondLatches, CondLatchNexts);
1597 if (!PartialReductions.
empty()) {
1600 "Can only introduce parallel reduction phis with single exit block");
1602 "currently only a single reduction is supported");
1603 Value *FinalRdxValue = PartialReductions.
back();
1604 Value *RdxResult =
nullptr;
1606 if (Phi.getIncomingValueForBlock(L->getLoopLatch()) != FinalRdxValue)
1609 RdxResult = PartialReductions.
front();
1611 Builder.setFastMathFlags(
Reductions.begin()->second.getFastMathFlags());
1617 RdxResult = Builder.CreateBinOp(
1619 RdxPart, RdxResult,
"bin.rdx");
1621 NeedToFixLCSSA =
true;
1623 RdxPart->dropPoisonGeneratingFlags();
1626 Phi.replaceAllUsesWith(RdxResult);
1635 DT->
verify(DominatorTree::VerificationLevel::Fast));
1637 Loop *OuterL = L->getParentLoop();
1638 std::vector<BasicBlock *> Blocks;
1640 if (CompletelyUnroll) {
1641 Blocks = L->getBlocks();
1650 L, !CompletelyUnroll && ULO.
Count > 1, LI, SE, DT, AC,
TTI,
1653 NumCompletelyUnrolled += CompletelyUnroll;
1656 if (!CompletelyUnroll) {
1685 assert((CondLatches.size() == 1 &&
1686 (ProbUpdateRequired || OriginalLoopProb.
isOne())) &&
1687 "Expected ULO.Runtime to give unrolled loop 1 conditional latch, "
1688 "the backedge, requiring a probability update unless infinite");
1693 if (OriginalTripCount) {
1694 unsigned NewTripCount = *OriginalTripCount / ULO.
Count;
1713 if (PreserveLCSSA && OuterL && CompletelyUnroll && !NeedToFixLCSSA)
1723 if (NeedToFixLCSSA) {
1728 Loop *FixLCSSALoop = OuterL;
1729 if (!FixLCSSALoop->
contains(LatchLoop))
1734 }
else if (PreserveLCSSA) {
1736 "Loops should be in LCSSA form after loop-unroll.");
1741 simplifyLoop(OuterL, DT, LI, SE, AC,
nullptr, PreserveLCSSA);
1744 for (
Loop *SubLoop : LoopsToSimplify)
1745 simplifyLoop(SubLoop, DT, LI, SE, AC,
nullptr, PreserveLCSSA);
1776 if (
MDNode *LoopID = L->getLoopID())
1781std::optional<RecurrenceDescriptor>
1787 nullptr,
nullptr, SE))
1788 return std::nullopt;
1790 return std::nullopt;
1792 static const auto ValidRKs = {
1803 return std::nullopt;
1806 return std::nullopt;
1809 return std::nullopt;
1813 return std::nullopt;
1823 return std::nullopt;
1826 return std::nullopt;
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
Optimize for code generation
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file defines the DenseMap class.
early cse Early CSE w MemorySSA
This file defines a set of templates that efficiently compute a dominator tree over a generic graph.
This file provides various utilities for inspecting and working with the control flow graph in LLVM I...
This defines the Use class.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static bool needToInsertPhisForLCSSA(Loop *L, const std::vector< BasicBlock * > &Blocks, LoopInfo *LI)
Check if unrolling created a situation where we need to insert phi nodes to preserve LCSSA form.
static bool isEpilogProfitable(Loop *L)
The function chooses which type of unroll (epilog or prolog) is more profitabale.
static void fixProbContradiction(Loop *L, UnrollLoopOptions ULO, OptimizationRemarkEmitter *ORE, BranchProbability OriginalLoopProb, bool CompletelyUnroll, std::vector< unsigned > &IterCounts, const std::vector< BasicBlock * > &CondLatches, std::vector< BasicBlock * > &CondLatchNexts)
void loadCSE(Loop *L, DominatorTree &DT, ScalarEvolution &SE, LoopInfo &LI, BatchAAResults &BAA, function_ref< MemorySSA *()> GetMSSA)
Value * getMatchingValue(LoadValue LV, LoadInst *LI, unsigned CurrentGeneration, BatchAAResults &BAA, function_ref< MemorySSA *()> GetMSSA)
static cl::opt< bool > UnrollUniformWeights("unroll-uniform-weights", cl::init(false), cl::Hidden, cl::desc("If new branch weights must be found, work harder to keep them " "uniform."))
static cl::opt< bool > UnrollRuntimeEpilog("unroll-runtime-epilog", cl::init(false), cl::Hidden, cl::desc("Allow runtime unrolled loops to be unrolled " "with epilog instead of prolog."))
static cl::opt< bool > UnrollVerifyLoopInfo("unroll-verify-loopinfo", cl::Hidden, cl::desc("Verify loopinfo after unrolling"), cl::init(false))
static cl::opt< bool > UnrollVerifyDomtree("unroll-verify-domtree", cl::Hidden, cl::desc("Verify domtree after unrolling"), cl::init(false))
static cl::opt< bool > UnrollAddParallelReductions("unroll-add-parallel-reductions", cl::init(false), cl::Hidden, cl::desc("Allow unrolling to add parallel reduction phis."))
This file implements a map that provides insertion order iteration.
This file exposes an interface to building/using memory SSA to walk memory instructions using a use/d...
uint64_t IntrinsicInst * II
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
void childGeneration(unsigned generation)
unsigned currentGeneration() const
unsigned childGeneration() const
StackNode(ScopedHashTable< const SCEV *, LoadValue > &AvailableLoads, unsigned cg, DomTreeNode *N, DomTreeNode::const_iterator Child, DomTreeNode::const_iterator End)
DomTreeNode::const_iterator end() const
DomTreeNode * nextChild()
DomTreeNode::const_iterator childIter() const
Class for arbitrary precision integers.
LLVM_ABI APInt sadd_ov(const APInt &RHS, bool &Overflow) const
Represent a constant reference to an array (0 or more elements consecutively in memory),...
A cache of @llvm.assume calls within a function.
LLVM_ABI void registerAssumption(AssumeInst *CI)
Add an @llvm.assume intrinsic to this function's cache.
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.
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 * getSinglePredecessor() const
Return the predecessor of this block if it has a single predecessor block.
LLVM_ABI const BasicBlock * getUniquePredecessor() const
Return the predecessor of this block if it has a unique predecessor block.
LLVM_ABI const BasicBlock * getSingleSuccessor() const
Return the successor of this block if it has a single successor.
InstListType::iterator iterator
Instruction iterators...
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
LLVM_ABI void removePredecessor(BasicBlock *Pred, bool KeepOneInputPHIs=false)
Update PHI nodes in this BasicBlock before removal of predecessor Pred.
This class is a wrapper over an AAResults, and it is intended to be used only when there are no IR ch...
static LLVM_ABI BranchProbability getBranchProbability(uint64_t Numerator, uint64_t Denominator)
static constexpr BranchProbability getOne()
LLVM_ABI BranchProbability pow(unsigned N) const
Compute pow(Probability, N).
static constexpr BranchProbability getZero()
Conditional Branch instruction.
A parsed version of the target data layout string in and methods for querying it.
ValueT lookup(const_arg_type_t< KeyT > Val) const
Return the entry for the specified key, or a default constructed value if no such entry exists.
iterator_range< iterator > children()
DomTreeNodeBase * getIDom() const
bool verify(VerificationLevel VL=VerificationLevel::Full) const
verify - checks if the tree is correct.
void changeImmediateDominator(DomTreeNodeBase< NodeT > *N, DomTreeNodeBase< NodeT > *NewIDom)
changeImmediateDominator - This method is used to update the dominator tree information when a node's...
DomTreeNodeBase< NodeT > * addNewBlock(NodeT *BB, NodeT *DomBB)
Add a new node to the dominator tree information.
static constexpr UpdateKind Delete
DomTreeNodeBase< NodeT > * getNode(const NodeT *BB) const
getNode - return the (Post)DominatorTree node for the specified basic block.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
LLVM_ABI Instruction * findNearestCommonDominator(Instruction *I1, Instruction *I2) const
Find the nearest instruction I that dominates both I1 and I2, in the sense that a result produced bef...
DomTreeT & getDomTree()
Flush DomTree updates and return DomTree.
void applyUpdates(ArrayRef< UpdateT > Updates)
Submit updates to all available trees.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
LLVM_ABI void moveBefore(InstListType::iterator InsertPos)
Unlink this instruction from its current basic block and insert it into the basic block that MovePos ...
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
An instruction for reading from memory.
bool contains(const LoopT *L) const
Return true if the specified loop is contained within this loop.
BlockT * getHeader() const
void addBasicBlockToLoop(BlockT *NewBB, LoopInfoBase< BlockT, LoopT > &LI)
This method is used by other analyses to update loop information.
void addChildLoop(LoopT *NewChild)
Add the specified loop to be a child of this loop.
LoopT * getParentLoop() const
Return the parent loop if it exists or nullptr for top level loops.
Store the result of a depth first search within basic blocks contained by a single loop.
RPOIterator beginRPO() const
Reverse iterate over the cached postorder blocks.
std::vector< BasicBlock * >::const_reverse_iterator RPOIterator
LLVM_ABI void perform(const LoopInfo *LI)
Traverse the loop blocks and store the DFS result.
RPOIterator endRPO() const
void addTopLevelLoop(LoopT *New)
This adds the specified loop to the collection of top-level loops.
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
bool replacementPreservesLCSSAForm(Instruction *From, Value *To)
Returns true if replacing From with To everywhere is guaranteed to preserve LCSSA form.
LLVM_ABI void erase(Loop *L)
Update LoopInfo after removing the last backedge from a loop.
Represents a single loop in the control flow graph.
bool isLCSSAForm(const DominatorTree &DT, bool IgnoreTokens=true) const
Return true if the Loop is in LCSSA form.
const MDOperand & getOperand(unsigned I) const
ArrayRef< MDOperand > operands() const
unsigned getNumOperands() const
Return number of MDNode operands.
LLVM_ABI StringRef getString() const
This class implements a map that also provides access to all stored values in a deterministic order.
iterator find(const KeyT &Key)
bool contains(const KeyT &Key) const
MemoryAccess * getClobberingMemoryAccess(const Instruction *I, BatchAAResults &AA)
Given a memory Mod/Ref/ModRef'ing instruction, calling this will give you the nearest dominating Memo...
Encapsulates MemorySSA, including all data associated with memory accesses.
LLVM_ABI bool dominates(const MemoryAccess *A, const MemoryAccess *B) const
Given two memory accesses in potentially different blocks, determine whether MemoryAccess A dominates...
LLVM_ABI MemorySSAWalker * getWalker()
MemoryUseOrDef * getMemoryAccess(const Instruction *I) const
Given a memory Mod/Ref'ing instruction, get the MemorySSA access associated with it.
void setIncomingValueForBlock(const BasicBlock *BB, Value *V)
Set every incoming value(s) for block BB to V.
Value * getIncomingValueForBlock(const BasicBlock *BB) const
The RecurrenceDescriptor is used to identify recurrences variables in a loop.
FastMathFlags getFastMathFlags() const
bool hasExactFPMath() const
Returns true if the recurrence has floating-point math that requires precise (ordered) operations.
static LLVM_ABI unsigned getOpcode(RecurKind Kind)
Returns the opcode corresponding to the RecurrenceKind.
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.
RecurKind getRecurrenceKind() const
StoreInst * IntermediateStore
Reductions may store temporary or final result to an invariant address.
static bool isMinMaxRecurrenceKind(RecurKind Kind)
Returns true if the recurrence kind is any min/max kind.
This class represents an analyzed expression in the program.
The main scalar evolution driver.
LLVM_ABI unsigned getSmallConstantTripMultiple(const Loop *L, const SCEV *ExitCount)
Returns the largest constant divisor of the trip count as a normal unsigned value,...
LLVM_ABI const SCEV * getSCEV(Value *V)
Return a SCEV expression for the full generality of the specified expression.
LLVM_ABI unsigned getSmallConstantMaxTripCount(const Loop *L, SmallVectorImpl< const SCEVPredicate * > *Predicates=nullptr)
Returns the upper bound of the loop trip count as a normal unsigned value.
LLVM_ABI bool isBackedgeTakenCountMaxOrZero(const Loop *L)
Return true if the backedge taken count is either the value returned by getConstantMaxBackedgeTakenCo...
LLVM_ABI void forgetTopmostLoop(const Loop *L)
LLVM_ABI void forgetValue(Value *V)
This method should be called by the client when it has changed a value in a way that may effect its v...
LLVM_ABI void forgetBlockAndLoopDispositions(Value *V=nullptr)
Called when the client has changed the disposition of values in a loop or block.
LLVM_ABI void forgetLcssaPhiWithNewPredecessor(Loop *L, PHINode *V)
Forget LCSSA phi node V of loop L to which a new predecessor was added, such that it may no longer be...
LLVM_ABI unsigned getSmallConstantTripCount(const Loop *L)
Returns the exact trip count of the loop if we can compute it, and the result is a small constant.
LLVM_ABI void forgetAllLoops()
void insert(const K &Key, const V &Val)
V lookup(const K &Key) const
ScopedHashTableScope< K, V, KInfo, AllocatorTy > ScopeTy
ScopeTy - A type alias for easy access to the name of the scope for this hash table.
void insert_range(Range &&R)
bool insert(const value_type &X)
Insert a new element into the SetVector.
A SetVector that performs no allocations if smaller than a certain size.
reference emplace_back(ArgTypes &&... Args)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
std::string str() const
Get the contents as an std::string.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
static UncondBrInst * Create(BasicBlock *Target, InsertPosition InsertBefore=nullptr)
A Use represents the edge between a Value definition and its users.
LLVM_ABI bool replaceUsesOfWith(Value *From, Value *To)
Replace uses of one Value with another.
iterator find(const KeyT &Val)
ValueMapIteratorImpl< MapT, const Value *, false > iterator
bool erase(const KeyT &Val)
DMAtomT AtomMap
Map {(InlinedAt, old atom number) -> new atom number}.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
An efficient, type-erasing, non-owning reference to a callable.
self_iterator getIterator()
Abstract Attribute helper functions.
BinaryOp_match< LHS, RHS, Instruction::Add > m_Add(const LHS &L, const RHS &R)
ap_match< APInt > m_APInt(const APInt *&Res)
Match a ConstantInt or splatted ConstantVector, binding the specified pointer to the contained APInt.
bool match(Val *V, const Pattern &P)
auto m_Value()
Match an arbitrary value and ignore it.
initializer< Ty > init(const Ty &Val)
Add a small namespace to avoid name clashes with the classes used in the streaming interface.
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI bool simplifyLoop(Loop *L, DominatorTree *DT, LoopInfo *LI, ScalarEvolution *SE, AssumptionCache *AC, MemorySSAUpdater *MSSAU, bool PreserveLCSSA)
Simplify each loop in a loop nest recursively.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
LLVM_ABI BranchProbability getBranchProbability(CondBrInst *B, bool ForFirstTarget)
Based on branch weight metadata, return either:
LLVM_ABI bool RemoveRedundantDbgInstrs(BasicBlock *BB)
Try to remove redundant dbg.value instructions from given basic block.
LLVM_ABI std::optional< unsigned > getLoopEstimatedTripCount(Loop *L, unsigned *EstimatedLoopInvocationWeight=nullptr)
Return either:
LLVM_ABI bool RecursivelyDeleteTriviallyDeadInstructions(Value *V, const TargetLibraryInfo *TLI=nullptr, MemorySSAUpdater *MSSAU=nullptr, std::function< void(Value *)> AboutToDeleteCallback=std::function< void(Value *)>())
If the specified value is a trivially dead instruction, delete it.
LLVM_ABI BasicBlock * CloneBasicBlock(const BasicBlock *BB, ValueToValueMapTy &VMap, const Twine &NameSuffix="", Function *F=nullptr, ClonedCodeInfo *CodeInfo=nullptr, bool MapAtoms=true)
Return a copy of the specified basic block, but without embedding the block into a particular functio...
LLVM_ABI std::optional< RecurrenceDescriptor > canParallelizeReductionWhenUnrolling(PHINode &Phi, Loop *L, ScalarEvolution *SE)
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.
auto successors(const MachineBasicBlock *BB)
SmallDenseMap< const Loop *, Loop *, 4 > NewLoopsMap
LLVM_ABI cl::opt< bool > EnableFSDiscriminator
@ Load
The value being inserted comes from a load (InsertElement only).
LLVM_ABI bool formLCSSARecursively(Loop &L, const DominatorTree &DT, const LoopInfo *LI, ScalarEvolution *SE)
Put a loop nest into LCSSA form.
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...
LLVM_ABI void simplifyLoopAfterUnroll(Loop *L, bool SimplifyIVs, LoopInfo *LI, ScalarEvolution *SE, DominatorTree *DT, AssumptionCache *AC, const TargetTransformInfo *TTI, ArrayRef< BasicBlock * > Blocks, AAResults *AA=nullptr)
Perform some cleanup and simplifications on loops after unrolling.
constexpr auto equal_to(T &&Arg)
Functor variant of std::equal_to that can be used as a UnaryPredicate in functional algorithms like a...
LLVM_ABI Value * createMinMaxOp(IRBuilderBase &Builder, RecurKind RK, Value *Left, Value *Right)
Returns a Min/Max operation corresponding to MinMaxRecurrenceKind.
LLVM_ABI Value * simplifyInstruction(Instruction *I, const SimplifyQuery &Q)
See if we can compute a simplified version of this instruction.
DomTreeNodeBase< BasicBlock > DomTreeNode
auto make_isa_range(RangeT &&Range)
Return a range over Range containing only elements for which isa<T> holds, casting each of them to T.
auto dyn_cast_or_null(const Y &Val)
void erase(Container &C, ValueType V)
Wrapper function to remove a value from a container:
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 bool isInstructionTriviallyDead(Instruction *I, const TargetLibraryInfo *TLI=nullptr)
Return true if the result produced by the instruction is not used, and the instruction will return.
LLVM_ABI void setBranchProbability(CondBrInst *B, BranchProbability P, bool ForFirstTarget)
Set branch weight metadata for B to indicate that P and 1 - P are the probabilities of control flowin...
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI bool simplifyLoopIVs(Loop *L, ScalarEvolution *SE, DominatorTree *DT, LoopInfo *LI, const TargetTransformInfo *TTI, SmallVectorImpl< WeakTrackingVH > &Dead)
SimplifyLoopIVs - Simplify users of induction variables within this loop.
SmallVector< ValueTypeFromRangeType< R >, Size > to_vector(R &&Range)
Given a range of type R, iterate the entire range and return a SmallVector with elements of the vecto...
LLVM_ABI BranchProbability getLoopProbability(Loop *L)
Based on branch weight metadata, return either:
LoopUnrollResult
Represents the result of a UnrollLoop invocation.
@ PartiallyUnrolled
The loop was partially unrolled – we still have a loop, but with a smaller trip count.
@ Unmodified
The loop was not modified.
@ FullyUnrolled
The loop was fully unrolled into straight-line code.
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 unsigned changeToUnreachable(Instruction *I, bool PreserveLCSSA=false, DomTreeUpdater *DTU=nullptr, MemorySSAUpdater *MSSAU=nullptr)
Insert an unreachable instruction before the specified instruction, making it and the rest of the cod...
LLVM_ABI void combineMetadataForCSE(Instruction *K, const Instruction *J, bool DoesKMove)
Combine the metadata of two instructions so that K can replace J.
LLVM_ABI bool setLoopProbability(Loop *L, BranchProbability P)
Set branch weight metadata for the latch of L to indicate that, at the end of any iteration,...
LLVM_ABI bool MergeBlockIntoPredecessor(BasicBlock *BB, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, MemoryDependenceResults *MemDep=nullptr, bool PredecessorWithTwoSuccessors=false, DominatorTree *DT=nullptr)
Attempts to merge a block into its predecessor, if possible.
void replace(R &&Range, const T &OldValue, const T &NewValue)
Provide wrappers to std::replace which take ranges instead of having to pass begin/end explicitly.
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.
@ FMaxNum
FP max with llvm.maxnum semantics including NaNs.
@ Mul
Product of integers.
@ 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()).
@ FMinNum
FP min with llvm.minnum semantics including NaNs.
@ FMaximumNum
FP max with llvm.maximumnum semantics.
@ UMax
Unsigned integer max implemented in terms of select(cmp()).
LLVM_ABI Value * getRecurrenceIdentity(RecurKind K, Type *Tp, FastMathFlags FMF)
Given information about an recurrence kind, return the identity for the @llvm.vector....
LLVM_ABI MDNode * getUnrollMetadataForLoop(const Loop *L, StringRef Name)
LLVM_ABI void cloneAndAdaptNoAliasScopes(ArrayRef< MDNode * > NoAliasDeclScopes, ArrayRef< BasicBlock * > NewBlocks, LLVMContext &Context, StringRef Ext)
Clone the specified noalias decl scopes.
LLVM_ABI void remapInstructionsInBlocks(ArrayRef< BasicBlock * > Blocks, ValueToValueMapTy &VMap)
Remaps instructions in Blocks using the mapping in VMap.
LLVM_ABI StringRef getLoopVectorizeKindPrefix(const Loop *L)
Return a short prefix describing the loop's vectorizer origin based on the llvm.loop....
ValueMap< const Value *, WeakTrackingVH > ValueToValueMapTy
LLVM_ABI bool setLoopEstimatedTripCount(Loop *L, unsigned EstimatedTripCount, std::optional< unsigned > EstimatedLoopInvocationWeight=std::nullopt)
Set llvm.loop.estimated_trip_count with the value EstimatedTripCount in the loop metadata of L.
LLVM_ABI const Loop * addClonedBlockToLoopInfo(BasicBlock *OriginalBB, BasicBlock *ClonedBB, LoopInfo *LI, NewLoopsMap &NewLoops)
Adds ClonedBB to LoopInfo, creates a new loop for ClonedBB if necessary and adds a mapping from the o...
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
LLVM_ABI void identifyNoAliasScopesToClone(ArrayRef< BasicBlock * > BBs, SmallVectorImpl< MDNode * > &NoAliasDeclScopes)
Find the 'llvm.experimental.noalias.scope.decl' intrinsics in the specified basic blocks and extract ...
@ End
Run the machine verifier once, at the end of the pipeline.
LLVM_ABI bool UnrollRuntimeLoopRemainder(Loop *L, unsigned Count, bool AllowExpensiveTripCount, bool UseEpilogRemainder, bool UnrollRemainder, bool ForgetAllSCEV, LoopInfo *LI, ScalarEvolution *SE, DominatorTree *DT, AssumptionCache *AC, const TargetTransformInfo *TTI, bool PreserveLCSSA, unsigned SCEVExpansionBudget, bool RuntimeUnrollMultiExit, Loop **ResultLoop=nullptr, std::optional< unsigned > OriginalTripCount=std::nullopt, BranchProbability OriginalLoopProb=BranchProbability::getUnknown())
Insert code in the prolog/epilog code when unrolling a loop with a run-time trip-count.
LLVM_ABI MDNode * GetUnrollMetadata(MDNode *LoopID, StringRef Name)
Given an llvm.loop loop id metadata node, returns the loop hint metadata node with the given name (fo...
constexpr detail::IsaCheckPredicate< Types... > IsaPred
Function object wrapper for the llvm::isa type check.
LLVM_ABI void RemapSourceAtom(Instruction *I, ValueToValueMapTy &VM)
Remap source location atom.
LLVM_ABI LoopUnrollResult UnrollLoop(Loop *L, UnrollLoopOptions ULO, LoopInfo *LI, ScalarEvolution *SE, DominatorTree *DT, AssumptionCache *AC, const llvm::TargetTransformInfo *TTI, OptimizationRemarkEmitter *ORE, bool PreserveLCSSA, Loop **RemainderLoop=nullptr, AAResults *AA=nullptr)
Unroll the given loop by Count.
LoadValue(Instruction *Inst, unsigned Generation)
const Instruction * Heart
bool RuntimeUnrollMultiExit
bool AllowExpensiveTripCount
bool AddAdditionalAccumulators
unsigned SCEVExpansionBudget
std::conditional_t< IsConst, const ValueT &, ValueT & > second