LLVM: lib/Transforms/Utils/UnifyLoopExits.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
30
31#define DEBUG_TYPE "unify-loop-exits"
32
33using namespace llvm;
34
37 cl::desc("Set the maximum number of outgoing blocks for using a boolean "
38 "value to record the exiting block in the ControlFlowHub."));
39
40namespace {
41struct UnifyLoopExitsLegacyPass : public FunctionPass {
42 static char ID;
45 }
46
52 }
53
55};
56}
57
58char UnifyLoopExitsLegacyPass::ID = 0;
59
61 return new UnifyLoopExitsLegacyPass();
62}
63
65 "Fixup each natural loop to have a single exit block",
66 false , false )
70 "Fixup each natural loop to have a single exit block",
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
94 IIMap ExternalUsers;
95 for (auto *BB : L->blocks()) {
96 for (auto &I : *BB) {
97 for (auto &U : I.uses()) {
98 auto UserInst = cast(U.getUser());
99 auto UserBlock = UserInst->getParent();
100 if (UserBlock == LoopExitBlock)
101 continue;
102 if (L->contains(UserBlock))
103 continue;
104 LLVM_DEBUG(dbgs() << "added ext use for " << I.getName() << "("
105 << BB->getName() << ")"
106 << ": " << UserInst->getName() << "("
107 << UserBlock->getName() << ")"
108 << "\n");
109 ExternalUsers[&I].push_back(UserInst);
110 }
111 }
112 }
113
114 for (const auto &II : ExternalUsers) {
115
116
117
118
119 auto Def = II.first;
120 LLVM_DEBUG(dbgs() << "externally used: " << Def->getName() << "\n");
121 auto NewPhi =
123 Def->getName() + ".moved", LoopExitBlock->begin());
125 LLVM_DEBUG(dbgs() << "predecessor " << In->getName() << ": ");
126 if (Def->getParent() == In || DT.dominates(Def, In)) {
128 NewPhi->addIncoming(Def, In);
129 } else {
132 }
133 }
134
136 for (auto *U : II.second) {
138 U->replaceUsesOfWith(Def, NewPhi);
139 }
141 }
142}
143
145
146
147
148
149
151 L->getExitingBlocks(ExitingBlocks);
152
153
155 for (auto *BB : ExitingBlocks) {
156 auto *Branch = cast(BB->getTerminator());
157 BasicBlock *Succ0 = Branch->getSuccessor(0);
158 Succ0 = L->contains(Succ0) ? nullptr : Succ0;
159
161 Branch->isUnconditional() ? nullptr : Branch->getSuccessor(1);
162 Succ1 = L->contains(Succ1) ? nullptr : Succ1;
163 CHub.addBranch(BB, Succ0, Succ1);
164
165 LLVM_DEBUG(dbgs() << "Added exiting branch: " << BB->getName() << " -> {"
166 << (Succ0 ? Succ0->getName() : "") << ", "
167 << (Succ1 ? Succ1->getName() : "") << "}\n");
168 }
169
171 DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Eager);
174
175 restoreSSA(DT, L, ExitingBlocks, LoopExitBlock);
176
177#if defined(EXPENSIVE_CHECKS)
178 assert(DT.verify(DominatorTree::VerificationLevel::Full));
179#else
180 assert(DT.verify(DominatorTree::VerificationLevel::Fast));
181#endif
182 L->verifyLoop();
183
184
185
186 if (auto ParentLoop = L->getParentLoop()) {
187 for (auto *G : GuardBlocks) {
188 ParentLoop->addBasicBlockToLoop(G, LI);
189 }
190 ParentLoop->verifyLoop();
191 }
192
193#if defined(EXPENSIVE_CHECKS)
195#endif
196
197 return true;
198}
199
201
202 bool Changed = false;
204 for (auto *L : Loops) {
207 }
208 return Changed;
209}
210
211bool UnifyLoopExitsLegacyPass::runOnFunction(Function &F) {
212 LLVM_DEBUG(dbgs() << "===== Unifying loop exits in function " << F.getName()
213 << "\n");
214 auto &LI = getAnalysis().getLoopInfo();
215 auto &DT = getAnalysis().getDomTree();
216
218
220}
221
222namespace llvm {
223
226 LLVM_DEBUG(dbgs() << "===== Unifying loop exits in function " << F.getName()
227 << "\n");
230
236 return PA;
237}
238}
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)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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.
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 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 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.
void 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)
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.
bool hasOnlySimpleTerminator(const Function &F)
void initializeUnifyLoopExitsLegacyPassPass(PassRegistry &)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
FunctionPass * createUnifyLoopExitsPass()
Given a set of branch descriptors [BB, Succ0, Succ1], create a "hub" such that the control flow from ...
BasicBlock * finalize(DomTreeUpdater *DTU, SmallVectorImpl< BasicBlock * > &GuardBlocks, const StringRef Prefix, std::optional< unsigned > MaxControlFlowBooleans=std::nullopt)
void addBranch(BasicBlock *BB, BasicBlock *Succ0, BasicBlock *Succ1)
Incoming for lane maks phi as machine instruction, incoming register Reg and incoming block Block are...