36#define DEBUG_TYPE "loop-simplifycfg"
39 "Number of terminators folded to unconditional branches");
41 "Number of loop blocks deleted");
43 "Number of loop exiting edges deleted");
51 if (BI->getSuccessor(0) == BI->getSuccessor(1))
52 return BI->getSuccessor(0);
56 return Cond->isZero() ? BI->getSuccessor(1) : BI->getSuccessor(0);
63 for (
auto Case :
SI->cases())
64 if (Case.getCaseValue() == CI)
65 return Case.getCaseSuccessor();
66 return SI->getDefaultDest();
74 Loop *LastLoop =
nullptr) {
76 "First loop is supposed to be inside of last loop!");
77 for (
Loop *Current = FirstLoop; Current != LastLoop;
79 Current->removeBlockFromLoop(BB);
86 Loop *Innermost =
nullptr;
89 while (BBL && !BBL->
contains(L.getHeader()))
104class ConstantTerminatorFoldingImpl {
110 MemorySSAUpdater *MSSAU;
116 bool HasIrreducibleCFG =
false;
125 bool DeleteCurrentLoop =
false;
127 bool HasIndirectEntry =
false;
131 SmallPtrSet<BasicBlock *, 8> LiveLoopBlocks;
134 SmallVector<BasicBlock *, 8> DeadLoopBlocks;
137 SmallPtrSet<BasicBlock *, 8> LiveExitBlocks;
140 SmallVector<BasicBlock *, 8> DeadExitBlocks;
142 SmallPtrSet<BasicBlock *, 8> BlocksInLoopAfterFolding;
146 SmallVector<BasicBlock *, 8> FoldCandidates;
149 dbgs() <<
"Constant terminator folding for loop " << L <<
"\n";
150 dbgs() <<
"After terminator constant-folding, the loop will";
151 if (!DeleteCurrentLoop)
153 dbgs() <<
" be destroyed\n";
154 auto PrintOutVector = [&](
const char *Message,
155 const SmallVectorImpl<BasicBlock *> &S) {
156 dbgs() << Message <<
"\n";
157 for (
const BasicBlock *BB : S)
158 dbgs() <<
"\t" << BB->getName() <<
"\n";
160 auto PrintOutSet = [&](
const char *Message,
161 const SmallPtrSetImpl<BasicBlock *> &S) {
162 dbgs() << Message <<
"\n";
163 for (
const BasicBlock *BB : S)
164 dbgs() <<
"\t" << BB->getName() <<
"\n";
166 PrintOutVector(
"Blocks in which we can constant-fold terminator:",
168 PrintOutSet(
"Live blocks from the original loop:", LiveLoopBlocks);
169 PrintOutVector(
"Dead blocks from the original loop:", DeadLoopBlocks);
170 PrintOutSet(
"Live exit blocks:", LiveExitBlocks);
171 PrintOutVector(
"Dead exit blocks:", DeadExitBlocks);
172 if (!DeleteCurrentLoop)
173 PrintOutSet(
"The following blocks will still be part of the loop:",
174 BlocksInLoopAfterFolding);
178 bool hasIrreducibleCFG(LoopBlocksDFS &DFS) {
179 assert(DFS.isComplete() &&
"DFS is expected to be finished");
181 DenseMap<const BasicBlock *, unsigned> RPO;
182 unsigned Current = 0;
183 for (
auto I = DFS.beginRPO(),
E = DFS.endRPO();
I !=
E; ++
I)
186 for (
auto I = DFS.beginRPO(),
E = DFS.endRPO();
I !=
E; ++
I) {
189 if (L.contains(Succ) && !LI.isLoopHeader(Succ) && RPO[BB] > RPO[Succ])
202 assert(DFS.isComplete() &&
"DFS is expected to be finished");
211 if (hasIrreducibleCFG(DFS)) {
212 HasIrreducibleCFG =
true;
219 if (!L.getLoopPreheader()) {
221 [&](BasicBlock *Pred) {
222 return isa<IndirectBrInst>(Pred->getTerminator());
224 "Loop should have preheader if it is not entered indirectly");
225 HasIndirectEntry =
true;
230 LiveLoopBlocks.insert(L.getHeader());
231 for (
auto I = DFS.beginRPO(),
E = DFS.endRPO();
I !=
E; ++
I) {
235 if (!LiveLoopBlocks.count(BB)) {
236 DeadLoopBlocks.push_back(BB);
246 bool TakeFoldCandidate = TheOnlySucc && LI.getLoopFor(BB) == &L;
247 if (TakeFoldCandidate)
248 FoldCandidates.push_back(BB);
252 if (!TakeFoldCandidate || TheOnlySucc == Succ) {
253 if (L.contains(Succ))
254 LiveLoopBlocks.insert(Succ);
256 LiveExitBlocks.insert(Succ);
262 assert(L.getNumBlocks() == LiveLoopBlocks.size() + DeadLoopBlocks.size() &&
263 "Malformed block sets?");
268 SmallVector<BasicBlock *, 8> ExitBlocks;
269 L.getExitBlocks(ExitBlocks);
270 SmallPtrSet<BasicBlock *, 8> UniqueDeadExits;
271 for (
auto *ExitBlock : ExitBlocks)
272 if (!LiveExitBlocks.count(ExitBlock) &&
273 UniqueDeadExits.
insert(ExitBlock).second &&
275 [
this](BasicBlock *Pred) {
return L.contains(Pred); }))
276 DeadExitBlocks.push_back(ExitBlock);
281 if (!LiveLoopBlocks.count(From))
284 return !TheOnlySucc || TheOnlySucc == To || LI.getLoopFor(From) != &L;
288 DeleteCurrentLoop = !IsEdgeLive(L.getLoopLatch(), L.getHeader());
292 if (DeleteCurrentLoop)
297 BlocksInLoopAfterFolding.insert(L.getLoopLatch());
304 return BlocksInLoopAfterFolding.count(Succ) && IsEdgeLive(BB, Succ);
307 for (
auto I = DFS.beginPostorder(),
E = DFS.endPostorder();
I !=
E; ++
I) {
309 if (BlockIsInLoop(BB))
310 BlocksInLoopAfterFolding.insert(BB);
313 assert(BlocksInLoopAfterFolding.count(L.getHeader()) &&
314 "Header not in loop?");
315 assert(BlocksInLoopAfterFolding.size() <= LiveLoopBlocks.size() &&
316 "All blocks that stay in loop should be live!");
354 void handleDeadExits() {
356 if (DeadExitBlocks.empty())
366 SwitchInst *DummySwitch =
367 Builder.CreateSwitch(Builder.getInt32(0), NewPreheader);
370 unsigned DummyIdx = 1;
371 for (BasicBlock *BB : DeadExitBlocks) {
374 SmallVector<Instruction *, 4> DeadInstructions(
378 DeadInstructions.emplace_back(LandingPad);
380 for (Instruction *
I : DeadInstructions) {
383 I->eraseFromParent();
386 assert(DummyIdx != 0 &&
"Too many dead exits!");
387 DummySwitch->
addCase(Builder.getInt32(DummyIdx++), BB);
388 DTUpdates.push_back({DominatorTree::Insert, Preheader, BB});
389 ++NumLoopExitsDeleted;
396 if (DummySwitch->
getParent()->getParent()->hasProfileData()) {
397 SmallVector<uint32_t> DummyBranchWeights(1 + DummySwitch->
getNumCases());
399 DummyBranchWeights[0] = 1;
403 assert(L.getLoopPreheader() == NewPreheader &&
"Malformed CFG?");
404 if (
Loop *OuterLoop = LI.getLoopFor(Preheader)) {
413 if (StillReachable != OuterLoop) {
414 LI.changeLoopFor(NewPreheader, StillReachable);
416 for (
auto *BB : L.blocks())
418 OuterLoop->removeChildLoop(&L);
422 LI.addTopLevelLoop(&L);
427 Loop *FixLCSSALoop = OuterLoop;
430 assert(FixLCSSALoop &&
"Should be a loop!");
433 MSSAU->applyUpdates(DTUpdates, DT,
true);
435 DTU.applyUpdates(DTUpdates);
438 SE.forgetBlockAndLoopDispositions();
444 MSSAU->applyUpdates(DTUpdates, DT,
true);
447 MSSAU->getMemorySSA()->verifyMemorySSA();
453 void deleteDeadLoopBlocks() {
455 SmallSetVector<BasicBlock *, 8> DeadLoopBlocksSet(DeadLoopBlocks.begin(),
456 DeadLoopBlocks.end());
457 MSSAU->removeBlocks(DeadLoopBlocksSet);
466 for (
auto *BB : DeadLoopBlocks)
467 if (LI.isLoopHeader(BB)) {
468 assert(LI.getLoopFor(BB) != &L &&
"Attempt to remove current loop!");
469 Loop *
DL = LI.getLoopFor(BB);
470 if (!
DL->isOutermost()) {
471 for (
auto *PL =
DL->getParentLoop(); PL; PL =
PL->getParentLoop())
472 for (
auto *BB :
DL->getBlocks())
473 PL->removeBlockFromLoop(BB);
474 DL->getParentLoop()->removeChildLoop(
DL);
475 LI.addTopLevelLoop(
DL);
480 for (
auto *BB : DeadLoopBlocks) {
481 assert(BB != L.getHeader() &&
482 "Header of the current loop cannot be dead!");
489 DTU.applyUpdates(DTUpdates);
491 for (
auto *BB : DeadLoopBlocks)
494 NumLoopBlocksDeleted += DeadLoopBlocks.size();
499 void foldTerminators() {
500 for (BasicBlock *BB : FoldCandidates) {
501 assert(LI.getLoopFor(BB) == &L &&
"Should be a loop block!");
503 assert(TheOnlySucc &&
"Should have one live successor!");
506 <<
" with an unconditional branch to the block "
507 << TheOnlySucc->
getName() <<
"\n");
509 SmallPtrSet<BasicBlock *, 2> DeadSuccessors;
511 unsigned TheOnlySuccDuplicates = 0;
513 if (Succ != TheOnlySucc) {
514 DeadSuccessors.
insert(Succ);
517 bool PreserveLCSSAPhi = !L.contains(Succ);
520 MSSAU->removeEdge(BB, Succ);
522 ++TheOnlySuccDuplicates;
524 assert(TheOnlySuccDuplicates > 0 &&
"Should be!");
528 bool PreserveLCSSAPhi = !L.contains(TheOnlySucc);
529 for (
unsigned Dup = 1; Dup < TheOnlySuccDuplicates; ++Dup)
531 if (MSSAU && TheOnlySuccDuplicates > 1)
532 MSSAU->removeDuplicatePhiEdgesBetween(BB, TheOnlySucc);
536 Builder.CreateBr(TheOnlySucc);
537 Term->eraseFromParent();
539 for (
auto *DeadSucc : DeadSuccessors)
540 DTUpdates.push_back({DominatorTree::Delete, BB, DeadSucc});
542 ++NumTerminatorsFolded;
547 ConstantTerminatorFoldingImpl(
Loop &L, LoopInfo &LI, DominatorTree &DT,
549 MemorySSAUpdater *MSSAU)
550 : L(L), LI(LI), DT(DT), SE(SE), MSSAU(MSSAU), DFS(&L),
551 DTU(DT, DomTreeUpdater::UpdateStrategy::Eager) {}
553 assert(L.getLoopLatch() &&
"Should be single latch!");
561 LLVM_DEBUG(
dbgs() <<
"In function " << Header->getParent()->getName()
564 if (HasIrreducibleCFG) {
565 LLVM_DEBUG(
dbgs() <<
"Loops with irreducible CFG are not supported!\n");
569 if (HasIndirectEntry) {
570 LLVM_DEBUG(
dbgs() <<
"Loops which can be entered indirectly are not"
576 if (FoldCandidates.empty()) {
578 dbgs() <<
"No constant terminator folding candidates found in loop "
579 << Header->getName() <<
"\n");
584 if (DeleteCurrentLoop) {
587 <<
"Give up constant terminator folding in loop " << Header->getName()
588 <<
": we don't currently support deletion of the current loop.\n");
594 if (BlocksInLoopAfterFolding.size() + DeadLoopBlocks.size() !=
597 dbgs() <<
"Give up constant terminator folding in loop "
598 << Header->getName() <<
": we don't currently"
599 " support blocks that are not dead, but will stop "
600 "being a part of the loop after constant-folding.\n");
607 if (!DeadExitBlocks.empty() && !L.isLCSSAForm(DT,
false)) {
608 assert(L.isLCSSAForm(DT,
true) &&
609 "LCSSA broken not by tokens?");
610 LLVM_DEBUG(
dbgs() <<
"Give up constant terminator folding in loop "
612 <<
": tokens uses potentially break LCSSA form.\n");
616 SE.forgetTopmostLoop(&L);
621 <<
" terminators in loop " << Header->getName() <<
"\n");
623 if (!DeadLoopBlocks.empty())
624 SE.forgetBlockAndLoopDispositions();
630 if (!DeadLoopBlocks.empty()) {
632 <<
" dead blocks in loop " << Header->getName() <<
"\n");
633 deleteDeadLoopBlocks();
636 DTU.applyUpdates(DTUpdates);
641 MSSAU->getMemorySSA()->verifyMemorySSA();
645#if defined(EXPENSIVE_CHECKS)
646 assert(DT.verify(DominatorTree::VerificationLevel::Full) &&
647 "DT broken after transform!");
649 assert(DT.verify(DominatorTree::VerificationLevel::Fast) &&
650 "DT broken after transform!");
652 assert(DT.isReachableFromEntry(Header));
659 bool foldingBreaksCurrentLoop()
const {
660 return DeleteCurrentLoop;
670 bool &IsLoopDeleted) {
671 if (!ScalarOptions::Global.enable_loop_simplifycfg_term_folding)
676 if (!L.getLoopLatch())
679 ConstantTerminatorFoldingImpl
BranchFolder(L, LI, DT, SE, MSSAU);
694 for (
auto &
Block : Blocks) {
702 if (!Pred || !Pred->getSingleSuccessor() || LI.
getLoopFor(Pred) != &L)
722 bool &IsLoopDeleted) {
743 std::optional<MemorySSAUpdater> MSSAU;
746 bool DeleteCurrentLoop =
false;
751 if (DeleteCurrentLoop)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This header provides classes for managing a pipeline of passes over loops in LLVM IR.
static BasicBlock * getOnlyLiveSuccessor(BasicBlock *BB)
If BB is a switch or a conditional branch, but only one of its successors can be reached from this bl...
static bool constantFoldTerminators(Loop &L, DominatorTree &DT, LoopInfo &LI, ScalarEvolution &SE, MemorySSAUpdater *MSSAU, bool &IsLoopDeleted)
Turn branches and switches with known constant conditions into unconditional branches.
static Loop * getInnermostLoopFor(SmallPtrSetImpl< BasicBlock * > &BBs, Loop &L, LoopInfo &LI)
Find innermost loop that contains at least one block from BBs and contains the header of loop L.
static bool mergeBlocksIntoPredecessors(Loop &L, DominatorTree &DT, LoopInfo &LI, MemorySSAUpdater *MSSAU, ScalarEvolution &SE)
static bool simplifyLoopCFG(Loop &L, DominatorTree &DT, LoopInfo &LI, ScalarEvolution &SE, MemorySSAUpdater *MSSAU, bool &IsLoopDeleted)
static void removeBlockFromLoops(BasicBlock *BB, Loop *FirstLoop, Loop *LastLoop=nullptr)
Removes BB from all loops from [FirstLoop, LastLoop) in parent chain.
This file exposes an interface to building/using memory SSA to walk memory instructions using a use/d...
This file contains the declarations for profiling metadata utility functions.
const SmallVectorImpl< MachineOperand > & Cond
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)
LLVM Basic Block Representation.
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.
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.
Conditional Branch instruction.
This is the shared class of boolean and integer constants.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
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 this loop.
BlockT * getHeader() const
unsigned getLoopDepth() const
Return the nesting level of this loop.
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.
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
LLVM_ABI PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM, LoopStandardAnalysisResults &AR, LPMUpdater &U)
Represents a single loop in the control flow graph.
LLVM_ABI instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
An analysis that produces MemorySSA for a function.
MemorySSA * getMemorySSA() const
Get handle on MemorySSA.
LLVM_ABI void verifyMemorySSA(VerificationLevel=VerificationLevel::Fast) const
Verify that MemorySSA is self consistent (IE definitions dominate all uses, uses appear in the right ...
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.
The main scalar evolution driver.
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.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
LLVM_ABI void addCase(ConstantInt *OnVal, BasicBlock *Dest)
Add an entry to the switch instruction.
unsigned getNumCases() const
Return the number of 'cases' in this switch instruction, excluding the default case.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
const ParentTy * getParent() const
@ BasicBlock
Various leaf nodes.
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the module M.
friend class Instruction
Iterator for Instructions in a `BasicBlock.
This is an optimization pass for GlobalISel generic memory operations.
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI void detachDeadBlocks(ArrayRef< BasicBlock * > BBs, SmallVectorImpl< DominatorTree::UpdateType > *Updates, bool KeepOneInputPHIs=false)
Replace contents of every block in BBs with single unreachable instruction.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
auto successors(const MachineBasicBlock *BB)
LLVM_ABI bool formLCSSARecursively(Loop &L, const DominatorTree &DT, const LoopInfo *LI, ScalarEvolution *SE)
Put a loop nest into LCSSA form.
auto cast_or_null(const Y &Val)
LLVM_ABI void setBranchWeights(Instruction &I, ArrayRef< uint32_t > Weights, bool IsExpected, bool ElideAllZero=false)
Create a new branch_weights metadata node and add or overwrite a prof metadata reference to instructi...
AnalysisManager< Loop, LoopStandardAnalysisResults & > LoopAnalysisManager
The loop analysis manager.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
IRBuilder(LLVMContext &, FolderTy, InserterTy) -> IRBuilder< FolderTy, InserterTy >
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
LLVM_ABI bool VerifyMemorySSA
Enables verification of MemorySSA.
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.
LLVM_ABI BasicBlock * SplitBlock(BasicBlock *Old, BasicBlock::iterator SplitPt, DominatorTree *DT, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, const Twine &BBName="")
Split the specified block at the specified instruction.
LLVM_ABI PreservedAnalyses getLoopPassPreservedAnalyses()
Returns the minimum set of Analyses that all loop passes must preserve.
auto predecessors(const MachineBasicBlock *BB)
iterator_range< pointer_iterator< WrappedIteratorT > > make_pointer_range(RangeT &&Range)
The adaptor from a function pass to a loop pass computes these analyses and makes them available to t...