31#define DEBUG_TYPE "unify-loop-exits"
37 cl::desc(
"Set the maximum number of outgoing blocks for using a boolean "
38 "value to record the exiting block in the ControlFlowHub."));
58char UnifyLoopExitsLegacyPass::ID = 0;
61 return new UnifyLoopExitsLegacyPass();
65 "Fixup each natural loop to have a single exit block",
95 for (
auto *BB : L->blocks()) {
97 for (
auto &U :
I.uses()) {
98 auto UserInst = cast<Instruction>(U.getUser());
99 auto UserBlock = UserInst->getParent();
100 if (UserBlock == LoopExitBlock)
102 if (L->contains(UserBlock))
105 << BB->getName() <<
")"
106 <<
": " << UserInst->getName() <<
"("
107 << UserBlock->getName() <<
")"
109 ExternalUsers[&
I].push_back(UserInst);
114 for (
const auto &
II : ExternalUsers) {
120 LLVM_DEBUG(
dbgs() <<
"externally used: " << Def->getName() <<
"\n");
123 Def->getName() +
".moved", LoopExitBlock->begin());
126 if (Def->getParent() == In || DT.
dominates(Def, In)) {
128 NewPhi->addIncoming(Def, In);
136 for (
auto *U :
II.second) {
138 U->replaceUsesOfWith(Def, NewPhi);
151 L->getExitingBlocks(ExitingBlocks);
155 for (
auto *BB : ExitingBlocks) {
156 auto *Branch = cast<BranchInst>(BB->getTerminator());
158 Succ0 = L->contains(Succ0) ? nullptr : Succ0;
161 Branch->isUnconditional() ? nullptr : Branch->getSuccessor(1);
162 Succ1 = L->contains(Succ1) ? nullptr : Succ1;
165 LLVM_DEBUG(
dbgs() <<
"Added exiting branch: " << BB->getName() <<
" -> {"
166 << (Succ0 ? Succ0->
getName() :
"<none>") <<
", "
167 << (Succ1 ? Succ1->
getName() :
"<none>") <<
"}\n");
174 std::tie(LoopExitBlock, ChangedCFG) = CHub.
finalize(
179 restoreSSA(DT, L, ExitingBlocks, LoopExitBlock);
181#if defined(EXPENSIVE_CHECKS)
182 assert(DT.
verify(DominatorTree::VerificationLevel::Full));
184 assert(DT.
verify(DominatorTree::VerificationLevel::Fast));
190 if (
auto ParentLoop = L->getParentLoop()) {
191 for (
auto *
G : GuardBlocks) {
192 ParentLoop->addBasicBlockToLoop(
G, LI);
194 ParentLoop->verifyLoop();
197#if defined(EXPENSIVE_CHECKS)
206 bool Changed =
false;
208 for (
auto *L :
Loops) {
215bool UnifyLoopExitsLegacyPass::runOnFunction(
Function &
F) {
216 LLVM_DEBUG(
dbgs() <<
"===== Unifying loop exits in function " <<
F.getName()
218 auto &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
219 auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
230 LLVM_DEBUG(
dbgs() <<
"===== Unifying loop exits in function " <<
F.getName()
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static bool runImpl(Function &F, const TargetLowering &TLI)
This file implements a map that provides insertion order iteration.
uint64_t IntrinsicInst * II
PowerPC TLS Dynamic Call Fixup
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
unify loop Fixup each natural loop to have a single exit block
static bool unifyLoopExits(DominatorTree &DT, LoopInfo &LI, Loop *L)
unify loop Fixup each natural loop to have a single exit static false void restoreSSA(const DominatorTree &DT, const Loop *L, SmallVectorImpl< BasicBlock * > &Incoming, BasicBlock *LoopExitBlock)
static cl::opt< unsigned > MaxBooleansInControlFlowHub("max-booleans-in-control-flow-hub", cl::init(32), cl::Hidden, cl::desc("Set the maximum number of outgoing blocks for using a boolean " "value to record the exiting block in the ControlFlowHub."))
static bool runImpl(LoopInfo &LI, DominatorTree &DT)
A container for analyses that lazily runs them and caches their results.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
LLVM Basic Block Representation.
Analysis pass which computes a DominatorTree.
bool verify(VerificationLevel VL=VerificationLevel::Full) const
verify - checks if the tree is correct.
Legacy analysis pass which computes a DominatorTree.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
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.
FunctionPass class - This class is used to implement most global optimizations.
virtual bool runOnFunction(Function &F)=0
runOnFunction - Virtual method overriden by subclasses to do the per-function processing of the pass.
Analysis pass that exposes the LoopInfo for a function.
void verify(const DominatorTreeBase< BlockT, false > &DomTree) const
SmallVector< LoopT *, 4 > getLoopsInPreorder() const
Return all of the loops in the function in preorder across the loop nests, with siblings in forward p...
The legacy pass manager's analysis pass to compute loop information.
Represents a single loop in the control flow graph.
This class implements a map that also provides access to all stored values in a deterministic order.
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 PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
virtual void getAnalysisUsage(AnalysisUsage &) const
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
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.
PreservedAnalyses & preserve()
Mark an analysis as preserved.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI bool hasOnlySimpleTerminator(const Function &F)
LLVM_ABI void initializeUnifyLoopExitsLegacyPassPass(PassRegistry &)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI FunctionPass * createUnifyLoopExitsPass()
Given a set of branch descriptors [BB, Succ0, Succ1], create a "hub" such that the control flow from ...
std::pair< BasicBlock *, bool > finalize(DomTreeUpdater *DTU, SmallVectorImpl< BasicBlock * > &GuardBlocks, const StringRef Prefix, std::optional< unsigned > MaxControlFlowBooleans=std::nullopt)
Return the unified loop exit block and a flag indicating if the CFG was changed at all.
void addBranch(BasicBlock *BB, BasicBlock *Succ0, BasicBlock *Succ1)
Incoming for lane maks phi as machine instruction, incoming register Reg and incoming block Block are...