LLVM 24.0.0git
FixIrreducible.cpp
Go to the documentation of this file.
1//===- FixIrreducible.cpp - Convert irreducible control-flow into loops ---===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// INPUT CFG: The blocks H and B form an irreducible cycle with two headers.
10//
11// Entry
12// / \
13// v v
14// H ----> B
15// ^ /|
16// `----' |
17// v
18// Exit
19//
20// OUTPUT CFG: Converted to a natural loop with a new header N.
21//
22// Entry
23// |
24// v
25// N <---.
26// / \ \
27// / \ |
28// v v /
29// H --> B --'
30// |
31// v
32// Exit
33//
34// To convert an irreducible cycle C to a natural loop L:
35//
36// 1. Add a new node N to C.
37// 2. Redirect all external incoming edges through N.
38// 3. Redirect all edges incident on header H through N.
39//
40// This is sufficient to ensure that:
41//
42// a. Every closed path in C also exists in L, with the modification that any
43// path passing through H now passes through N before reaching H.
44// b. Every external path incident on any entry of C is now incident on N and
45// then redirected to the entry.
46//
47// Thus, L is a strongly connected component dominated by N, and hence L is a
48// natural loop with header N.
49//
50// When an irreducible cycle C with header H is transformed into a loop, the
51// following invariants hold:
52//
53// 1. No new subcycles are "discovered" in the set (C-H). The only internal
54// edges that are redirected by the transform are incident on H. Any subcycle
55// S in (C-H), already existed prior to this transform, and is already in the
56// list of children for this cycle C.
57//
58// 2. Subcycles of C are not modified by the transform. For some subcycle S of
59// C, edges incident on the entries of S are either internal to C, or they
60// are now redirected through N, which is outside of S. So the list of
61// entries to S does not change. Since the transform only adds a block
62// outside S, and redirects edges that are not internal to S, the list of
63// blocks in S does not change.
64//
65// 3. Similarly, any natural loop L included in C is not affected, with one
66// exception: L is "destroyed" by the transform iff its header is H. The
67// backedges of such a loop are now redirected to N instead, and hence the
68// body of this loop gets merged into the new loop with header N.
69//
70// The actual transformation is handled by the ControlFlowHub, which redirects
71// specified control flow edges through a set of guard blocks. This also moves
72// every PHINode in an outgoing block to the hub. Since the hub dominates all
73// the outgoing blocks, each such PHINode continues to dominate its uses. Since
74// every header in an SCC has at least two predecessors, every value used in the
75// header (or later) but defined in a predecessor (or earlier) is represented by
76// a PHINode in a header. Hence the above handling of PHINodes is sufficient and
77// no further processing is required to restore SSA.
78//
79// Limitation: The pass cannot handle indirect branches. They must be lowered to
80// plain branches first.
81//
82// CallBr and Switch support: CallBr and Switch terminators are handled as a
83// more general branch instruction which can have multiple successors. The pass
84// redirects the edges to intermediate target blocks that unconditionally branch
85// to the original target blocks. This allows the control flow hub to know to
86// which of the original target blocks to jump to. Example input CFG:
87// Entry (callbr/switch)
88// / \
89// v v
90// H ----> B
91// ^ /|
92// `----' |
93// v
94// Exit
95//
96// becomes:
97// Entry (callbr/switch)
98// / \
99// v v
100// target.H target.B
101// | |
102// v v
103// H ----> B
104// ^ /|
105// `----' |
106// v
107// Exit
108//
109// Note
110// OUTPUT CFG: Converted to a natural loop with a new header N.
111//
112// Entry (callbr/switch)
113// / \
114// v v
115// target.H target.B
116// \ /
117// \ /
118// v v
119// N <---.
120// / \ \
121// / \ |
122// v v /
123// H --> B --'
124// |
125// v
126// Exit
127//
128//===----------------------------------------------------------------------===//
129
131#include "llvm/ADT/DenseMap.h"
135#include "llvm/IR/Instructions.h"
137#include "llvm/Pass.h"
142
143#define DEBUG_TYPE "fix-irreducible"
144
145using namespace llvm;
146
147namespace {
148struct FixIrreducible : public FunctionPass {
149 static char ID;
150 FixIrreducible() : FunctionPass(ID) {
152 }
153
154 void getAnalysisUsage(AnalysisUsage &AU) const override {
160 }
161
162 bool runOnFunction(Function &F) override;
163};
164} // namespace
165
166char FixIrreducible::ID = 0;
167
168FunctionPass *llvm::createFixIrreduciblePass() { return new FixIrreducible(); }
169
170INITIALIZE_PASS_BEGIN(FixIrreducible, "fix-irreducible",
171 "Convert irreducible control-flow into natural loops",
172 false /* Only looks at CFG */, false /* Analysis Pass */)
175INITIALIZE_PASS_END(FixIrreducible, "fix-irreducible",
176 "Convert irreducible control-flow into natural loops",
177 false /* Only looks at CFG */, false /* Analysis Pass */)
178
179// When a new loop is created, existing children of the parent loop may now be
180// fully inside the new loop. Reconnect these as children of the new loop.
181static void reconnectChildLoops(LoopInfo &LI, Loop *ParentLoop, Loop *NewLoop,
182 BasicBlock *OldHeader) {
183 // Any candidate (sibling of NewLoop, or top-level loop if there is no
184 // parent) is a child iff its header is owned by the new loop. The new loop's
185 // block list is already populated but its subloops are not yet attached, so
186 // query the block list directly rather than contains(), which would derive
187 // from the not-yet-updated block-to-loop map.
188 SmallVector<Loop *, 4> ChildLoops =
189 LI.takeChildrenIf(ParentLoop, [&](Loop *L) {
190 return NewLoop != L &&
191 llvm::is_contained(NewLoop->getBlocks(), L->getHeader());
192 });
193
194 for (Loop *Child : ChildLoops) {
195 LLVM_DEBUG(dbgs() << "child loop: " << Child->getHeader()->getName()
196 << "\n");
197 // A child loop whose header was the old cycle header gets destroyed since
198 // its backedges are removed.
199 if (Child->getHeader() == OldHeader) {
200 for (auto *BB : Child->blocks()) {
201 if (LI.getLoopFor(BB) != Child)
202 continue;
203 LI.changeLoopFor(BB, NewLoop);
204 LLVM_DEBUG(dbgs() << "moved block from child: " << BB->getName()
205 << "\n");
206 }
207 for (Loop *GrandChildLoop :
208 LI.takeChildrenIf(Child, [](const Loop *) { return true; }))
209 NewLoop->addChildLoop(GrandChildLoop);
210 LI.destroy(Child);
211 LLVM_DEBUG(dbgs() << "subsumed child loop (common header)\n");
212 continue;
213 }
214
215 NewLoop->addChildLoop(Child);
216 LLVM_DEBUG(dbgs() << "added child loop to new loop\n");
217 }
218}
219
221 ArrayRef<BasicBlock *> GuardBlocks) {
222 // The parent loop is a natural loop L mapped to the cycle header H as long as
223 // H is not also the header of L. In the latter case, L is destroyed and we
224 // seek its parent instead.
225 BasicBlock *CycleHeader = CI.getHeader(C);
226 Loop *ParentLoop = LI.getLoopFor(CycleHeader);
227 if (ParentLoop && ParentLoop->getHeader() == CycleHeader)
228 ParentLoop = ParentLoop->getParentLoop();
229
230 // Create a new loop from the now-transformed cycle
231 auto *NewLoop = LI.AllocateLoop();
232 if (ParentLoop) {
233 ParentLoop->addChildLoop(NewLoop);
234 } else {
235 LI.addTopLevelLoop(NewLoop);
236 }
237
238 // Add the guard blocks to the new loop. The first guard block is
239 // the head of all the backedges, and it is the first to be inserted
240 // in the loop. This ensures that it is recognized as the
241 // header. Since the new loop is already in LoopInfo, the new blocks
242 // are also propagated up the chain of parent loops.
243 for (auto *G : GuardBlocks) {
244 LLVM_DEBUG(dbgs() << "added guard block to loop: " << G->getName() << "\n");
245 NewLoop->addBasicBlockToLoop(G, LI);
246 }
247
248 for (auto *BB : CI.getBlocks(C)) {
249 NewLoop->addBlockEntry(BB);
250 if (LI.getLoopFor(BB) == ParentLoop) {
251 LLVM_DEBUG(dbgs() << "moved block from parent: " << BB->getName()
252 << "\n");
253 LI.changeLoopFor(BB, NewLoop);
254 } else {
255 LLVM_DEBUG(dbgs() << "added block from child: " << BB->getName() << "\n");
256 }
257 }
258 LLVM_DEBUG(dbgs() << "header for new loop: "
259 << NewLoop->getHeader()->getName() << "\n");
260
261 reconnectChildLoops(LI, ParentLoop, NewLoop, CI.getHeader(C));
262
263 LLVM_DEBUG(dbgs() << "Verify new loop.\n"; NewLoop->print(dbgs()));
264 NewLoop->verifyLoop();
265 if (ParentLoop) {
266 LLVM_DEBUG(dbgs() << "Verify parent loop.\n"; ParentLoop->print(dbgs()));
267 ParentLoop->verifyLoop();
268 }
269}
270
271// Given a set of blocks and headers in an irreducible SCC, convert it into a
272// natural loop. Also insert this new loop at its appropriate place in the
273// hierarchy of loops.
275 LoopInfo *LI) {
276 if (CI.isReducible(C))
277 return false;
278 LLVM_DEBUG(dbgs() << "Processing cycle:\n" << CI.print(C) << "\n";);
279
280 DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Eager);
281 ControlFlowHub CHub;
282 SetVector<BasicBlock *> Predecessors;
283
284 // Redirect internal edges incident on the header.
285 BasicBlock *Header = CI.getHeader(C);
286 for (BasicBlock *P : predecessors(Header)) {
287 if (CI.contains(C, P))
288 Predecessors.insert(P);
289 }
290
291 for (BasicBlock *P : Predecessors) {
292 Instruction *Term = P->getTerminator();
293 if (isa<UncondBrInst>(Term)) {
294 assert(Term->getSuccessor(0) == Header);
295 CHub.addBranch(P, Header);
296
297 LLVM_DEBUG(dbgs() << "Added internal branch: " << printBasicBlock(P)
298 << " -> " << printBasicBlock(Header) << '\n');
299 } else if (CondBrInst *Branch = dyn_cast<CondBrInst>(Term)) {
300 BasicBlock *Succ0 = Branch->getSuccessor(0) == Header ? Header : nullptr;
301 BasicBlock *Succ1 = Branch->getSuccessor(1) == Header ? Header : nullptr;
302 assert(Succ0 || Succ1);
303 CHub.addBranch(P, Succ0, Succ1);
304
305 LLVM_DEBUG(dbgs() << "Added internal branch: " << printBasicBlock(P)
306 << " -> " << printBasicBlock(Succ0)
307 << (Succ0 && Succ1 ? " " : "") << printBasicBlock(Succ1)
308 << '\n');
309 } else if (isa<CallBrInst>(Term) || isa<SwitchInst>(Term)) {
310 BasicBlock *NewSucc = nullptr;
311 for (unsigned I = 0; I < Term->getNumSuccessors(); ++I) {
312 BasicBlock *Succ = Term->getSuccessor(I);
313 if (Succ != Header)
314 continue;
315 NewSucc = SplitMultiBrEdge(P, Succ, I, NewSucc, &DTU, &CI, LI);
316 LLVM_DEBUG(dbgs() << "Added internal branch: "
317 << printBasicBlock(NewSucc) << " -> "
318 << printBasicBlock(Succ) << '\n');
319 }
320 if (NewSucc)
321 CHub.addBranch(NewSucc, Header);
322 } else {
324 "unsupported block terminator: fix-irreducible "
325 "only supports br, callbr, and switch instructions");
326 }
327 }
328
329 // Redirect external incoming edges. This includes the edges on the header.
330 Predecessors.clear();
331 for (BasicBlock *E : CI.getEntries(C)) {
332 for (BasicBlock *P : predecessors(E)) {
333 if (!CI.contains(C, P))
334 Predecessors.insert(P);
335 }
336 }
337
338 for (BasicBlock *P : Predecessors) {
339 Instruction *Term = P->getTerminator();
340 if (UncondBrInst *Branch = dyn_cast<UncondBrInst>(Term)) {
341 BasicBlock *Succ0 = Branch->getSuccessor();
342 Succ0 = CI.contains(C, Succ0) ? Succ0 : nullptr;
343 CHub.addBranch(P, Succ0);
344
345 LLVM_DEBUG(dbgs() << "Added external branch: " << printBasicBlock(P)
346 << " -> " << printBasicBlock(Succ0) << '\n');
347 } else if (CondBrInst *Branch = dyn_cast<CondBrInst>(Term)) {
348 BasicBlock *Succ0 = Branch->getSuccessor(0);
349 Succ0 = CI.contains(C, Succ0) ? Succ0 : nullptr;
350 BasicBlock *Succ1 = Branch->getSuccessor(1);
351 Succ1 = CI.contains(C, Succ1) ? Succ1 : nullptr;
352 CHub.addBranch(P, Succ0, Succ1);
353
354 LLVM_DEBUG(dbgs() << "Added external branch: " << printBasicBlock(P)
355 << " -> " << printBasicBlock(Succ0)
356 << (Succ0 && Succ1 ? " " : "") << printBasicBlock(Succ1)
357 << '\n');
358 } else if (isa<CallBrInst>(Term) || isa<SwitchInst>(Term)) {
360 for (unsigned I = 0; I < Term->getNumSuccessors(); ++I) {
361 BasicBlock *Succ = Term->getSuccessor(I);
362 if (!CI.contains(C, Succ))
363 continue;
364 auto It = MultiBrTargets.find(Succ);
365 BasicBlock *ExistingTarget =
366 (It != MultiBrTargets.end()) ? It->second : nullptr;
367
368 BasicBlock *NewSucc =
369 SplitMultiBrEdge(P, Succ, I, ExistingTarget, &DTU, &CI, LI);
370 if (!ExistingTarget) {
371 CHub.addBranch(NewSucc, Succ);
372 MultiBrTargets[Succ] = NewSucc;
373 }
374 LLVM_DEBUG(dbgs() << "Added external branch: "
375 << printBasicBlock(NewSucc) << " -> "
376 << printBasicBlock(Succ) << '\n');
377 }
378 } else {
380 "unsupported block terminator: fix-irreducible "
381 "only supports br, callbr, and switch instructions");
382 }
383 }
384
385 // Redirect all the backedges through a "hub" consisting of a series
386 // of guard blocks that manage the flow of control from the
387 // predecessors to the headers.
388 SmallVector<BasicBlock *> GuardBlocks;
389
390 // Minor optimization: The cycle entries are discovered in an order that is
391 // the opposite of the order in which these blocks appear as branch targets.
392 // This results in a lot of condition inversions in the control flow out of
393 // the new ControlFlowHub, which can be mitigated if the orders match. So we
394 // reverse the entries when adding them to the hub.
396 Entries.insert(CI.getEntries(C).rbegin(), CI.getEntries(C).rend());
397
398 CHub.finalize(&DTU, GuardBlocks, "irr");
399#if defined(EXPENSIVE_CHECKS)
400 assert(DT.verify(DominatorTree::VerificationLevel::Full));
401#else
402 assert(DT.verify(DominatorTree::VerificationLevel::Fast));
403#endif
404
405 // If we are updating LoopInfo, do that now before modifying the cycle. This
406 // ensures that the first guard block is the header of a new natural loop.
407 if (LI)
408 updateLoopInfo(CI, *LI, C, GuardBlocks);
409
410 for (auto *G : GuardBlocks) {
411 LLVM_DEBUG(dbgs() << "added guard block to cycle: " << G->getName()
412 << "\n");
413 CI.addBlockToCycle(G, C);
414 }
415 CI.setSingleEntry(C, GuardBlocks[0]);
416
417 CI.verifyCycle(C);
418 if (CycleRef Parent = CI.getParentCycle(C))
419 CI.verifyCycle(Parent);
420
421 LLVM_DEBUG(dbgs() << "Finished one cycle:\n"; CI.print(dbgs()););
422 return true;
423}
424
426 LoopInfo *LI) {
427 LLVM_DEBUG(dbgs() << "===== Fix irreducible control-flow in function: "
428 << F.getName() << "\n");
429
430 bool Changed = false;
431 for (auto C : CI.cycles())
432 Changed |= fixIrreducible(C, CI, DT, LI);
433
434 if (!Changed)
435 return false;
436
437#if defined(EXPENSIVE_CHECKS)
438 CI.verify();
439 if (LI) {
440 LI->verify(DT);
441 }
442#endif // EXPENSIVE_CHECKS
443
444 return true;
445}
446
447bool FixIrreducible::runOnFunction(Function &F) {
448 auto *LIWP = getAnalysisIfAvailable<LoopInfoWrapperPass>();
449 LoopInfo *LI = LIWP ? &LIWP->getLoopInfo() : nullptr;
450 auto &CI = getAnalysis<CycleInfoWrapperPass>().getResult();
451 auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
452 return FixIrreducibleImpl(F, CI, DT, LI);
453}
454
457 auto *LI = AM.getCachedResult<LoopAnalysis>(F);
458 auto &CI = AM.getResult<CycleAnalysis>(F);
459 auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
460
461 if (!FixIrreducibleImpl(F, CI, DT, LI))
462 return PreservedAnalyses::all();
463
468 return PA;
469}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file declares an analysis pass that computes CycleInfo for LLVM IR, specialized from GenericCycl...
This file defines the DenseMap class.
static bool runOnFunction(Function &F, bool PostInlining)
fix Convert irreducible control flow into natural static false void reconnectChildLoops(LoopInfo &LI, Loop *ParentLoop, Loop *NewLoop, BasicBlock *OldHeader)
static bool FixIrreducibleImpl(Function &F, CycleInfo &CI, DominatorTree &DT, LoopInfo *LI)
static void updateLoopInfo(CycleInfo &CI, LoopInfo &LI, CycleRef C, ArrayRef< BasicBlock * > GuardBlocks)
static bool fixIrreducible(CycleRef C, CycleInfo &CI, DominatorTree &DT, LoopInfo *LI)
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
#define G(x, y, z)
Definition MD5.cpp:55
#define P(N)
#define INITIALIZE_PASS_DEPENDENCY(depName)
Definition PassSupport.h:42
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition PassSupport.h:44
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
Definition PassSupport.h:39
#define LLVM_DEBUG(...)
Definition Debug.h:119
PassT::Result * getCachedResult(IRUnitT &IR) const
Get the cached result of an analysis pass for a given IR unit.
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.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
LLVM Basic Block Representation.
Definition BasicBlock.h:62
Conditional Branch instruction.
Analysis pass which computes a CycleInfo.
Legacy analysis pass which computes a CycleInfo.
Opaque handle to a cycle within a GenericCycleInfo that wraps the cycle's preorder index.
iterator find(const_arg_type_t< KeyT > Val)
Definition DenseMap.h:223
iterator end()
Definition DenseMap.h:141
Analysis pass which computes a DominatorTree.
Definition Dominators.h:270
bool verify(VerificationLevel VL=VerificationLevel::Full) const
verify - checks if the tree is correct.
Legacy analysis pass which computes a DominatorTree.
Definition Dominators.h:306
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Definition Dominators.h:151
FunctionPass class - This class is used to implement most global optimizations.
Definition Pass.h:314
void verify() const
Verify that the entire cycle tree well-formed.
auto cycles() const
All cycles in forest preorder.
void verifyCycle(CycleRef C) const
Verify that C is actually a well-formed cycle in the CFG.
bool isReducible(CycleRef C) const
CycleRef getParentCycle(CycleRef C) const
void print(raw_ostream &Out) const
Print the cycle info.
ArrayRef< BlockT * > getEntries(CycleRef C) const
void setSingleEntry(CycleRef C, BlockT *Block)
void addBlockToCycle(BlockT *Block, CycleRef C)
Assumes that C is the innermost cycle containing Block.
ArrayRef< BlockT * > getBlocks(CycleRef C) const
Return the blocks of C, including those of nested cycles.
bool contains(CycleRef Outer, CycleRef Inner) const
Returns true iff Outer contains Inner. O(1). Non-strict.
BlockT * getHeader(CycleRef C) const
Analysis pass that exposes the LoopInfo for a function.
Definition LoopInfo.h:587
void verifyLoop() const
Verify loop structure.
BlockT * getHeader() const
void print(raw_ostream &OS, bool Verbose=false, bool PrintNested=true, unsigned Depth=0) const
Print loop with all the BBs inside it.
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.
void verify(const DominatorTreeBase< BlockT, false > &DomTree) const
void addTopLevelLoop(LoopT *New)
This adds the specified loop to the collection of top-level loops.
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
void changeLoopFor(const BlockT *BB, LoopT *L)
Change the top-level loop that contains BB to the specified loop.
The legacy pass manager's analysis pass to compute loop information.
Definition LoopInfo.h:612
Represents a single loop in the control flow graph.
Definition LoopInfo.h:40
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
A set of analyses that are preserved following a run of a transformation pass.
Definition Analysis.h:112
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
PreservedAnalyses & preserve()
Mark an analysis as preserved.
Definition Analysis.h:132
A vector that has set insertion semantics.
Definition SetVector.h:57
void clear()
Completely clear the SetVector.
Definition SetVector.h:267
bool insert(const value_type &X)
Insert a new element into the SetVector.
Definition SetVector.h:151
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Unconditional Branch instruction.
Changed
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI BasicBlock * SplitMultiBrEdge(BasicBlock *MultiBrBlock, BasicBlock *Succ, unsigned SuccIdx, BasicBlock *BrTarget=nullptr, DomTreeUpdater *DTU=nullptr, CycleInfo *CI=nullptr, LoopInfo *LI=nullptr, bool *UpdatedLI=nullptr)
Create a new intermediate target block for a callbr or switch edge.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
LLVM_ABI FunctionPass * createFixIrreduciblePass()
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
LLVM_ABI Printable printBasicBlock(const BasicBlock *BB)
Print BasicBlock BB as an operand or print "<nullptr>" if BB is a nullptr.
auto predecessors(const MachineBasicBlock *BB)
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition STLExtras.h:1947
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
LLVM_ABI void initializeFixIrreduciblePass(PassRegistry &)
LLVM_ABI void reportFatalUsageError(Error Err)
Report a fatal error that does not indicate a bug in LLVM.
Definition Error.cpp:177
Given a set of branch descriptors [BB, Succ0, Succ1], create a "hub" such that the control flow from ...
void addBranch(BasicBlock *BB, BasicBlock *Succ0, BasicBlock *Succ1=nullptr)
LLVM_ABI 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.
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)