69#define DEBUG_TYPE "simple-loop-unswitch"
74STATISTIC(NumBranches,
"Number of branches unswitched");
75STATISTIC(NumSwitches,
"Number of switches unswitched");
76STATISTIC(NumSelects,
"Number of selects turned into branches for unswitching");
77STATISTIC(NumGuards,
"Number of guards turned into branches for unswitching");
78STATISTIC(NumTrivial,
"Number of unswitches that are trivial");
80 NumCostMultiplierSkipped,
81 "Number of unswitch candidates that had their cost multiplier skipped");
83 "Number of invariant conditions injected and unswitched");
87 cl::desc(
"Forcibly enables non-trivial loop unswitching rather than "
88 "following the configuration passed into the pass."));
92 cl::desc(
"The cost threshold for unswitching a loop."));
96 cl::desc(
"Enable unswitch cost multiplier that prohibits exponential "
97 "explosion in nontrivial unswitch."));
100 cl::desc(
"Toplevel siblings divisor for cost multiplier."));
103 cl::desc(
"Outer loop size divisor for cost multiplier."));
106 cl::desc(
"Number of unswitch candidates that are ignored when calculating "
107 "cost multiplier."));
110 cl::desc(
"If enabled, simple loop unswitching will also consider "
111 "llvm.experimental.guard intrinsics as unswitch candidates."));
113 "simple-loop-unswitch-drop-non-trivial-implicit-null-checks",
115 cl::desc(
"If enabled, drop make.implicit metadata in unswitched implicit "
116 "null checks to save time analyzing if we can keep it."));
119 cl::desc(
"Max number of memory uses to explore during "
120 "partial unswitching analysis"),
124 cl::desc(
"If enabled, the freeze instruction will be added to condition "
125 "of loop unswitch to prevent miscompilation."));
128 "simple-loop-unswitch-inject-invariant-conditions",
cl::Hidden,
129 cl::desc(
"Whether we should inject new invariants and unswitch them to "
130 "eliminate some existing (non-invariant) conditions."),
134 "simple-loop-unswitch-inject-invariant-condition-hotness-threshold",
136 "unswitch on them to eliminate branches that are "
137 "not-taken 1/<this option> times or less."),
148 : Term(Term), Invariant(Invariant), InLoopSucc(InLoopSucc) {}
151struct InjectedInvariant {
152 ICmpInst::Predicate Pred;
157 InjectedInvariant(ICmpInst::Predicate Pred,
Value *LHS,
Value *RHS,
158 BasicBlock *InLoopSucc)
159 : Pred(Pred), LHS(LHS), RHS(RHS), InLoopSucc(InLoopSucc) {}
162struct NonTrivialUnswitchCandidate {
164 TinyPtrVector<Value *> Invariants;
165 std::optional<InstructionCost> Cost;
166 std::optional<InjectedInvariant> PendingInjection;
167 NonTrivialUnswitchCandidate(
169 std::optional<InstructionCost> Cost = std::nullopt,
170 std::optional<InjectedInvariant> PendingInjection = std::nullopt)
171 : TI(TI), Invariants(Invariants), Cost(Cost),
172 PendingInjection(PendingInjection) {};
174 bool hasPendingInjection()
const {
return PendingInjection.has_value(); }
198 assert(!L.isLoopInvariant(&Root) &&
199 "Only need to walk the graph if root itself is not invariant.");
212 for (
Value *OpV :
I.operand_values()) {
218 if (L.isLoopInvariant(OpV)) {
229 if (Visited.
insert(OpI).second)
233 }
while (!Worklist.
empty());
248 if (UserI && L.contains(UserI))
266 if (!L.isLoopInvariant(PN->getIncomingValueForBlock(&ExitingBB)))
283 for (
Value *Inv : Invariants) {
292 Direction ? &NormalSucc : &UnswitchedSucc);
301 for (
auto *Val :
reverse(ToDuplicate)) {
319 auto *DefiningAccess = MemUse->getDefiningAccess();
321 while (L.contains(DefiningAccess->getBlock())) {
326 MemPhi->getIncomingValueForBlock(L.getLoopPreheader());
340 Direction ? &NormalSucc : &UnswitchedSucc);
357 for (
auto i :
seq<int>(0, PN.getNumOperands())) {
358 assert(PN.getIncomingBlock(i) == &OldExitingBB &&
359 "Found incoming block different from unique predecessor!");
360 PN.setIncomingBlock(i, &OldPH);
377 assert(&ExitBB != &UnswitchedBB &&
378 "Must have different loop exit and unswitched blocks!");
382 PN.getName() +
".split");
383 NewPN->insertBefore(InsertPt);
394 for (
int i = PN.getNumIncomingValues() - 1; i >= 0; --i) {
395 if (PN.getIncomingBlock(i) != &OldExitingBB)
401 PN.removeIncomingValue(i);
403 NewPN->addIncoming(
Incoming, &OldPH);
408 PN.replaceAllUsesWith(NewPN);
409 NewPN->addIncoming(&PN, &ExitBB);
422 Loop *OldParentL = L.getParentLoop();
427 L.getExitBlocks(Exits);
428 Loop *NewParentL =
nullptr;
429 for (
auto *ExitBB : Exits)
431 if (!NewParentL || NewParentL->
contains(ExitL))
434 if (NewParentL == OldParentL)
440 "Can only hoist this loop up the nest!");
445 "Parent loop of this loop should contain this loop's preheader!");
460 for (
Loop *OldContainingL = OldParentL; OldContainingL != NewParentL;
464 return BB == &Preheader || L.contains(BB);
467 OldContainingL->getBlocksSet().erase(&Preheader);
469 OldContainingL->getBlocksSet().erase(BB);
492 Loop *Current = TopMost;
522 LLVM_DEBUG(
dbgs() <<
" Trying to unswitch branch: " << BI <<
"\n");
529 bool FullUnswitch =
false;
532 if (L.isLoopInvariant(
Cond)) {
538 if (Invariants.
empty()) {
545 bool ExitDirection =
true;
546 int LoopExitSuccIdx = 0;
548 if (L.contains(LoopExitBB)) {
549 ExitDirection =
false;
552 if (L.contains(LoopExitBB)) {
557 auto *ContinueBB = BI.
getSuccessor(1 - LoopExitSuccIdx);
560 LLVM_DEBUG(
dbgs() <<
" Loop exit PHI's aren't loop-invariant!\n");
573 "non-full unswitch!\n");
579 dbgs() <<
" unswitching trivial invariant conditions for: " << BI
581 for (
Value *Invariant : Invariants) {
582 dbgs() <<
" " << *Invariant <<
" == true";
583 if (Invariant != Invariants.back())
615 if (FullUnswitch && LoopExitBB->getUniquePredecessor()) {
617 "A branch's parent isn't a predecessor!");
618 UnswitchedBB = LoopExitBB;
621 SplitBlock(LoopExitBB, LoopExitBB->begin(), &DT, &LI, MSSAU,
"",
false);
654 "Must have an `or` of `i1`s or `select i1 X, true, Y`s for the "
658 "Must have an `and` of `i1`s or `select i1 X, Y, false`s for the"
661 *OldPH, Invariants, ExitDirection, *UnswitchedBB, *NewPH,
684 Term->eraseFromParent();
694 if (UnswitchedBB == LoopExitBB)
698 *ParentBB, *OldPH, FullUnswitch);
709 for (
Value *Invariant : Invariants)
756 Value *LoopCond =
SI.getCondition();
759 if (!L.isLoopInvariant(LoopCond))
762 auto *ParentBB =
SI.getParent();
769 auto IsTriviallyUnswitchableExitBlock = [&](
BasicBlock &BBToCheck) {
771 if (L.contains(&BBToCheck))
780 auto *TI = BBToCheck.getTerminator();
782 return !isUnreachable || &*BBToCheck.getFirstNonPHIOrDbg() != TI;
786 for (
auto Case :
SI.cases())
787 if (IsTriviallyUnswitchableExitBlock(*Case.getCaseSuccessor()))
788 ExitCaseIndices.
push_back(Case.getCaseIndex());
792 if (IsTriviallyUnswitchableExitBlock(*
SI.getDefaultDest())) {
793 DefaultExitBB =
SI.getDefaultDest();
794 }
else if (ExitCaseIndices.
empty())
809 if (!ExitL || ExitL->
contains(OuterL))
812 for (
unsigned Index : ExitCaseIndices) {
813 auto CaseI =
SI.case_begin() + Index;
816 if (!ExitL || ExitL->
contains(OuterL))
830 SI.setDefaultDest(
nullptr);
838 ExitCases.reserve(ExitCaseIndices.
size());
842 for (
unsigned Index :
reverse(ExitCaseIndices)) {
843 auto CaseI =
SI.case_begin() + Index;
846 ExitCases.emplace_back(CaseI->getCaseValue(), CaseI->getCaseSuccessor(), W);
854 if (
SI.getNumCases() > 0 &&
856 return Case.getCaseSuccessor() == SI.case_begin()->getCaseSuccessor();
858 CommonSuccBB =
SI.case_begin()->getCaseSuccessor();
859 if (!DefaultExitBB) {
863 if (
SI.getNumCases() == 0)
864 CommonSuccBB =
SI.getDefaultDest();
865 else if (
SI.getDefaultDest() != CommonSuccBB)
866 CommonSuccBB =
nullptr;
895 UnswitchedExitBBs.
insert(DefaultExitBB);
903 DefaultExitBB = SplitExitBBMap[DefaultExitBB] = SplitBB;
908 for (
auto &ExitCase :
reverse(ExitCases)) {
916 if (UnswitchedExitBBs.
insert(ExitBB).second)
923 BasicBlock *&SplitExitBB = SplitExitBBMap[ExitBB];
932 std::get<1>(ExitCase) = SplitExitBB;
937 for (
auto &ExitCase :
reverse(ExitCases)) {
939 BasicBlock *UnswitchedBB = std::get<1>(ExitCase);
941 NewSIW.
addCase(CaseVal, UnswitchedBB, std::get<2>(ExitCase));
952 for (
const auto &Case :
SI.cases())
955 }
else if (DefaultCaseWeight) {
958 for (
const auto &Case :
SI.cases()) {
961 "case weight must be defined as default case weight is defined");
976 bool SkippedFirst = DefaultExitBB ==
nullptr;
977 for (
auto Case :
SI.cases()) {
979 "Non-common successor!");
992 }
else if (DefaultExitBB) {
994 "If we had no cases we'd have a common successor!");
999 auto LastCaseI = std::prev(
SI.case_end());
1001 SI.setDefaultDest(LastCaseI->getCaseSuccessor());
1012 for (
auto *UnswitchedExitBB : UnswitchedExitBBs) {
1016 for (
auto SplitUnswitchedPair : SplitExitBBMap) {
1017 DTUpdates.
push_back({DT.
Delete, ParentBB, SplitUnswitchedPair.first});
1029 assert(DT.
verify(DominatorTree::VerificationLevel::Fast));
1074 Visited.
insert(CurrentBB);
1081 if (!
isa<MemoryPhi>(*Defs->begin()) || (++Defs->begin() != Defs->end()))
1108 if (!BI || BI->isConditional())
1111 CurrentBB = BI->getSuccessor(0);
1123 if (!BI->isConditional() ||
1138 if (BI->isConditional())
1142 CurrentBB = BI->getSuccessor(0);
1147 }
while (L.contains(CurrentBB) && Visited.
insert(CurrentBB).second);
1185 NewBlocks.
reserve(L.getNumBlocks() + ExitBlocks.
size());
1196 VMap[OldBB] = NewBB;
1204 auto It = DominatingSucc.
find(BB);
1205 return It != DominatingSucc.
end() && It->second != UnswitchedSuccBB;
1209 auto *ClonedPH = CloneBlock(LoopPH);
1212 for (
auto *LoopBB : L.blocks())
1213 if (!SkipBlock(LoopBB))
1219 for (
auto *ExitBB : ExitBlocks) {
1220 if (SkipBlock(ExitBB))
1228 auto *MergeBB =
SplitBlock(ExitBB, ExitBB->begin(), &DT, &LI, MSSAU);
1233 MergeBB->takeName(ExitBB);
1234 ExitBB->setName(
Twine(MergeBB->getName()) +
".split");
1237 auto *ClonedExitBB = CloneBlock(ExitBB);
1238 assert(ClonedExitBB->getTerminator()->getNumSuccessors() == 1 &&
1239 "Exit block should have been split to have one successor!");
1240 assert(ClonedExitBB->getTerminator()->getSuccessor(0) == MergeBB &&
1241 "Cloned exit block has the wrong successor!");
1247 std::prev(ClonedExitBB->end())))) {
1255 "Bad instruction in exit block!");
1257 assert(VMap.
lookup(&
I) == &ClonedI &&
"Mismatch in the value map!");
1268 MergePN->insertBefore(InsertPt);
1269 MergePN->setDebugLoc(InsertPt->getDebugLoc());
1270 I.replaceAllUsesWith(MergePN);
1271 MergePN->addIncoming(&
I, ExitBB);
1272 MergePN->addIncoming(&ClonedI, ClonedExitBB);
1281 Module *M = ClonedPH->getParent()->getParent();
1282 for (
auto *ClonedBB : NewBlocks)
1294 for (
auto *LoopBB : L.blocks())
1295 if (SkipBlock(LoopBB))
1298 for (
PHINode &PN : ClonedSuccBB->phis())
1299 PN.removeIncomingValue(LoopBB,
false);
1305 if (SuccBB == UnswitchedSuccBB)
1312 ClonedSuccBB->removePredecessor(ClonedParentBB,
1319 Instruction *ClonedTerminator = ClonedParentBB->getTerminator();
1322 Value *ClonedConditionToErase =
nullptr;
1324 ClonedConditionToErase = BI->getCondition();
1326 ClonedConditionToErase =
SI->getCondition();
1332 if (ClonedConditionToErase)
1339 for (
PHINode &PN : ClonedSuccBB->phis()) {
1343 for (
int i = PN.getNumOperands() - 1; i >= 0; --i) {
1344 if (PN.getIncomingBlock(i) != ClonedParentBB)
1350 PN.removeIncomingValue(i,
false);
1356 for (
auto *ClonedBB : NewBlocks) {
1358 if (SuccSet.
insert(SuccBB).second)
1374 auto AddClonedBlocksToLoop = [&](
Loop &OrigL,
Loop &ClonedL) {
1375 assert(ClonedL.getBlocks().empty() &&
"Must start with an empty loop!");
1377 for (
auto *BB : OrigL.
blocks()) {
1379 ClonedL.addBlockEntry(ClonedBB);
1392 AddClonedBlocksToLoop(OrigRootL, *ClonedRootL);
1404 LoopsToClone.
push_back({ClonedRootL, ChildL});
1406 Loop *ClonedParentL, *L;
1407 std::tie(ClonedParentL, L) = LoopsToClone.
pop_back_val();
1410 AddClonedBlocksToLoop(*L, *ClonedL);
1412 LoopsToClone.
push_back({ClonedL, ChildL});
1413 }
while (!LoopsToClone.
empty());
1434 Loop *ClonedL =
nullptr;
1446 Loop *ParentL =
nullptr;
1450 for (
auto *ExitBB : ExitBlocks)
1453 ExitLoopMap[ClonedExitBB] = ExitL;
1454 ClonedExitsInLoops.
push_back(ClonedExitBB);
1455 if (!ParentL || (ParentL != ExitL && ParentL->
contains(ExitL)))
1460 "The computed parent loop should always contain (or be) the parent of "
1461 "the original loop.");
1468 for (
auto *BB : OrigL.
blocks())
1470 ClonedLoopBlocks.
insert(ClonedBB);
1481 if (Pred == ClonedPH)
1486 assert(ClonedLoopBlocks.
count(Pred) &&
"Found a predecessor of the loop "
1487 "header other than the preheader "
1488 "that is not part of the loop!");
1493 if (BlocksInClonedLoop.
insert(Pred).second && Pred != ClonedHeader)
1500 if (!BlocksInClonedLoop.
empty()) {
1501 BlocksInClonedLoop.
insert(ClonedHeader);
1503 while (!Worklist.
empty()) {
1506 "Didn't put block into the loop set!");
1514 if (ClonedLoopBlocks.
count(Pred) &&
1515 BlocksInClonedLoop.
insert(Pred).second)
1534 for (
auto *BB : OrigL.
blocks()) {
1536 if (!ClonedBB || !BlocksInClonedLoop.
count(ClonedBB))
1548 for (
Loop *PL = ClonedL; PL; PL = PL->getParentLoop())
1549 PL->addBlockEntry(ClonedBB);
1556 for (
Loop *ChildL : OrigL) {
1557 auto *ClonedChildHeader =
1559 if (!ClonedChildHeader || !BlocksInClonedLoop.
count(ClonedChildHeader))
1565 for (
auto *ChildLoopBB : ChildL->blocks())
1568 "Child cloned loop has a header within the cloned outer "
1569 "loop but not all of its blocks!");
1584 if (BlocksInClonedLoop.
empty())
1585 UnloopedBlockSet.
insert(ClonedPH);
1586 for (
auto *ClonedBB : ClonedLoopBlocks)
1587 if (!BlocksInClonedLoop.
count(ClonedBB))
1588 UnloopedBlockSet.
insert(ClonedBB);
1594 auto OrderedClonedExitsInLoops = ClonedExitsInLoops;
1596 return ExitLoopMap.
lookup(
LHS)->getLoopDepth() <
1597 ExitLoopMap.
lookup(
RHS)->getLoopDepth();
1602 while (!UnloopedBlockSet.
empty() && !OrderedClonedExitsInLoops.empty()) {
1603 assert(Worklist.
empty() &&
"Didn't clear worklist!");
1605 BasicBlock *ExitBB = OrderedClonedExitsInLoops.pop_back_val();
1620 if (!UnloopedBlockSet.
erase(PredBB)) {
1622 (BlocksInClonedLoop.
count(PredBB) || ExitLoopMap.
count(PredBB)) &&
1623 "Predecessor not mapped to a loop!");
1630 bool Inserted = ExitLoopMap.
insert({PredBB, ExitL}).second;
1632 assert(Inserted &&
"Should only visit an unlooped block once!");
1637 }
while (!Worklist.
empty());
1647 ArrayRef(ClonedPH), ClonedLoopBlocks, ClonedExitsInLoops))
1649 OuterL->addBasicBlockToLoop(BB, LI);
1652 for (
auto &BBAndL : ExitLoopMap) {
1653 auto *BB = BBAndL.first;
1654 auto *OuterL = BBAndL.second;
1656 "Failed to put all blocks into outer loops!");
1663 for (
Loop *ChildL : OrigL) {
1664 auto *ClonedChildHeader =
1666 if (!ClonedChildHeader || BlocksInClonedLoop.
count(ClonedChildHeader))
1670 for (
auto *ChildLoopBB : ChildL->blocks())
1672 "Cloned a child loop header but not all of that loops blocks!");
1676 *ChildL, ExitLoopMap.
lookup(ClonedChildHeader), VMap, LI));
1682 ArrayRef<std::unique_ptr<ValueToValueMapTy>> VMaps,
1687 for (
const auto &VMap : VMaps)
1691 SuccBB->removePredecessor(ClonedBB);
1704 BB->dropAllReferences();
1707 BB->eraseFromParent();
1724 DeathCandidates.
append(L.blocks().begin(), L.blocks().end());
1725 while (!DeathCandidates.
empty()) {
1729 SuccBB->removePredecessor(BB);
1746 for (
Loop *ParentL = &L; ParentL; ParentL = ParentL->getParentLoop()) {
1747 for (
auto *BB : DeadBlockSet)
1748 ParentL->getBlocksSet().erase(BB);
1750 [&](
BasicBlock *BB) { return DeadBlockSet.count(BB); });
1756 if (!DeadBlockSet.count(ChildL->getHeader()))
1759 assert(llvm::all_of(ChildL->blocks(),
1760 [&](BasicBlock *ChildBB) {
1761 return DeadBlockSet.count(ChildBB);
1763 "If the child loop header is dead all blocks in the child loop must "
1764 "be dead as well!");
1775 for (
auto *BB : DeadBlockSet) {
1777 assert(!DT.getNode(BB) &&
"Should already have cleared domtree!");
1778 LI.changeLoopFor(BB,
nullptr);
1784 BB->dropAllReferences();
1789 for (
auto *BB : DeadBlockSet)
1790 BB->eraseFromParent();
1808 auto *PH = L.getLoopPreheader();
1809 auto *Header = L.getHeader();
1823 assert(L.contains(Pred) &&
"Found a predecessor of the loop header other "
1824 "than the preheader that is not part of the "
1830 if (LoopBlockSet.
insert(Pred).second && Pred != Header)
1835 if (LoopBlockSet.
empty())
1836 return LoopBlockSet;
1839 while (!Worklist.
empty()) {
1841 assert(LoopBlockSet.
count(BB) &&
"Didn't put block into the loop set!");
1853 assert(L.contains(InnerL) &&
1854 "Should not reach a loop *outside* this loop!");
1857 auto *InnerPH = InnerL->getLoopPreheader();
1858 assert(L.contains(InnerPH) &&
"Cannot contain an inner loop block "
1859 "but not contain the inner loop "
1861 if (!LoopBlockSet.
insert(InnerPH).second)
1871 for (
auto *InnerBB : InnerL->blocks()) {
1872 if (InnerBB == BB) {
1874 "Block should already be in the set!");
1878 LoopBlockSet.
insert(InnerBB);
1890 if (L.contains(Pred) && LoopBlockSet.
insert(Pred).second)
1894 assert(LoopBlockSet.
count(Header) &&
"Cannot fail to add the header!");
1898 return LoopBlockSet;
1919 auto *PH = L.getLoopPreheader();
1923 Loop *ParentL =
nullptr;
1927 for (
auto *ExitBB : ExitBlocks)
1931 if (!ParentL || (ParentL != ExitL && ParentL->
contains(ExitL)))
1943 if (!LoopBlockSet.empty() && L.getParentLoop() != ParentL) {
1945 for (
Loop *IL = L.getParentLoop(); IL != ParentL;
1947 IL->getBlocksSet().erase(PH);
1948 for (
auto *BB : L.blocks())
1949 IL->getBlocksSet().erase(BB);
1951 return BB == PH || L.contains(BB);
1956 L.getParentLoop()->removeChildLoop(&L);
1964 auto &Blocks = L.getBlocksVector();
1966 LoopBlockSet.empty()
1968 : std::stable_partition(
1969 Blocks.begin(), Blocks.end(),
1970 [&](
BasicBlock *BB) { return LoopBlockSet.count(BB); });
1974 if (LoopBlockSet.empty())
1975 UnloopedBlocks.
insert(PH);
1978 for (
auto *BB :
make_range(BlocksSplitI, Blocks.end()))
1979 L.getBlocksSet().erase(BB);
1980 Blocks.erase(BlocksSplitI, Blocks.end());
1990 Loop *PrevExitL = L.getParentLoop();
1992 auto RemoveUnloopedBlocksFromLoop =
1994 for (
auto *BB : UnloopedBlocks)
1995 L.getBlocksSet().erase(BB);
1997 return UnloopedBlocks.count(BB);
2002 while (!UnloopedBlocks.
empty() && !ExitsInLoops.
empty()) {
2003 assert(Worklist.
empty() &&
"Didn't clear worklist!");
2004 assert(NewExitLoopBlocks.empty() &&
"Didn't clear loop set!");
2009 assert(ExitL.
contains(&L) &&
"Exit loop must contain the inner loop!");
2015 for (; PrevExitL != &ExitL; PrevExitL = PrevExitL->
getParentLoop())
2016 RemoveUnloopedBlocksFromLoop(*PrevExitL, UnloopedBlocks);
2030 if (!UnloopedBlocks.
erase(PredBB)) {
2031 assert((NewExitLoopBlocks.count(PredBB) ||
2033 "Predecessor not in a nested loop (or already visited)!");
2040 bool Inserted = NewExitLoopBlocks.insert(PredBB).second;
2042 assert(Inserted &&
"Should only visit an unlooped block once!");
2047 }
while (!Worklist.
empty());
2052 for (
auto *BB : NewExitLoopBlocks)
2054 if (BBL == &L || !L.contains(BBL))
2059 NewExitLoopBlocks.clear();
2065 RemoveUnloopedBlocksFromLoop(*PrevExitL, UnloopedBlocks);
2066 for (
auto *BB : UnloopedBlocks)
2068 if (BBL == &L || !L.contains(BBL))
2074 auto &SubLoops = L.getSubLoopsVector();
2075 auto SubLoopsSplitI =
2076 LoopBlockSet.empty()
2078 : std::stable_partition(
2079 SubLoops.begin(), SubLoops.end(), [&](
Loop *SubL) {
2080 return LoopBlockSet.count(SubL->getHeader());
2082 for (
auto *HoistedL :
make_range(SubLoopsSplitI, SubLoops.end())) {
2084 HoistedL->setParentLoop(
nullptr);
2094 if (
auto *NewParentL = LI.
getLoopFor(HoistedL->getLoopPreheader()))
2095 NewParentL->addChildLoop(HoistedL);
2099 SubLoops.erase(SubLoopsSplitI, SubLoops.end());
2102 if (Blocks.empty()) {
2103 assert(SubLoops.empty() &&
2104 "Failed to remove all subloops from the original loop!");
2105 if (
Loop *ParentL = L.getParentLoop())
2123template <
typename CallableT>
2135 if (!Callable(
N->getBlock()))
2141 "Cannot visit a node twice when walking a tree!");
2144 }
while (!DomWorklist.
empty());
2148 bool CurrentLoopValid,
bool PartiallyInvariant,
2151 if (!NewLoops.
empty())
2152 U.addSiblingLoops(NewLoops);
2156 if (CurrentLoopValid) {
2157 if (PartiallyInvariant) {
2160 auto &Context = L.getHeader()->getContext();
2163 MDString::get(Context,
"llvm.loop.unswitch.partial.disable"));
2165 Context, L.getLoopID(), {
"llvm.loop.unswitch.partial"},
2166 {DisableUnswitchMD});
2167 L.setLoopID(NewLoopID);
2168 }
else if (InjectedCondition) {
2170 auto &Context = L.getHeader()->getContext();
2173 MDString::get(Context,
"llvm.loop.unswitch.injection.disable"));
2175 Context, L.getLoopID(), {
"llvm.loop.unswitch.injection"},
2176 {DisableUnswitchMD});
2177 L.setLoopID(NewLoopID);
2179 U.revisitCurrentLoop();
2181 U.markLoopAsDeleted(L, LoopName);
2188 LPMUpdater &LoopUpdater,
bool InsertFreeze,
bool InjectedCondition) {
2195 std::string LoopName(L.getName());
2201 "Can only unswitch switches and conditional branch!");
2205 !PartiallyInvariant);
2208 "Cannot have other invariants with full unswitching!");
2211 "Partial unswitching requires an instruction as the condition!");
2224 if (!FullUnswitch) {
2228 PartiallyInvariant) &&
2229 "Only `or`, `and`, an `select`, partially invariant instructions "
2230 "can combine invariants being unswitched.");
2246 for (
auto Case :
SI->cases())
2247 if (Case.getCaseSuccessor() != RetainedSuccBB)
2248 UnswitchedSuccBBs.
insert(Case.getCaseSuccessor());
2250 assert(!UnswitchedSuccBBs.
count(RetainedSuccBB) &&
2251 "Should not unswitch the same successor we are retaining!");
2260 Loop *ParentL = L.getParentLoop();
2269 Loop *OuterExitL = &L;
2271 L.getUniqueExitBlocks(ExitBlocks);
2272 for (
auto *ExitBB : ExitBlocks) {
2276 if (!NewOuterExitL) {
2278 OuterExitL =
nullptr;
2281 if (NewOuterExitL != OuterExitL && NewOuterExitL->
contains(OuterExitL))
2282 OuterExitL = NewOuterExitL;
2304 if (SuccBB->getUniquePredecessor() ||
2306 return PredBB == ParentBB || DT.
dominates(SuccBB, PredBB);
2309 DominatingSucc[BB] = SuccBB;
2328 for (
auto *SuccBB : UnswitchedSuccBBs) {
2331 L, LoopPH, SplitBB, ExitBlocks, ParentBB, SuccBB, RetainedSuccBB,
2332 DominatingSucc, *VMaps.
back(), DTUpdates, AC, DT, LI, MSSAU, SE);
2337 if (TI.
getMetadata(LLVMContext::MD_make_implicit)) {
2341 TI.
setMetadata(LLVMContext::MD_make_implicit,
nullptr);
2348 TI.
setMetadata(LLVMContext::MD_make_implicit,
nullptr);
2359 NewTI->
insertInto(ParentBB, ParentBB->end());
2382 assert(
SI &&
"Must either be a branch or switch!");
2385 assert(
SI->getDefaultDest() == RetainedSuccBB &&
2386 "Not retaining default successor!");
2387 SI->setDefaultDest(LoopPH);
2388 for (
const auto &Case :
SI->cases())
2389 if (Case.getCaseSuccessor() == RetainedSuccBB)
2390 Case.setSuccessor(LoopPH);
2392 Case.setSuccessor(ClonedPHs.
find(Case.getCaseSuccessor())->second);
2396 SI->getCondition()->getName() +
".fr",
2397 SI->getIterator()));
2418 for (
auto &VMap : VMaps)
2434 "Only one possible unswitched block for a branch!");
2448 "Not retaining default successor!");
2449 for (
const auto &Case : NewSI->
cases())
2450 Case.getCaseSuccessor()->removePredecessor(
2469 assert(BI &&
"Only branches have partial unswitching.");
2471 "Only one possible unswitched block for a branch!");
2475 if (PartiallyInvariant)
2477 *SplitBB, Invariants,
Direction, *ClonedPH, *LoopPH, L, MSSAU);
2480 *SplitBB, Invariants,
Direction, *ClonedPH, *LoopPH,
2490 for (
auto &VMap : VMaps)
2510 for (std::unique_ptr<ValueToValueMapTy> &VMap : VMaps)
2533 assert(DT.
verify(DominatorTree::VerificationLevel::Fast));
2535 if (BI && !PartiallyInvariant) {
2541 "Only one possible unswitched block for a branch!");
2553 bool ReplaceUnswitched =
2554 FullUnswitch || (Invariants.
size() == 1) || PartiallyInvariant;
2562 for (
Value *Invariant : Invariants) {
2564 "Should not be replacing constant values!");
2574 U.set(ContinueReplacement);
2575 else if (ReplaceUnswitched &&
2577 U.set(UnswitchedReplacement);
2594 auto UpdateLoop = [&](
Loop &UpdateL) {
2596 UpdateL.verifyLoop();
2597 for (
Loop *ChildL : UpdateL) {
2598 ChildL->verifyLoop();
2599 assert(ChildL->isRecursivelyLCSSAForm(DT, LI) &&
2600 "Perturbed a child loop's LCSSA form!");
2620 for (
Loop *UpdatedL :
2622 UpdateLoop(*UpdatedL);
2623 if (UpdatedL->isOutermost())
2624 OuterExitL =
nullptr;
2628 if (L.isOutermost())
2629 OuterExitL =
nullptr;
2634 if (OuterExitL != &L)
2635 for (
Loop *OuterL = ParentL; OuterL != OuterExitL;
2637 UpdateLoop(*OuterL);
2650 if (UpdatedL->getParentLoop() == ParentL)
2652 postUnswitch(L, LoopUpdater, LoopName, IsStillLoop, PartiallyInvariant,
2653 InjectedCondition, SibLoops);
2676 auto BBCostIt = BBCostMap.
find(
N.getBlock());
2677 if (BBCostIt == BBCostMap.
end())
2681 auto DTCostIt = DTCostMap.
find(&
N);
2682 if (DTCostIt != DTCostMap.
end())
2683 return DTCostIt->second;
2688 N.begin(),
N.end(), BBCostIt->second,
2690 return Sum + computeDomSubtreeCost(*ChildN, BBCostMap, DTCostMap);
2692 bool Inserted = DTCostMap.
insert({&
N, Cost}).second;
2694 assert(Inserted &&
"Should not insert a node while visiting children!");
2729 SI->getMetadata(LLVMContext::MD_prof), &DTU, &LI);
2731 BasicBlock *ThenBB = CondBr->getSuccessor(0),
2732 *TailBB = CondBr->getSuccessor(1);
2738 Phi->addIncoming(
SI->getTrueValue(), ThenBB);
2739 Phi->addIncoming(
SI->getFalseValue(), HeadBB);
2740 Phi->setDebugLoc(
SI->getDebugLoc());
2741 SI->replaceAllUsesWith(Phi);
2742 SI->eraseFromParent();
2784 GI->
getMetadata(LLVMContext::MD_prof), &DTU, &LI);
2791 GuardedBlock->
setName(
"guarded");
2842 return L.contains(SuccBB);
2844 NumCostMultiplierSkipped++;
2855 auto *ParentL = L.getParentLoop();
2856 int ParentLoopSizeMultiplier = 1;
2858 ParentLoopSizeMultiplier =
2861 int SiblingsCount = (ParentL ? ParentL->getSubLoopsVector().
size()
2862 : std::distance(LI.
begin(), LI.
end()));
2866 int UnswitchedClones = 0;
2867 for (
const auto &Candidate : UnswitchCandidates) {
2870 bool SkipExitingSuccessors = DT.
dominates(CondBlock, Latch);
2876 if (!SkipExitingSuccessors)
2880 int NonExitingSuccessors =
2882 [SkipExitingSuccessors, &L](
const BasicBlock *SuccBB) {
2883 return !SkipExitingSuccessors || L.contains(SuccBB);
2885 UnswitchedClones +=
Log2_32(NonExitingSuccessors);
2893 unsigned ClonesPower =
2897 int SiblingsMultiplier =
2898 std::max((ParentL ? SiblingsCount
2909 CostMultiplier = std::min(SiblingsMultiplier * (1 << ClonesPower),
2913 <<
" (siblings " << SiblingsMultiplier <<
" * parent size "
2914 << ParentLoopSizeMultiplier <<
" * clones "
2915 << (1 << ClonesPower) <<
")"
2916 <<
" for unswitch candidate: " << TI <<
"\n");
2917 return CostMultiplier;
2925 assert(UnswitchCandidates.
empty() &&
"Should be!");
2931 if (L.isLoopInvariant(
Cond)) {
2939 if (!Invariants.
empty())
2940 UnswitchCandidates.
push_back({
I, std::move(Invariants)});
2945 bool CollectGuards =
false;
2948 L.getHeader()->getParent()->getParent(), Intrinsic::experimental_guard);
2949 if (GuardDecl && !GuardDecl->use_empty())
2950 CollectGuards =
true;
2953 for (
auto *BB : L.blocks()) {
2957 for (
auto &
I : *BB) {
2959 auto *
Cond =
SI->getCondition();
2961 if (
Cond->getType()->isIntegerTy(1) && !
SI->getType()->isIntegerTy(1))
2962 AddUnswitchCandidatesForInst(
SI,
Cond);
2963 }
else if (CollectGuards &&
isGuard(&
I)) {
2976 L.isLoopInvariant(
SI->getCondition()) && !BB->getUniqueSuccessor())
2982 if (!BI || !BI->isConditional() ||
2983 BI->getSuccessor(0) == BI->getSuccessor(1))
2986 AddUnswitchCandidatesForInst(BI, BI->getCondition());
2990 !
any_of(UnswitchCandidates, [&L](
auto &TerminatorAndInvariants) {
2991 return TerminatorAndInvariants.TI == L.getHeader()->getTerminator();
2996 dbgs() <<
"simple-loop-unswitch: Found partially invariant condition "
2997 << *
Info->InstToDuplicate[0] <<
"\n");
2998 PartialIVInfo = *
Info;
2999 PartialIVCondBranch = L.getHeader()->getTerminator();
3003 {L.getHeader()->getTerminator(), std::move(ValsToDuplicate)});
3006 return !UnswitchCandidates.
empty();
3021 if (!L.contains(IfTrue)) {
3027 if (L.isLoopInvariant(
LHS)) {
3035 RHS = ConstantInt::get(
3047 if (L.isLoopInvariant(
LHS) || !L.isLoopInvariant(
RHS))
3053 if (!L.contains(IfTrue) || L.contains(IfFalse))
3057 if (L.getHeader() == IfTrue)
3074 assert(Weights.
size() == 2 &&
"Unexpected profile data!");
3076 auto Num = Weights[Idx];
3077 auto Denom = Weights[0] + Weights[1];
3079 if (Denom == 0 || Num > Denom)
3082 if (LikelyTaken > ActualTaken)
3105static NonTrivialUnswitchCandidate
3109 assert(Candidate.hasPendingInjection() &&
"Nothing to inject!");
3110 BasicBlock *Preheader = L.getLoopPreheader();
3111 assert(Preheader &&
"Loop is not in simplified form?");
3113 "Unswitching branch of inner loop!");
3115 auto Pred = Candidate.PendingInjection->Pred;
3116 auto *
LHS = Candidate.PendingInjection->LHS;
3117 auto *
RHS = Candidate.PendingInjection->RHS;
3118 auto *InLoopSucc = Candidate.PendingInjection->InLoopSucc;
3121 auto *OutOfLoopSucc = InLoopSucc == TI->getSuccessor(0) ? TI->getSuccessor(1)
3122 : TI->getSuccessor(0);
3124 assert(L.contains(InLoopSucc) &&
"Not supported yet!");
3125 assert(!L.contains(OutOfLoopSucc) &&
"Not supported yet!");
3126 auto &Ctx = BB->getContext();
3130 if (
LHS->getType() !=
RHS->getType()) {
3131 if (
LHS->getType()->getIntegerBitWidth() <
3132 RHS->getType()->getIntegerBitWidth())
3133 LHS = Builder.CreateZExt(
LHS,
RHS->getType(),
LHS->getName() +
".wide");
3135 RHS = Builder.CreateZExt(
RHS,
LHS->getType(),
RHS->getName() +
".wide");
3139 auto *InjectedCond =
3144 BB->getParent(), InLoopSucc);
3145 Builder.SetInsertPoint(TI);
3147 Builder.CreateCondBr(InjectedCond, InLoopSucc, CheckBlock);
3149 Builder.SetInsertPoint(CheckBlock);
3150 Builder.CreateCondBr(TI->getCondition(), TI->getSuccessor(0),
3151 TI->getSuccessor(1));
3152 TI->eraseFromParent();
3155 for (
auto &
I : *InLoopSucc) {
3159 auto *Inc = PN->getIncomingValueForBlock(BB);
3160 PN->addIncoming(Inc, CheckBlock);
3162 OutOfLoopSucc->replacePhiUsesWith(BB, CheckBlock);
3174 L.addBasicBlockToLoop(CheckBlock, LI);
3186 LLVM_DEBUG(
dbgs() <<
"Injected a new loop-invariant branch " << *InvariantBr
3187 <<
" and considering it for unswitching.");
3188 ++NumInvariantConditionsInjected;
3189 return NonTrivialUnswitchCandidate(InvariantBr, { InjectedCond },
3211 if (Compares.
size() < 2)
3219 InjectedInvariant ToInject(NonStrictPred,
LHS,
RHS, InLoopSucc);
3220 NonTrivialUnswitchCandidate Candidate(Prev->Term, { LHS, RHS },
3221 std::nullopt, std::move(ToInject));
3222 UnswitchCandidates.
push_back(std::move(Candidate));
3252 auto *Latch = L.getLoopLatch();
3256 assert(L.getLoopPreheader() &&
"Must have a preheader!");
3261 for (
auto *DTN = DT.
getNode(Latch); L.contains(DTN->getBlock());
3262 DTN = DTN->getIDom()) {
3265 BasicBlock *IfTrue =
nullptr, *IfFalse =
nullptr;
3266 auto *BB = DTN->getBlock();
3270 auto *Term = BB->getTerminator();
3274 if (!
LHS->getType()->isIntegerTy())
3286 LHS = Zext->getOperand(0);
3287 CandidatesULT[
LHS].push_back(
Desc);
3291 for (
auto &It : CandidatesULT)
3298 if (!L.isSafeToClone())
3300 for (
auto *BB : L.blocks())
3301 for (
auto &
I : *BB) {
3302 if (
I.getType()->isTokenTy() &&
I.isUsedOutsideOfBlock(BB))
3305 assert(!CB->cannotDuplicate() &&
"Checked by L.isSafeToClone().");
3306 if (CB->isConvergent())
3323 L.getUniqueExitBlocks(ExitBlocks);
3328 for (
auto *ExitBB : ExitBlocks) {
3329 auto It = ExitBB->getFirstNonPHIIt();
3331 LLVM_DEBUG(
dbgs() <<
"Cannot unswitch because of cleanuppad/catchswitch "
3359 L.getHeader()->getParent()->hasMinSize()
3363 for (
auto *BB : L.blocks()) {
3365 for (
auto &
I : *BB) {
3370 assert(Cost >= 0 &&
"Must not have negative costs!");
3372 assert(LoopCost >= 0 &&
"Must not have negative loop costs!");
3373 BBCostMap[BB] = Cost;
3406 if (!Visited.
insert(SuccBB).second)
3414 if (!FullUnswitch) {
3418 if (SuccBB == BI.getSuccessor(1))
3421 if (SuccBB == BI.getSuccessor(0))
3424 SuccBB == BI.getSuccessor(0)) ||
3426 SuccBB == BI.getSuccessor(1)))
3434 if (SuccBB->getUniquePredecessor() ||
3436 return PredBB == &BB || DT.
dominates(SuccBB, PredBB);
3439 assert(Cost <= LoopCost &&
3440 "Non-duplicated cost should never exceed total loop cost!");
3449 int SuccessorsCount =
isGuard(&TI) ? 2 : Visited.
size();
3450 assert(SuccessorsCount > 1 &&
3451 "Cannot unswitch a condition without multiple distinct successors!");
3452 return (LoopCost - Cost) * (SuccessorsCount - 1);
3455 std::optional<NonTrivialUnswitchCandidate> Best;
3456 for (
auto &Candidate : UnswitchCandidates) {
3461 !BI || Candidate.hasPendingInjection() ||
3462 (Invariants.
size() == 1 &&
3464 InstructionCost CandidateCost = ComputeUnswitchedCost(TI, FullUnswitch);
3468 int CostMultiplier =
3472 "cost multiplier needs to be in the range of 1..UnswitchThreshold");
3473 CandidateCost *= CostMultiplier;
3475 <<
" (multiplier: " << CostMultiplier <<
")"
3476 <<
" for unswitch candidate: " << TI <<
"\n");
3479 <<
" for unswitch candidate: " << TI <<
"\n");
3482 if (!Best || CandidateCost < Best->Cost) {
3484 Best->Cost = CandidateCost;
3487 assert(Best &&
"Must be!");
3514 Cond, &AC, L.getLoopPreheader()->getTerminator(), &DT);
3528 PartialIVCondBranch, L, LI,
AA, MSSAU);
3531 PartialIVCondBranch, L, DT, LI,
AA,
3534 if (UnswitchCandidates.
empty())
3538 dbgs() <<
"Considering " << UnswitchCandidates.
size()
3539 <<
" non-trivial loop invariant conditions for unswitching.\n");
3542 UnswitchCandidates, L, DT, LI, AC,
TTI, PartialIVInfo);
3544 assert(Best.TI &&
"Failed to find loop unswitch candidate");
3545 assert(Best.Cost &&
"Failed to compute cost");
3548 LLVM_DEBUG(
dbgs() <<
"Cannot unswitch, lowest cost found: " << *Best.Cost
3553 bool InjectedCondition =
false;
3554 if (Best.hasPendingInjection()) {
3556 InjectedCondition =
true;
3558 assert(!Best.hasPendingInjection() &&
3559 "All injections should have been done by now!");
3561 if (Best.TI != PartialIVCondBranch)
3571 SI->getCondition(), &AC, L.getLoopPreheader()->getTerminator(), &DT);
3581 LLVM_DEBUG(
dbgs() <<
" Unswitching non-trivial (cost = " << Best.Cost
3582 <<
") terminator: " << *Best.TI <<
"\n");
3584 LI, AC, SE, MSSAU, LoopUpdater, InsertFreeze,
3616 assert(L.isRecursivelyLCSSAForm(DT, LI) &&
3617 "Loops must be in LCSSA form before unswitching.");
3620 if (!L.isLoopSimplifyForm())
3633 const Function *
F = L.getHeader()->getParent();
3646 bool ContinueWithNonTrivial =
3648 if (!ContinueWithNonTrivial)
3652 if (
F->hasOptSize())
3657 auto IsLoopNestCold = [&](
const Loop *L) {
3663 Parent = Parent->getParentLoop();
3668 while (!Worklist.
empty()) {
3706 Function &
F = *L.getHeader()->getParent();
3709 if (
auto OuterProxy =
3713 LLVM_DEBUG(
dbgs() <<
"Unswitching loop in " <<
F.getName() <<
": " << L
3716 std::optional<MemorySSAUpdater> MSSAU;
3723 &AR.
SE, MSSAU ? &*MSSAU :
nullptr, PSI, AR.
BFI, U))
3742 OS, MapClassName2PassName);
3745 OS << (NonTrivial ?
"" :
"no-") <<
"nontrivial;";
3746 OS << (Trivial ?
"" :
"no-") <<
"trivial";
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Analysis containing CSE Info
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static cl::opt< OutputCostKind > CostKind("cost-kind", cl::desc("Target cost kind"), cl::init(OutputCostKind::RecipThroughput), cl::values(clEnumValN(OutputCostKind::RecipThroughput, "throughput", "Reciprocal throughput"), clEnumValN(OutputCostKind::Latency, "latency", "Instruction latency"), clEnumValN(OutputCostKind::CodeSize, "code-size", "Code size"), clEnumValN(OutputCostKind::SizeAndLatency, "size-latency", "Code size and latency"), clEnumValN(OutputCostKind::All, "all", "Print all cost kinds")))
This file defines the DenseMap class.
This file defines a set of templates that efficiently compute a dominator tree over a generic graph.
Module.h This file contains the declarations for the Module class.
This defines the Use class.
This file defines an InstructionCost class that is used when calculating the cost of an instruction,...
This header provides classes for managing per-loop analyses.
Loop::LoopBounds::Direction Direction
This header provides classes for managing a pipeline of passes over loops in LLVM IR.
This file exposes an interface to building/using memory SSA to walk memory instructions using a use/d...
Contains a collection of routines for determining if a given instruction is guaranteed to execute if ...
uint64_t IntrinsicInst * II
This file contains the declarations for profiling metadata utility functions.
const SmallVectorImpl< MachineOperand > & Cond
Provides some synthesis utilities to produce sequences of values.
This file implements a set that has insertion order iteration characteristics.
static void rewritePHINodesForUnswitchedExitBlock(BasicBlock &UnswitchedBB, BasicBlock &OldExitingBB, BasicBlock &OldPH)
Rewrite the PHI nodes in an unswitched loop exit basic block.
static bool unswitchLoop(Loop &L, DominatorTree &DT, LoopInfo &LI, AssumptionCache &AC, AAResults &AA, TargetTransformInfo &TTI, bool Trivial, bool NonTrivial, ScalarEvolution *SE, MemorySSAUpdater *MSSAU, ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI, LPMUpdater &LoopUpdater)
Unswitch control flow predicated on loop invariant conditions.
static bool unswitchAllTrivialConditions(Loop &L, DominatorTree &DT, LoopInfo &LI, ScalarEvolution *SE, MemorySSAUpdater *MSSAU)
This routine scans the loop to find a branch or switch which occurs before any side effects occur.
static cl::opt< bool > EnableNonTrivialUnswitch("enable-nontrivial-unswitch", cl::init(false), cl::Hidden, cl::desc("Forcibly enables non-trivial loop unswitching rather than " "following the configuration passed into the pass."))
static cl::opt< bool > UnswitchGuards("simple-loop-unswitch-guards", cl::init(true), cl::Hidden, cl::desc("If enabled, simple loop unswitching will also consider " "llvm.experimental.guard intrinsics as unswitch candidates."))
static SmallPtrSet< const BasicBlock *, 16 > recomputeLoopBlockSet(Loop &L, LoopInfo &LI)
Recompute the set of blocks in a loop after unswitching.
static int CalculateUnswitchCostMultiplier(const Instruction &TI, const Loop &L, const LoopInfo &LI, const DominatorTree &DT, ArrayRef< NonTrivialUnswitchCandidate > UnswitchCandidates)
Cost multiplier is a way to limit potentially exponential behavior of loop-unswitch.
static void buildPartialInvariantUnswitchConditionalBranch(BasicBlock &BB, ArrayRef< Value * > ToDuplicate, bool Direction, BasicBlock &UnswitchedSucc, BasicBlock &NormalSucc, Loop &L, MemorySSAUpdater *MSSAU)
Copy a set of loop invariant values, and conditionally branch on them.
static TinyPtrVector< Value * > collectHomogenousInstGraphLoopInvariants(const Loop &L, Instruction &Root, const LoopInfo &LI)
Collect all of the loop invariant input values transitively used by the homogeneous instruction graph...
static void deleteDeadClonedBlocks(Loop &L, ArrayRef< BasicBlock * > ExitBlocks, ArrayRef< std::unique_ptr< ValueToValueMapTy > > VMaps, DominatorTree &DT, MemorySSAUpdater *MSSAU)
void visitDomSubTree(DominatorTree &DT, BasicBlock *BB, CallableT Callable)
Helper to visit a dominator subtree, invoking a callable on each node.
static BranchInst * turnSelectIntoBranch(SelectInst *SI, DominatorTree &DT, LoopInfo &LI, MemorySSAUpdater *MSSAU, AssumptionCache *AC)
Turns a select instruction into implicit control flow branch, making the following replacement:
static bool isSafeForNoNTrivialUnswitching(Loop &L, LoopInfo &LI)
void postUnswitch(Loop &L, LPMUpdater &U, StringRef LoopName, bool CurrentLoopValid, bool PartiallyInvariant, bool InjectedCondition, ArrayRef< Loop * > NewLoops)
static void buildPartialUnswitchConditionalBranch(BasicBlock &BB, ArrayRef< Value * > Invariants, bool Direction, BasicBlock &UnswitchedSucc, BasicBlock &NormalSucc, bool InsertFreeze, const Instruction *I, AssumptionCache *AC, const DominatorTree &DT)
Copy a set of loop invariant values ToDuplicate and insert them at the end of BB and conditionally br...
static cl::opt< int > UnswitchNumInitialUnscaledCandidates("unswitch-num-initial-unscaled-candidates", cl::init(8), cl::Hidden, cl::desc("Number of unswitch candidates that are ignored when calculating " "cost multiplier."))
static bool shouldTryInjectInvariantCondition(const ICmpInst::Predicate Pred, const Value *LHS, const Value *RHS, const BasicBlock *IfTrue, const BasicBlock *IfFalse, const Loop &L)
Returns true, if predicate described by ( Pred, LHS, RHS ) succeeding into blocks ( IfTrue,...
static NonTrivialUnswitchCandidate findBestNonTrivialUnswitchCandidate(ArrayRef< NonTrivialUnswitchCandidate > UnswitchCandidates, const Loop &L, const DominatorTree &DT, const LoopInfo &LI, AssumptionCache &AC, const TargetTransformInfo &TTI, const IVConditionInfo &PartialIVInfo)
static cl::opt< bool > EnableUnswitchCostMultiplier("enable-unswitch-cost-multiplier", cl::init(true), cl::Hidden, cl::desc("Enable unswitch cost multiplier that prohibits exponential " "explosion in nontrivial unswitch."))
static Value * skipTrivialSelect(Value *Cond)
static Loop * getTopMostExitingLoop(const BasicBlock *ExitBB, const LoopInfo &LI)
static bool collectUnswitchCandidatesWithInjections(SmallVectorImpl< NonTrivialUnswitchCandidate > &UnswitchCandidates, IVConditionInfo &PartialIVInfo, Instruction *&PartialIVCondBranch, Loop &L, const DominatorTree &DT, const LoopInfo &LI, AAResults &AA, const MemorySSAUpdater *MSSAU)
Collect unswitch candidates by invariant conditions that are not immediately present in the loop.
static cl::opt< int > UnswitchThreshold("unswitch-threshold", cl::init(50), cl::Hidden, cl::desc("The cost threshold for unswitching a loop."))
static void replaceLoopInvariantUses(const Loop &L, Value *Invariant, Constant &Replacement)
static bool unswitchTrivialBranch(Loop &L, BranchInst &BI, DominatorTree &DT, LoopInfo &LI, ScalarEvolution *SE, MemorySSAUpdater *MSSAU)
Unswitch a trivial branch if the condition is loop invariant.
static bool collectUnswitchCandidates(SmallVectorImpl< NonTrivialUnswitchCandidate > &UnswitchCandidates, IVConditionInfo &PartialIVInfo, Instruction *&PartialIVCondBranch, const Loop &L, const LoopInfo &LI, AAResults &AA, const MemorySSAUpdater *MSSAU)
static cl::opt< bool > InjectInvariantConditions("simple-loop-unswitch-inject-invariant-conditions", cl::Hidden, cl::desc("Whether we should inject new invariants and unswitch them to " "eliminate some existing (non-invariant) conditions."), cl::init(true))
static cl::opt< bool > FreezeLoopUnswitchCond("freeze-loop-unswitch-cond", cl::init(true), cl::Hidden, cl::desc("If enabled, the freeze instruction will be added to condition " "of loop unswitch to prevent miscompilation."))
static InstructionCost computeDomSubtreeCost(DomTreeNode &N, const SmallDenseMap< BasicBlock *, InstructionCost, 4 > &BBCostMap, SmallDenseMap< DomTreeNode *, InstructionCost, 4 > &DTCostMap)
Recursively compute the cost of a dominator subtree based on the per-block cost map provided.
static bool shouldInsertFreeze(Loop &L, Instruction &TI, DominatorTree &DT, AssumptionCache &AC)
static cl::opt< int > UnswitchSiblingsToplevelDiv("unswitch-siblings-toplevel-div", cl::init(2), cl::Hidden, cl::desc("Toplevel siblings divisor for cost multiplier."))
static cl::opt< unsigned > MSSAThreshold("simple-loop-unswitch-memoryssa-threshold", cl::desc("Max number of memory uses to explore during " "partial unswitching analysis"), cl::init(100), cl::Hidden)
static void canonicalizeForInvariantConditionInjection(CmpPredicate &Pred, Value *&LHS, Value *&RHS, BasicBlock *&IfTrue, BasicBlock *&IfFalse, const Loop &L)
Tries to canonicalize condition described by:
static bool areLoopExitPHIsLoopInvariant(const Loop &L, const BasicBlock &ExitingBB, const BasicBlock &ExitBB)
Check that all the LCSSA PHI nodes in the loop exit block have trivial incoming values along this edg...
static void rewritePHINodesForExitAndUnswitchedBlocks(BasicBlock &ExitBB, BasicBlock &UnswitchedBB, BasicBlock &OldExitingBB, BasicBlock &OldPH, bool FullUnswitch)
Rewrite the PHI nodes in the loop exit basic block and the split off unswitched block.
static bool insertCandidatesWithPendingInjections(SmallVectorImpl< NonTrivialUnswitchCandidate > &UnswitchCandidates, Loop &L, ICmpInst::Predicate Pred, ArrayRef< CompareDesc > Compares, const DominatorTree &DT)
Given chain of loop branch conditions looking like: br (Variant < Invariant1) br (Variant < Invariant...
static NonTrivialUnswitchCandidate injectPendingInvariantConditions(NonTrivialUnswitchCandidate Candidate, Loop &L, DominatorTree &DT, LoopInfo &LI, AssumptionCache &AC, MemorySSAUpdater *MSSAU)
Materialize pending invariant condition of the given candidate into IR.
static cl::opt< bool > DropNonTrivialImplicitNullChecks("simple-loop-unswitch-drop-non-trivial-implicit-null-checks", cl::init(false), cl::Hidden, cl::desc("If enabled, drop make.implicit metadata in unswitched implicit " "null checks to save time analyzing if we can keep it."))
static cl::opt< int > UnswitchParentBlocksDiv("unswitch-parent-blocks-div", cl::init(8), cl::Hidden, cl::desc("Outer loop size divisor for cost multiplier."))
static cl::opt< unsigned > InjectInvariantConditionHotnesThreshold("simple-loop-unswitch-inject-invariant-condition-hotness-threshold", cl::Hidden, cl::desc("Only try to inject loop invariant conditions and " "unswitch on them to eliminate branches that are " "not-taken 1/<this option> times or less."), cl::init(16))
static bool unswitchTrivialSwitch(Loop &L, SwitchInst &SI, DominatorTree &DT, LoopInfo &LI, ScalarEvolution *SE, MemorySSAUpdater *MSSAU)
Unswitch a trivial switch if the condition is loop invariant.
static void unswitchNontrivialInvariants(Loop &L, Instruction &TI, ArrayRef< Value * > Invariants, IVConditionInfo &PartialIVInfo, DominatorTree &DT, LoopInfo &LI, AssumptionCache &AC, ScalarEvolution *SE, MemorySSAUpdater *MSSAU, LPMUpdater &LoopUpdater, bool InsertFreeze, bool InjectedCondition)
static bool rebuildLoopAfterUnswitch(Loop &L, ArrayRef< BasicBlock * > ExitBlocks, LoopInfo &LI, SmallVectorImpl< Loop * > &HoistedLoops, ScalarEvolution *SE)
Rebuild a loop after unswitching removes some subset of blocks and edges.
static bool unswitchBestCondition(Loop &L, DominatorTree &DT, LoopInfo &LI, AssumptionCache &AC, AAResults &AA, TargetTransformInfo &TTI, ScalarEvolution *SE, MemorySSAUpdater *MSSAU, LPMUpdater &LoopUpdater)
static BasicBlock * buildClonedLoopBlocks(Loop &L, BasicBlock *LoopPH, BasicBlock *SplitBB, ArrayRef< BasicBlock * > ExitBlocks, BasicBlock *ParentBB, BasicBlock *UnswitchedSuccBB, BasicBlock *ContinueSuccBB, const SmallDenseMap< BasicBlock *, BasicBlock *, 16 > &DominatingSucc, ValueToValueMapTy &VMap, SmallVectorImpl< DominatorTree::UpdateType > &DTUpdates, AssumptionCache &AC, DominatorTree &DT, LoopInfo &LI, MemorySSAUpdater *MSSAU, ScalarEvolution *SE)
Build the cloned blocks for an unswitched copy of the given loop.
static void deleteDeadBlocksFromLoop(Loop &L, SmallVectorImpl< BasicBlock * > &ExitBlocks, DominatorTree &DT, LoopInfo &LI, MemorySSAUpdater *MSSAU, ScalarEvolution *SE, LPMUpdater &LoopUpdater)
bool shouldTryInjectBasingOnMetadata(const BranchInst *BI, const BasicBlock *TakenSucc)
Returns true, if metadata on BI allows us to optimize branching into TakenSucc via injection of invar...
static BranchInst * turnGuardIntoBranch(IntrinsicInst *GI, Loop &L, DominatorTree &DT, LoopInfo &LI, MemorySSAUpdater *MSSAU)
Turns a llvm.experimental.guard intrinsic into implicit control flow branch, making the following rep...
static Loop * cloneLoopNest(Loop &OrigRootL, Loop *RootParentL, const ValueToValueMapTy &VMap, LoopInfo &LI)
Recursively clone the specified loop and all of its children.
static void hoistLoopToNewParent(Loop &L, BasicBlock &Preheader, DominatorTree &DT, LoopInfo &LI, MemorySSAUpdater *MSSAU, ScalarEvolution *SE)
Hoist the current loop up to the innermost loop containing a remaining exit.
static void buildClonedLoops(Loop &OrigL, ArrayRef< BasicBlock * > ExitBlocks, const ValueToValueMapTy &VMap, LoopInfo &LI, SmallVectorImpl< Loop * > &NonChildClonedLoops)
Build the cloned loops of an original loop from unswitching.
This file defines the SmallPtrSet class.
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)
static APInt getSignedMinValue(unsigned numBits)
Gets minimum signed value of APInt for a specific bit width.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
bool empty() const
empty - Check if the array is empty.
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.
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
InstListType::iterator iterator
Instruction iterators...
void moveBefore(BasicBlock *MovePos)
Unlink this basic block from its current function and insert it into the function that MovePos lives ...
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
LLVM_ABI void removePredecessor(BasicBlock *Pred, bool KeepOneInputPHIs=false)
Update PHI nodes in this BasicBlock before removal of predecessor Pred.
BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate IR basic block frequen...
Conditional or Unconditional Branch instruction.
void setCondition(Value *V)
LLVM_ABI void swapSuccessors()
Swap the successors of this branch instruction.
bool isConditional() const
static BranchInst * Create(BasicBlock *IfTrue, InsertPosition InsertBefore=nullptr)
BasicBlock * getSuccessor(unsigned i) const
void setSuccessor(unsigned idx, BasicBlock *NewSucc)
Value * getCondition() const
Value * getArgOperand(unsigned i) const
void setArgOperand(unsigned i, Value *v)
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ ICMP_ULT
unsigned less than
@ ICMP_SGE
signed greater or equal
Predicate getSwappedPredicate() const
For example, EQ->EQ, SLE->SGE, ULT->UGT, OEQ->OEQ, ULE->UGE, OLT->OGT, etc.
static LLVM_ABI CmpInst * Create(OtherOps Op, Predicate Pred, Value *S1, Value *S2, const Twine &Name="", InsertPosition InsertBefore=nullptr)
Construct a compare instruction, given the opcode, the predicate and the two operands.
Predicate getNonStrictPredicate() const
For example, SGT -> SGE, SLT -> SLE, ULT -> ULE, UGT -> UGE.
static LLVM_ABI bool isStrictPredicate(Predicate predicate)
This is a static version that you can use without an instruction available.
Predicate getInversePredicate() const
For example, EQ -> NE, UGT -> ULE, SLT -> SGE, OEQ -> UNE, UGT -> OLE, OLT -> UGE,...
An abstraction over a floating-point predicate, and a pack of an integer predicate with samesign info...
This is the shared class of boolean and integer constants.
static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)
static LLVM_ABI ConstantInt * getFalse(LLVMContext &Context)
This is an important base class in LLVM.
LLVM_ABI bool isOneValue() const
Returns true if the value is one.
static DebugLoc getCompilerGenerated()
static DebugLoc getDropped()
ValueT lookup(const_arg_type_t< KeyT > Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
iterator find(const_arg_type_t< KeyT > Val)
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
bool verify(VerificationLevel VL=VerificationLevel::Full) const
verify - checks if the tree is correct.
void applyUpdates(ArrayRef< UpdateType > Updates)
Inform the dominator tree about a sequence of CFG edge insertions and deletions and perform a batch u...
void insertEdge(NodeT *From, NodeT *To)
Inform the dominator tree about a CFG edge insertion and update the tree.
static constexpr UpdateKind Delete
static constexpr UpdateKind Insert
void deleteEdge(NodeT *From, NodeT *To)
Inform the dominator tree about a CFG edge deletion and update the tree.
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 bool isReachableFromEntry(const Use &U) const
Provide an overload for a Use.
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 ...
This implementation of LoopSafetyInfo use ImplicitControlFlowTracking to give precise answers on "may...
bool isGuaranteedToExecute(const Instruction &Inst, const DominatorTree *DT, const Loop *CurLoop) const override
Returns true if the instruction in a loop is guaranteed to execute at least once (under the assumptio...
void computeLoopSafetyInfo(const Loop *CurLoop) override
Computes safety information for a loop checks loop body & header for the possibility of may throw exc...
bool isRelational() const
Return true if the predicate is relational (not EQ or NE).
Value * CreateFreeze(Value *V, const Twine &Name="")
void SetCurrentDebugLocation(DebugLoc L)
Set location information used by debugging information.
BranchInst * CreateCondBr(Value *Cond, BasicBlock *True, BasicBlock *False, MDNode *BranchWeights=nullptr, MDNode *Unpredictable=nullptr)
Create a conditional 'br Cond, TrueDest, FalseDest' instruction.
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="", bool IsDisjoint=false)
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
LLVM_ABI Instruction * clone() const
Create a copy of 'this' instruction that is identical in all ways except the following:
LLVM_ABI void dropLocation()
Drop the instruction's debug location.
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
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.
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this Instruction.
bool isTerminator() const
LLVM_ABI void setMetadata(unsigned KindID, MDNode *Node)
Set the metadata of the specified kind to the specified node.
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
LLVM_ABI InstListType::iterator insertInto(BasicBlock *ParentBB, InstListType::iterator It)
Inserts an unlinked instruction into ParentBB at position It and returns the iterator of the inserted...
A wrapper class for inspecting calls to intrinsic functions.
This class provides an interface for updating the loop pass manager based on mutations to the loop ne...
void markLoopAsDeleted(Loop &L, llvm::StringRef Name)
Loop passes should use this method to indicate they have deleted a loop from the nest.
bool contains(const LoopT *L) const
Return true if the specified loop is contained within in this loop.
bool isInnermost() const
Return true if the loop does not contain any (natural) loops.
unsigned getNumBlocks() const
Get the number of blocks in this loop in constant time.
BlockT * getHeader() const
void addBasicBlockToLoop(BlockT *NewBB, LoopInfoBase< BlockT, LoopT > &LI)
This method is used by other analyses to update loop information.
void reserveBlocks(unsigned size)
interface to do reserve() for Blocks
iterator_range< block_iterator > blocks() const
void addChildLoop(LoopT *NewChild)
Add the specified loop to be a child of this loop.
BlockT * getLoopPreheader() const
If there is a preheader for this loop, return it.
LoopT * getParentLoop() const
Return the parent loop if it exists or nullptr for top level loops.
bool isLoopExiting(const BlockT *BB) const
True if terminator in the block can branch to another block that is outside of the current loop.
LoopT * removeChildLoop(iterator I)
This removes the specified child from being a subloop of this loop.
Wrapper class to LoopBlocksDFS that provides a standard begin()/end() interface for the DFS reverse p...
void perform(const LoopInfo *LI)
Traverse the loop blocks and store the DFS result.
void verify(const DominatorTreeBase< BlockT, false > &DomTree) const
void addTopLevelLoop(LoopT *New)
This adds the specified loop to the collection of top-level loops.
LoopT * AllocateLoop(ArgsTy &&...Args)
LoopT * removeLoop(iterator I)
This removes the specified top-level loop from this loop info object.
void changeLoopFor(BlockT *BB, LoopT *L)
Change the top-level loop that contains BB to the specified loop.
unsigned getLoopDepth(const BlockT *BB) const
Return the loop nesting level of the specified block.
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
void destroy(LoopT *L)
Destroy a loop that has been removed from the LoopInfo nest.
Represents a single loop in the control flow graph.
StringRef getName() const
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
static LLVM_ABI MDString * get(LLVMContext &Context, StringRef Str)
Represents a read-write access to memory, whether it is a must-alias, or a may-alias.
An analysis that produces MemorySSA for a function.
MemorySSA * getMemorySSA() const
Get handle on MemorySSA.
LLVM_ABI void removeEdge(BasicBlock *From, BasicBlock *To)
Update the MemoryPhi in To following an edge deletion between From and To.
LLVM_ABI void updateForClonedLoop(const LoopBlocksRPO &LoopBlocks, ArrayRef< BasicBlock * > ExitBlocks, const ValueToValueMapTy &VM, bool IgnoreIncomingWithNoClones=false)
Update MemorySSA after a loop was cloned, given the blocks in RPO order, the exit blocks and a 1:1 ma...
LLVM_ABI void removeDuplicatePhiEdgesBetween(const BasicBlock *From, const BasicBlock *To)
Update the MemoryPhi in To to have a single incoming edge from From, following a CFG change that repl...
LLVM_ABI void removeBlocks(const SmallSetVector< BasicBlock *, 8 > &DeadBlocks)
Remove all MemoryAcceses in a set of BasicBlocks about to be deleted.
LLVM_ABI void moveAllAfterSpliceBlocks(BasicBlock *From, BasicBlock *To, Instruction *Start)
From block was spliced into From and To.
LLVM_ABI MemoryAccess * createMemoryAccessInBB(Instruction *I, MemoryAccess *Definition, const BasicBlock *BB, MemorySSA::InsertionPlace Point, bool CreationMustSucceed=true)
Create a MemoryAccess in MemorySSA at a specified point in a block.
LLVM_ABI void applyInsertUpdates(ArrayRef< CFGUpdate > Updates, DominatorTree &DT)
Apply CFG insert updates, analogous with the DT edge updates.
LLVM_ABI void applyUpdates(ArrayRef< CFGUpdate > Updates, DominatorTree &DT, bool UpdateDTFirst=false)
Apply CFG updates, analogous with the DT edge updates.
LLVM_ABI void moveToPlace(MemoryUseOrDef *What, BasicBlock *BB, MemorySSA::InsertionPlace Where)
LLVM_ABI void updateExitBlocksForClonedLoop(ArrayRef< BasicBlock * > ExitBlocks, const ValueToValueMapTy &VMap, DominatorTree &DT)
Update phi nodes in exit block successors following cloning.
Encapsulates MemorySSA, including all data associated with memory accesses.
LLVM_ABI void verifyMemorySSA(VerificationLevel=VerificationLevel::Fast) const
Verify that MemorySSA is self consistent (IE definitions dominate all uses, uses appear in the right ...
MemoryUseOrDef * getMemoryAccess(const Instruction *I) const
Given a memory Mod/Ref'ing instruction, get the MemorySSA access associated with it.
const DefsList * getBlockDefs(const BasicBlock *BB) const
Return the list of MemoryDef's and MemoryPhi's for a given basic block.
A Module instance is used to store all the information related to an LLVM module.
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
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.
An analysis pass based on the new PM to deliver ProfileSummaryInfo.
Analysis providing profile information.
bool hasProfileSummary() const
Returns true if profile summary is available.
bool isColdBlock(const BBType *BB, BFIT *BFI) const
Returns true if BasicBlock BB is considered cold.
The main scalar evolution driver.
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 void forgetTopmostLoop(const Loop *L)
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...
This class represents the LLVM 'select' instruction.
size_type size() const
Determine the number of elements in the SetVector.
size_type count(const key_type &key) const
Count the number of elements of a given key in the SetVector.
iterator begin()
Get an iterator to the beginning of the SetVector.
bool insert(const value_type &X)
Insert a new element into the SetVector.
void printPipeline(raw_ostream &OS, function_ref< StringRef(StringRef)> MapClassName2PassName)
PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM, LoopStandardAnalysisResults &AR, LPMUpdater &U)
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
bool erase(PtrType Ptr)
Remove pointer from the set.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
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.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void reserve(size_type N)
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
A wrapper class to simplify modification of SwitchInst cases along with their prof branch_weights met...
LLVM_ABI void setSuccessorWeight(unsigned idx, CaseWeightOpt W)
LLVM_ABI Instruction::InstListType::iterator eraseFromParent()
Delegate the call to the underlying SwitchInst::eraseFromParent() and mark this object to not touch t...
LLVM_ABI void addCase(ConstantInt *OnVal, BasicBlock *Dest, CaseWeightOpt W)
Delegate the call to the underlying SwitchInst::addCase() and set the specified branch weight for the...
LLVM_ABI CaseWeightOpt getSuccessorWeight(unsigned idx)
std::optional< uint32_t > CaseWeightOpt
LLVM_ABI SwitchInst::CaseIt removeCase(SwitchInst::CaseIt I)
Delegate the call to the underlying SwitchInst::removeCase() and remove correspondent branch weight.
unsigned getSuccessorIndex() const
Returns successor index for current case successor.
BasicBlockT * getCaseSuccessor() const
Resolves successor for current case.
ConstantIntT * getCaseValue() const
Resolves case value for current case.
BasicBlock * getDefaultDest() const
static SwitchInst * Create(Value *Value, BasicBlock *Default, unsigned NumCases, InsertPosition InsertBefore=nullptr)
void setDefaultDest(BasicBlock *DefaultCase)
iterator_range< CaseIt > cases()
Iteration adapter for range-for loops.
TinyPtrVector - This class is specialized for cases where there are normally 0 or 1 element in a vect...
void push_back(EltTy NewVal)
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
A Use represents the edge between a Value definition and its users.
ValueT lookup(const KeyT &Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
size_type count(const KeyT &Val) const
Return 1 if the specified key is in the map, 0 otherwise.
LLVM Value Representation.
LLVM_ABI void setName(const Twine &Name)
Change the name of the value.
LLVM_ABI LLVMContext & getContext() const
All values hold a context through their type.
iterator_range< use_iterator > uses()
An efficient, type-erasing, non-owning reference to a callable.
const ParentTy * getParent() const
self_iterator getIterator()
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Abstract Attribute helper functions.
@ BasicBlock
Various leaf nodes.
LLVM_ABI Function * getDeclarationIfExists(const Module *M, ID id)
Look up the Function declaration of the intrinsic id in the Module M and return it if it exists.
LogicalOp_match< LHS, RHS, Instruction::And > m_LogicalAnd(const LHS &L, const RHS &R)
Matches L && R either in the form of L & R or L ?
bool match(Val *V, const Pattern &P)
cst_pred_ty< is_one > m_One()
Match an integer 1 or a vector with all elements equal to 1.
ThreeOps_match< Cond, LHS, RHS, Instruction::Select > m_Select(const Cond &C, const LHS &L, const RHS &R)
Matches SelectInst.
auto m_LogicalOr()
Matches L || R where L and R are arbitrary values.
brc_match< Cond_t, bind_ty< BasicBlock >, bind_ty< BasicBlock > > m_Br(const Cond_t &C, BasicBlock *&T, BasicBlock *&F)
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
CmpClass_match< LHS, RHS, ICmpInst > m_ICmp(CmpPredicate &Pred, const LHS &L, const RHS &R)
auto m_LogicalAnd()
Matches L && R where L and R are arbitrary values.
LogicalOp_match< LHS, RHS, Instruction::Or > m_LogicalOr(const LHS &L, const RHS &R)
Matches L || R either in the form of L | R or L ?
class_match< BasicBlock > m_BasicBlock()
Match an arbitrary basic block value and ignore it.
is_zero m_Zero()
Match any null constant or a vector with all elements equal to 0.
match_combine_or< LTy, RTy > m_CombineOr(const LTy &L, const RTy &R)
Combine two pattern matchers matching L || R.
initializer< Ty > init(const Ty &Val)
friend class Instruction
Iterator for Instructions in a `BasicBlock.
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
FunctionAddr VTableAddr Value
void stable_sort(R &&Range)
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
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 size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
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...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
auto successors(const MachineBasicBlock *BB)
OuterAnalysisManagerProxy< ModuleAnalysisManager, Function > ModuleAnalysisManagerFunctionProxy
Provide the ModuleAnalysisManager to Function proxy.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
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...
auto cast_or_null(const Y &Val)
LLVM_ABI MDNode * findOptionMDForLoop(const Loop *TheLoop, StringRef Name)
Find string metadata for a loop.
detail::concat_range< ValueT, RangeTs... > concat(RangeTs &&...Ranges)
Returns a concatenated range across two or more ranges.
DomTreeNodeBase< BasicBlock > DomTreeNode
AnalysisManager< Loop, LoopStandardAnalysisResults & > LoopAnalysisManager
The loop analysis manager.
auto dyn_cast_or_null(const Y &Val)
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
bool isGuard(const User *U)
Returns true iff U has semantics of a guard expressed in a form of call of llvm.experimental....
void RemapDbgRecordRange(Module *M, iterator_range< DbgRecordIterator > Range, ValueToValueMapTy &VM, RemapFlags Flags=RF_None, ValueMapTypeRemapper *TypeMapper=nullptr, ValueMaterializer *Materializer=nullptr, const MetadataPredicate *IdentityMD=nullptr)
Remap the Values used in the DbgRecords Range using the value map VM.
auto reverse(ContainerTy &&C)
bool containsIrreducibleCFG(RPOTraversalT &RPOTraversal, const LoopInfoT &LI)
Return true if the control flow in RPOTraversal is irreducible.
detail::zippy< detail::zip_first, T, U, Args... > zip_first(T &&t, U &&u, Args &&...args)
zip iterator that, for the sake of efficiency, assumes the first iteratee to be the shortest.
void sort(IteratorTy Start, IteratorTy End)
@ RF_IgnoreMissingLocals
If this flag is set, the remapper ignores missing function-local entries (Argument,...
@ RF_NoModuleLevelChanges
If this flag is set, the remapper knows that only local values within a function (such as an instruct...
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI bool VerifyLoopInfo
Enable verification of loop info.
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...
OuterAnalysisManagerProxy< FunctionAnalysisManager, Loop, LoopStandardAnalysisResults & > FunctionAnalysisManagerLoopProxy
A proxy from a FunctionAnalysisManager to a Loop.
LLVM_ABI bool VerifyMemorySSA
Enables verification of MemorySSA.
FunctionAddr VTableAddr Next
LLVM_ABI bool formDedicatedExitBlocks(Loop *L, DominatorTree *DT, LoopInfo *LI, MemorySSAUpdater *MSSAU, bool PreserveLCSSA)
Ensure that all exit blocks of the loop are dedicated exits.
void RemapInstruction(Instruction *I, ValueToValueMapTy &VM, RemapFlags Flags=RF_None, ValueMapTypeRemapper *TypeMapper=nullptr, ValueMaterializer *Materializer=nullptr, const MetadataPredicate *IdentityMD=nullptr)
Convert the instruction operands from referencing the current values into those specified by VM.
LLVM_ABI bool isGuaranteedNotToBeUndefOrPoison(const Value *V, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
Return true if this function can prove that V does not have undef bits and is never poison.
ArrayRef(const T &OneElt) -> ArrayRef< T >
ValueMap< const Value *, WeakTrackingVH > ValueToValueMapTy
LLVM_ABI bool extractBranchWeights(const MDNode *ProfileData, SmallVectorImpl< uint32_t > &Weights)
Extract branch weights from MD_prof metadata.
auto count_if(R &&Range, UnaryPredicate P)
Wrapper function around std::count_if to count the number of times an element satisfying a given pred...
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI BasicBlock * SplitBlock(BasicBlock *Old, BasicBlock::iterator SplitPt, DominatorTree *DT, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, const Twine &BBName="", bool Before=false)
Split the specified block at the specified instruction.
LLVM_ABI PreservedAnalyses getLoopPassPreservedAnalyses()
Returns the minimum set of Analyses that all loop passes must preserve.
LLVM_ABI llvm::MDNode * makePostTransformationMetadata(llvm::LLVMContext &Context, MDNode *OrigLoopID, llvm::ArrayRef< llvm::StringRef > RemovePrefixes, llvm::ArrayRef< llvm::MDNode * > AddAttrs)
Create a new LoopID after the loop has been transformed.
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
auto predecessors(const MachineBasicBlock *BB)
bool pred_empty(const BasicBlock *BB)
LLVM_ABI Instruction * SplitBlockAndInsertIfThen(Value *Cond, BasicBlock::iterator SplitBefore, bool Unreachable, MDNode *BranchWeights=nullptr, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, BasicBlock *ThenBlock=nullptr)
Split the containing block at the specified instruction - everything before SplitBefore stays in the ...
auto seq(T Begin, T End)
Iterate over an integral type from Begin up to - but not including - End.
LLVM_ABI BasicBlock * SplitEdge(BasicBlock *From, BasicBlock *To, DominatorTree *DT=nullptr, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, const Twine &BBName="")
Split the edge connecting the specified blocks, and return the newly created basic block between From...
LLVM_ABI std::optional< IVConditionInfo > hasPartialIVCondition(const Loop &L, unsigned MSSAThreshold, const MemorySSA &MSSA, AAResults &AA)
Check if the loop header has a conditional branch that is not loop-invariant, because it involves loa...
LLVM_ABI bool formLCSSA(Loop &L, const DominatorTree &DT, const LoopInfo *LI, ScalarEvolution *SE)
Put loop into LCSSA form.
LLVM_ABI void mapAtomInstance(const DebugLoc &DL, ValueToValueMapTy &VMap)
Mark a cloned instruction as a new instance so that its source loc can be updated when remapped.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
A special type used by analysis passes to provide an address that identifies that particular analysis...
static LLVM_ABI void collectEphemeralValues(const Loop *L, AssumptionCache *AC, SmallPtrSetImpl< const Value * > &EphValues)
Collect a loop's ephemeral values (those used only by an assume or similar intrinsics in the loop).
Struct to hold information about a partially invariant condition.
SmallVector< Instruction * > InstToDuplicate
Instructions that need to be duplicated and checked for the unswitching condition.
Constant * KnownValue
Constant to indicate for which value the condition is invariant.
Incoming for lane maks phi as machine instruction, incoming register Reg and incoming block Block are...
The adaptor from a function pass to a loop pass computes these analyses and makes them available to t...
TargetTransformInfo & TTI
A CRTP mix-in to automatically provide informational APIs needed for passes.