42 #define DEBUG_TYPE "loop-simplifycfg" 48 "Number of terminators folded to unconditional branches");
50 "Number of loop blocks deleted");
52 "Number of loop exiting edges deleted");
59 if (
BranchInst *BI = dyn_cast<BranchInst>(TI)) {
60 if (BI->isUnconditional())
62 if (BI->getSuccessor(0) == BI->getSuccessor(1))
67 return Cond->
isZero() ? BI->getSuccessor(1) : BI->getSuccessor(0);
74 for (
auto Case :
SI->cases())
75 if (Case.getCaseValue() == CI)
76 return Case.getCaseSuccessor();
77 return SI->getDefaultDest();
86 class ConstantTerminatorFoldingImpl {
95 bool HasIrreducibleCFG =
false;
104 bool DeleteCurrentLoop =
false;
126 dbgs() <<
"Constant terminator folding for loop " << L <<
"\n";
127 dbgs() <<
"After terminator constant-folding, the loop will";
128 if (!DeleteCurrentLoop)
130 dbgs() <<
" be destroyed\n";
131 auto PrintOutVector = [&](
const char *Message,
133 dbgs() << Message <<
"\n";
135 dbgs() <<
"\t" << BB->getName() <<
"\n";
137 auto PrintOutSet = [&](
const char *Message,
139 dbgs() << Message <<
"\n";
141 dbgs() <<
"\t" << BB->getName() <<
"\n";
143 PrintOutVector(
"Blocks in which we can constant-fold terminator:",
145 PrintOutSet(
"Live blocks from the original loop:", LiveLoopBlocks);
146 PrintOutVector(
"Dead blocks from the original loop:", DeadLoopBlocks);
147 PrintOutSet(
"Live exit blocks:", LiveExitBlocks);
148 PrintOutVector(
"Dead exit blocks:", DeadExitBlocks);
149 if (!DeleteCurrentLoop)
150 PrintOutSet(
"The following blocks will still be part of the loop:",
151 BlocksInLoopAfterFolding);
159 unsigned Current = 0;
189 if (hasIrreducibleCFG(DFS)) {
190 HasIrreducibleCFG =
true;
200 if (!LiveLoopBlocks.
count(BB)) {
216 if (!TheOnlySucc || TheOnlySucc == Succ) {
218 LiveLoopBlocks.
insert(Succ);
220 LiveExitBlocks.
insert(Succ);
227 "Malformed block sets?");
232 for (
auto *ExitBlock : ExitBlocks)
233 if (!LiveExitBlocks.
count(ExitBlock))
239 if (!LiveLoopBlocks.
count(From))
242 return !TheOnlySucc || TheOnlySucc == To;
250 if (DeleteCurrentLoop)
262 return BlocksInLoopAfterFolding.
count(Succ) && IsEdgeLive(BB, Succ);
267 if (BlockIsInLoop(BB))
268 BlocksInLoopAfterFolding.
insert(BB);
273 "Header not in loop?");
274 assert(BlocksInLoopAfterFolding.
size() <= LiveLoopBlocks.
size() &&
275 "All blocks that stay in loop should be live!");
313 void handleDeadExits() {
315 if (DeadExitBlocks.
empty())
330 Builder.CreateSwitch(Builder.getInt32(0), NewPreheader);
333 unsigned DummyIdx = 1;
336 for (
auto &PN : BB->phis())
342 PN->eraseFromParent();
344 assert(DummyIdx != 0 &&
"Too many dead exits!");
345 DummySwitch->addCase(Builder.getInt32(DummyIdx++), BB);
347 ++NumLoopExitsDeleted;
352 OuterLoop->addBasicBlockToLoop(NewPreheader, LI);
358 Loop *StillReachable =
nullptr;
362 if (!StillReachable ||
364 StillReachable = BBL;
369 if (StillReachable != OuterLoop) {
371 for (
Loop *NotContaining = OuterLoop; NotContaining != StillReachable;
373 NotContaining->removeBlockFromLoop(NewPreheader);
374 for (
auto *BB : L.
blocks())
375 NotContaining->removeBlockFromLoop(BB);
377 OuterLoop->removeChildLoop(&L);
388 void deleteDeadLoopBlocks() {
392 DeadLoopBlocks.
end());
395 for (
auto *BB : DeadLoopBlocks) {
397 "Header of the current loop cannot be dead!");
406 ++NumLoopBlocksDeleted;
412 void foldTerminators() {
418 assert(TheOnlySucc &&
"Should have one live successor!");
421 <<
" with an unconditional branch to the block " 422 << TheOnlySucc->getName() <<
"\n");
426 unsigned TheOnlySuccDuplicates = 0;
428 if (Succ != TheOnlySucc) {
429 DeadSuccessors.
insert(Succ);
432 bool PreserveLCSSAPhi = !L.
contains(Succ);
433 Succ->removePredecessor(BB, PreserveLCSSAPhi);
437 ++TheOnlySuccDuplicates;
439 assert(TheOnlySuccDuplicates > 0 &&
"Should be!");
443 bool PreserveLCSSAPhi = !L.
contains(TheOnlySucc);
444 for (
unsigned Dup = 1; Dup < TheOnlySuccDuplicates; ++Dup)
445 TheOnlySucc->removePredecessor(BB, PreserveLCSSAPhi);
446 if (MSSAU && TheOnlySuccDuplicates > 1)
451 Builder.SetInsertPoint(Term);
452 Builder.CreateBr(TheOnlySucc);
453 Term->eraseFromParent();
455 for (
auto *DeadSucc : DeadSuccessors)
458 ++NumTerminatorsFolded;
466 : L(L), LI(LI), DT(DT), SE(SE), MSSAU(MSSAU) {}
477 if (HasIrreducibleCFG) {
478 LLVM_DEBUG(
dbgs() <<
"Loops with irreducible CFG are not supported!\n");
483 if (FoldCandidates.
empty()) {
485 dbgs() <<
"No constant terminator folding candidates found in loop " 491 if (DeleteCurrentLoop) {
494 <<
"Give up constant terminator folding in loop " 496 <<
": we don't currently support deletion of the current loop.\n");
502 if (BlocksInLoopAfterFolding.
size() + DeadLoopBlocks.
size() !=
505 dbgs() <<
"Give up constant terminator folding in loop " 507 <<
": we don't currently" 508 " support blocks that are not dead, but will stop " 509 "being a part of the loop after constant-folding.\n");
525 if (!DeadLoopBlocks.
empty()) {
529 deleteDeadLoopBlocks();
557 ConstantTerminatorFoldingImpl
BranchFolder(L, LI, DT, SE, MSSAU);
558 return BranchFolder.run();
563 bool Changed =
false;
569 for (
auto &Block : Blocks) {
572 BasicBlock *Succ = cast_or_null<BasicBlock>(Block);
591 bool Changed =
false;
619 class LoopSimplifyCFGLegacyPass :
public LoopPass {
622 LoopSimplifyCFGLegacyPass() :
LoopPass(ID) {
630 DominatorTree &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
631 LoopInfo &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
632 ScalarEvolution &SE = getAnalysis<ScalarEvolutionWrapperPass>().getSE();
635 MemorySSA *MSSA = &getAnalysis<MemorySSAWrapperPass>().getMSSA();
657 "Simplify loop CFG",
false,
false)
664 return new LoopSimplifyCFGLegacyPass();
detail::concat_range< ValueT, RangeTs... > concat(RangeTs &&... Ranges)
Concatenated range across two or more ranges.
Pass interface - Implemented by all 'passes'.
static bool simplifyLoopCFG(Loop &L, DominatorTree &DT, LoopInfo &LI, ScalarEvolution &SE, MemorySSAUpdater *MSSAU)
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
BlockT * getLoopLatch() const
If there is a single latch block for this loop, return it.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
PreservedAnalyses getLoopPassPreservedAnalyses()
Returns the minimum set of Analyses that all loop passes must preserve.
bool VerifyMemorySSA
Enables verification of MemorySSA.
This class represents lattice values for constants.
This header provides classes for managing a pipeline of passes over loops in LLVM IR...
This is the interface for a simple mod/ref and alias analysis over globals.
static cl::opt< bool > EnableTermFolding("enable-loop-simplifycfg-term-folding", cl::init(false))
bool MergeBlockIntoPredecessor(BasicBlock *BB, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, MemoryDependenceResults *MemDep=nullptr)
Attempts to merge a block into its predecessor, if possible.
void removeDuplicatePhiEdgesBetween(BasicBlock *From, BasicBlock *To)
Update the MemoryPhi in To to have a single incoming edge from From, following a CFG change that repl...
BasicBlock * getSuccessor(unsigned Idx) const
Return the specified successor. This instruction must be a terminator.
static bool mergeBlocksIntoPredecessors(Loop &L, DominatorTree &DT, LoopInfo &LI, MemorySSAUpdater *MSSAU)
Legacy pass manager pass to access dependence information.
unsigned getLoopDepth() const
Return the nesting level of this loop.
void push_back(const T &Elt)
The main scalar evolution driver.
void removeBlocks(const SmallPtrSetImpl< BasicBlock *> &DeadBlocks)
Remove all MemoryAcceses in a set of BasicBlocks about to be deleted.
BlockT * getLoopPreheader() const
If there is a preheader for this loop, return it.
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...
void DeleteDeadBlock(BasicBlock *BB, DomTreeUpdater *DTU=nullptr)
Delete the specified block, which must have no predecessors.
STATISTIC(NumFunctions, "Total number of functions")
The adaptor from a function pass to a loop pass computes these analyses and makes them available to t...
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...
bool isComplete() const
Return true if postorder numbers are assigned to all loop blocks.
bool isReachableFromEntry(const Use &U) const
Provide an overload for a Use.
void verify(const DominatorTreeBase< BlockT, false > &DomTree) const
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
void removeEdge(BasicBlock *From, BasicBlock *To)
Update the MemoryPhi in To following an edge deletion between From and To.
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
Legacy analysis pass which computes MemorySSA.
This is the interface for a SCEV-based alias analysis.
POIterator beginPostorder() const
Iterate over the cached postorder blocks.
bool verify(VerificationLevel VL=VerificationLevel::Full) const
verify - checks if the tree is correct.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
Encapsulates MemorySSA, including all data associated with memory accesses.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
void erase(Loop *L)
Update LoopInfo after removing the last backedge from a loop.
RPOIterator endRPO() const
BlockT * getHeader() const
void getExitBlocks(SmallVectorImpl< BlockT *> &ExitBlocks) const
Return all of the successor blocks of this loop.
void addTopLevelLoop(LoopT *New)
This adds the specified loop to the collection of top-level loops.
const BasicBlock * getSingleSuccessor() const
Return the successor of this block if it has a single successor.
static bool constantFoldTerminators(Loop &L, DominatorTree &DT, LoopInfo &LI, ScalarEvolution &SE, MemorySSAUpdater *MSSAU)
Turn branches and switches with known constant conditions into unconditional branches.
void perform(LoopInfo *LI)
Traverse the loop blocks and store the DFS result.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree...
initializer< Ty > init(const Ty &Val)
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
A set of analyses that are preserved following a run of a transformation pass.
const BasicBlock * getSinglePredecessor() const
Return the predecessor of this block if it has a single predecessor block.
LLVM Basic Block Representation.
Conditional or Unconditional Branch instruction.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
Represent the analysis usage information of a pass.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly...
const T * getPointer() const
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
static UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
void deleteEdge(BasicBlock *From, BasicBlock *To)
Notify all available trees on an edge deletion.
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false) RegBankSelect
This class provides an interface for updating the loop pass manager based on mutations to the loop ne...
bool contains(const LoopT *L) const
Return true if the specified loop is contained within in this loop.
void insertEdge(BasicBlock *From, BasicBlock *To)
Notify all available trees on an edge insertion.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
This is the shared class of boolean and integer constants.
BlockVerifier::State From
void verifyMemorySSA() const
Verify that MemorySSA is self consistent (IE definitions dominate all uses, uses appear in the right ...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Pass * createLoopSimplifyCFGPass()
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Store the result of a depth first search within basic blocks contained by a single loop...
bool isLoopHeader(const BlockT *BB) const
void initializeLoopSimplifyCFGLegacyPassPass(PassRegistry &)
POIterator endPostorder() const
LoopT * getParentLoop() const
unsigned getNumBlocks() const
Get the number of blocks in this loop in constant time.
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
void addChildLoop(LoopT *NewChild)
Add the specified loop to be a child of this loop.
INITIALIZE_PASS_BEGIN(LoopSimplifyCFGLegacyPass, "loop-simplifycfg", "Simplify loop CFG", false, false) INITIALIZE_PASS_END(LoopSimplifyCFGLegacyPass
LLVM_NODISCARD bool empty() const
Represents a single loop in the control flow graph.
StringRef getName() const
Return a constant reference to the value's name.
const Function * getParent() const
Return the enclosing method, or null if none.
bool isZero() const
This is just a convenience method to make client code smaller for a common code.
void getLoopAnalysisUsage(AnalysisUsage &AU)
Helper to consistently add the set of standard passes to a loop pass's AnalysisUsage.
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
void changeLoopFor(BlockT *BB, LoopT *L)
Change the top-level loop that contains BB to the specified loop.
BasicBlock * splitBasicBlock(iterator I, const Twine &BBName="")
Split the basic block into two basic blocks at the specified instruction.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
rpo Deduce function attributes in RPO
succ_range successors(Instruction *I)
RPOIterator beginRPO() const
Reverse iterate over the cached postorder blocks.
PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM, LoopStandardAnalysisResults &AR, LPMUpdater &U)
This file exposes an interface to building/using memory SSA to walk memory instructions using a use/d...
This is the interface for LLVM's primary stateless and local alias analysis.
A container for analyses that lazily runs them and caches their results.
iterator_range< block_iterator > blocks() const
void removeBlock(BlockT *BB)
This method completely removes BB from all data structures, including all of the Loop objects it is n...
void forgetTopmostLoop(const Loop *L)
cl::opt< bool > EnableMSSALoopDependency
Enables memory ssa as a dependency for loop passes.