35#define DEBUG_TYPE "loop-simplifycfg"
41 "Number of terminators folded to unconditional branches");
43 "Number of loop blocks deleted");
45 "Number of loop exiting edges deleted");
52 if (
BranchInst *BI = dyn_cast<BranchInst>(TI)) {
53 if (BI->isUnconditional())
55 if (BI->getSuccessor(0) == BI->getSuccessor(1))
60 return Cond->isZero() ? BI->getSuccessor(1) : BI->getSuccessor(0);
63 if (
SwitchInst *SI = dyn_cast<SwitchInst>(TI)) {
64 auto *CI = dyn_cast<ConstantInt>(SI->getCondition());
67 for (
auto Case : SI->cases())
68 if (Case.getCaseValue() == CI)
69 return Case.getCaseSuccessor();
70 return SI->getDefaultDest();
78 Loop *LastLoop =
nullptr) {
80 "First loop is supposed to be inside of last loop!");
82 for (
Loop *Current = FirstLoop; Current != LastLoop;
84 Current->removeBlockFromLoop(BB);
91 Loop *Innermost =
nullptr;
94 while (BBL && !BBL->
contains(L.getHeader()))
109class ConstantTerminatorFoldingImpl {
121 bool HasIrreducibleCFG =
false;
130 bool DeleteCurrentLoop =
false;
152 dbgs() <<
"Constant terminator folding for loop " <<
L <<
"\n";
153 dbgs() <<
"After terminator constant-folding, the loop will";
154 if (!DeleteCurrentLoop)
156 dbgs() <<
" be destroyed\n";
157 auto PrintOutVector = [&](
const char *Message,
159 dbgs() << Message <<
"\n";
161 dbgs() <<
"\t" << BB->getName() <<
"\n";
163 auto PrintOutSet = [&](
const char *Message,
165 dbgs() << Message <<
"\n";
167 dbgs() <<
"\t" << BB->getName() <<
"\n";
169 PrintOutVector(
"Blocks in which we can constant-fold terminator:",
171 PrintOutSet(
"Live blocks from the original loop:", LiveLoopBlocks);
172 PrintOutVector(
"Dead blocks from the original loop:", DeadLoopBlocks);
173 PrintOutSet(
"Live exit blocks:", LiveExitBlocks);
174 PrintOutVector(
"Dead exit blocks:", DeadExitBlocks);
175 if (!DeleteCurrentLoop)
176 PrintOutSet(
"The following blocks will still be part of the loop:",
177 BlocksInLoopAfterFolding);
185 unsigned Current = 0;
192 if (
L.contains(Succ) && !LI.
isLoopHeader(Succ) && RPO[BB] > RPO[Succ])
214 if (hasIrreducibleCFG(DFS)) {
215 HasIrreducibleCFG =
true;
220 LiveLoopBlocks.
insert(
L.getHeader());
225 if (!LiveLoopBlocks.
count(BB)) {
236 bool TakeFoldCandidate = TheOnlySucc && LI.
getLoopFor(BB) == &
L;
237 if (TakeFoldCandidate)
242 if (!TakeFoldCandidate || TheOnlySucc == Succ) {
243 if (
L.contains(Succ))
244 LiveLoopBlocks.
insert(Succ);
246 LiveExitBlocks.
insert(Succ);
252 assert(
L.getNumBlocks() == LiveLoopBlocks.
size() + DeadLoopBlocks.
size() &&
253 "Malformed block sets?");
259 L.getExitBlocks(ExitBlocks);
261 for (
auto *ExitBlock : ExitBlocks)
262 if (!LiveExitBlocks.
count(ExitBlock) &&
263 UniqueDeadExits.
insert(ExitBlock).second &&
265 [
this](
BasicBlock *Pred) {
return L.contains(Pred); }))
278 DeleteCurrentLoop = !IsEdgeLive(
L.getLoopLatch(),
L.getHeader());
282 if (DeleteCurrentLoop)
287 BlocksInLoopAfterFolding.
insert(
L.getLoopLatch());
294 return BlocksInLoopAfterFolding.
count(Succ) && IsEdgeLive(BB, Succ);
299 if (BlockIsInLoop(BB))
300 BlocksInLoopAfterFolding.
insert(BB);
304 "Header not in loop?");
305 assert(BlocksInLoopAfterFolding.
size() <= LiveLoopBlocks.
size() &&
306 "All blocks that stay in loop should be live!");
344 void handleDeadExits() {
346 if (DeadExitBlocks.
empty())
357 Builder.CreateSwitch(Builder.getInt32(0), NewPreheader);
360 unsigned DummyIdx = 1;
365 for (
auto &PN : BB->
phis())
368 if (
auto *LandingPad = dyn_cast<LandingPadInst>(BB->
getFirstNonPHI()))
374 I->eraseFromParent();
377 assert(DummyIdx != 0 &&
"Too many dead exits!");
378 DummySwitch->
addCase(Builder.getInt32(DummyIdx++), BB);
379 DTUpdates.
push_back({DominatorTree::Insert, Preheader, BB});
380 ++NumLoopExitsDeleted;
383 assert(
L.getLoopPreheader() == NewPreheader &&
"Malformed CFG?");
393 if (StillReachable != OuterLoop) {
396 for (
auto *BB :
L.blocks())
398 OuterLoop->removeChildLoop(&L);
407 Loop *FixLCSSALoop = OuterLoop;
410 assert(FixLCSSALoop &&
"Should be a loop!");
433 void deleteDeadLoopBlocks() {
436 DeadLoopBlocks.
end());
446 for (
auto *BB : DeadLoopBlocks)
450 if (!
DL->isOutermost()) {
451 for (
auto *PL =
DL->getParentLoop(); PL; PL =
PL->getParentLoop())
452 for (
auto *BB :
DL->getBlocks())
453 PL->removeBlockFromLoop(BB);
454 DL->getParentLoop()->removeChildLoop(
DL);
460 for (
auto *BB : DeadLoopBlocks) {
462 "Header of the current loop cannot be dead!");
471 for (
auto *BB : DeadLoopBlocks)
474 NumLoopBlocksDeleted += DeadLoopBlocks.size();
479 void foldTerminators() {
483 assert(TheOnlySucc &&
"Should have one live successor!");
486 <<
" with an unconditional branch to the block "
487 << TheOnlySucc->
getName() <<
"\n");
491 unsigned TheOnlySuccDuplicates = 0;
493 if (Succ != TheOnlySucc) {
494 DeadSuccessors.
insert(Succ);
497 bool PreserveLCSSAPhi = !
L.contains(Succ);
502 ++TheOnlySuccDuplicates;
504 assert(TheOnlySuccDuplicates > 0 &&
"Should be!");
508 bool PreserveLCSSAPhi = !
L.contains(TheOnlySucc);
509 for (
unsigned Dup = 1; Dup < TheOnlySuccDuplicates; ++Dup)
511 if (MSSAU && TheOnlySuccDuplicates > 1)
516 Builder.SetInsertPoint(Term);
517 Builder.CreateBr(TheOnlySucc);
518 Term->eraseFromParent();
520 for (
auto *DeadSucc : DeadSuccessors)
521 DTUpdates.
push_back({DominatorTree::Delete, BB, DeadSucc});
523 ++NumTerminatorsFolded;
531 :
L(
L), LI(LI), DT(DT), SE(SE), MSSAU(MSSAU), DFS(&
L),
534 assert(
L.getLoopLatch() &&
"Should be single latch!");
542 LLVM_DEBUG(
dbgs() <<
"In function " << Header->getParent()->getName()
545 if (HasIrreducibleCFG) {
546 LLVM_DEBUG(
dbgs() <<
"Loops with irreducible CFG are not supported!\n");
551 if (FoldCandidates.empty()) {
553 dbgs() <<
"No constant terminator folding candidates found in loop "
554 << Header->getName() <<
"\n");
559 if (DeleteCurrentLoop) {
562 <<
"Give up constant terminator folding in loop " << Header->getName()
563 <<
": we don't currently support deletion of the current loop.\n");
569 if (BlocksInLoopAfterFolding.
size() + DeadLoopBlocks.size() !=
572 dbgs() <<
"Give up constant terminator folding in loop "
573 << Header->getName() <<
": we don't currently"
574 " support blocks that are not dead, but will stop "
575 "being a part of the loop after constant-folding.\n");
582 if (!DeadExitBlocks.empty() && !
L.isLCSSAForm(DT,
false)) {
583 assert(
L.isLCSSAForm(DT,
true) &&
584 "LCSSA broken not by tokens?");
585 LLVM_DEBUG(
dbgs() <<
"Give up constant terminator folding in loop "
587 <<
": tokens uses potentially break LCSSA form.\n");
596 <<
" terminators in loop " << Header->getName() <<
"\n");
598 if (!DeadLoopBlocks.empty())
605 if (!DeadLoopBlocks.empty()) {
607 <<
" dead blocks in loop " << Header->getName() <<
"\n");
608 deleteDeadLoopBlocks();
620#if defined(EXPENSIVE_CHECKS)
621 assert(DT.
verify(DominatorTree::VerificationLevel::Full) &&
622 "DT broken after transform!");
624 assert(DT.
verify(DominatorTree::VerificationLevel::Fast) &&
625 "DT broken after transform!");
634 bool foldingBreaksCurrentLoop()
const {
635 return DeleteCurrentLoop;
645 bool &IsLoopDeleted) {
651 if (!L.getLoopLatch())
654 ConstantTerminatorFoldingImpl
BranchFolder(L, LI, DT, SE, MSSAU);
656 IsLoopDeleted = Changed &&
BranchFolder.foldingBreaksCurrentLoop();
663 bool Changed =
false;
697 bool &IsLoopDeleted) {
698 bool Changed =
false;
718 std::optional<MemorySSAUpdater> MSSAU;
721 bool DeleteCurrentLoop =
false;
726 if (DeleteCurrentLoop)
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
BlockVerifier::State From
DenseMap< Block *, BlockRelaxAux > Blocks
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 cl::opt< bool > EnableTermFolding("enable-loop-simplifycfg-term-folding", cl::init(true))
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...
const SmallVectorImpl< MachineOperand > & Cond
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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)
A container for analyses that lazily runs them and caches their results.
LLVM Basic Block Representation.
iterator_range< const_phi_iterator > phis() const
Returns a range that iterates over the phis in the basic block.
const Instruction * getFirstNonPHI() const
Returns a pointer to the first instruction in this block that is not a PHINode instruction.
const BasicBlock * getSinglePredecessor() const
Return the predecessor of this block if it has a single predecessor block.
const BasicBlock * getSingleSuccessor() const
Return the successor of this block if it has a single successor.
LLVMContext & getContext() const
Get the context in which this basic block 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...
void removePredecessor(BasicBlock *Pred, bool KeepOneInputPHIs=false)
Update PHI nodes in this BasicBlock before removal of predecessor Pred.
Conditional or Unconditional Branch instruction.
This is the shared class of boolean and integer constants.
void deleteBB(BasicBlock *DelBB)
Delete DelBB.
bool verify(VerificationLevel VL=VerificationLevel::Full) const
verify - checks if the tree is correct.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
bool isReachableFromEntry(const Use &U) const
Provide an overload for a Use.
void applyUpdates(ArrayRef< typename DomTreeT::UpdateType > Updates)
Submit updates to all available trees.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
BasicBlock * getSuccessor(unsigned Idx) const LLVM_READONLY
Return the specified successor. This instruction must be a terminator.
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.
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.
Store the result of a depth first search within basic blocks contained by a single loop.
RPOIterator beginRPO() const
Reverse iterate over the cached postorder blocks.
bool isComplete() const
Return true if postorder numbers are assigned to all loop blocks.
POIterator beginPostorder() const
Iterate over the cached postorder blocks.
POIterator endPostorder() const
void perform(const LoopInfo *LI)
Traverse the loop blocks and store the DFS result.
RPOIterator endRPO() const
void verify(const DominatorTreeBase< BlockT, false > &DomTree) const
void addTopLevelLoop(LoopT *New)
This adds the specified loop to the collection of top-level loops.
void removeBlock(BlockT *BB)
This method completely removes BB from all data structures, including all of the Loop objects it is n...
bool isLoopHeader(const BlockT *BB) const
void changeLoopFor(BlockT *BB, LoopT *L)
Change the top-level loop that contains BB to the specified loop.
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
void erase(Loop *L)
Update LoopInfo after removing the last backedge from a loop.
PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM, LoopStandardAnalysisResults &AR, LPMUpdater &U)
Represents a single loop in the control flow graph.
An analysis that produces MemorySSA for a function.
MemorySSA * getMemorySSA() const
Get handle on MemorySSA.
void removeEdge(BasicBlock *From, BasicBlock *To)
Update the MemoryPhi in To following an edge deletion between From and To.
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...
void removeBlocks(const SmallSetVector< BasicBlock *, 8 > &DeadBlocks)
Remove all MemoryAcceses in a set of BasicBlocks about to be deleted.
void applyUpdates(ArrayRef< CFGUpdate > Updates, DominatorTree &DT, bool UpdateDTFirst=false)
Apply CFG updates, analogous with the DT edge updates.
void verifyMemorySSA(VerificationLevel=VerificationLevel::Fast) const
Verify that MemorySSA is self consistent (IE definitions dominate all uses, uses appear in the right ...
static 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.
void forgetTopmostLoop(const Loop *L)
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...
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 push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
void addCase(ConstantInt *OnVal, BasicBlock *Dest)
Add an entry to the switch instruction.
StringRef getName() const
Return a constant reference to the value's name.
initializer< Ty > init(const Ty &Val)
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the module M.
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.
void detachDeadBlocks(ArrayRef< BasicBlock * > BBs, SmallVectorImpl< DominatorTree::UpdateType > *Updates, bool KeepOneInputPHIs=false)
Replace contents of every block in BBs with single unreachable instruction.
auto successors(const MachineBasicBlock *BB)
bool formLCSSARecursively(Loop &L, const DominatorTree &DT, const LoopInfo *LI, ScalarEvolution *SE)
Put a loop nest into LCSSA form.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool VerifyMemorySSA
Enables verification of MemorySSA.
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.
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.
PreservedAnalyses getLoopPassPreservedAnalyses()
Returns the minimum set of Analyses that all loop passes must preserve.
auto predecessors(const MachineBasicBlock *BB)
The adaptor from a function pass to a loop pass computes these analyses and makes them available to t...