LLVM 22.0.0git
SimplifyCFGPass.cpp
Go to the documentation of this file.
1//===- SimplifyCFGPass.cpp - CFG Simplification Pass ----------------------===//
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// This file implements dead code elimination and basic block merging, along
10// with a collection of other peephole control flow optimizations. For example:
11//
12// * Removes basic blocks with no predecessors.
13// * Merges a basic block into its predecessor if there is only one and the
14// predecessor only has one successor.
15// * Eliminates PHI nodes for basic blocks with a single predecessor.
16// * Eliminates a basic block that only contains an unconditional branch.
17// * Changes invoke instructions to nounwind functions to be calls.
18// * Change things like "if (x) if (y)" into "if (x&y)".
19// * etc..
20//
21//===----------------------------------------------------------------------===//
22
23#include "llvm/ADT/MapVector.h"
26#include "llvm/ADT/Statistic.h"
28#include "llvm/Analysis/CFG.h"
32#include "llvm/IR/Attributes.h"
33#include "llvm/IR/CFG.h"
34#include "llvm/IR/Dominators.h"
36#include "llvm/IR/ValueHandle.h"
38#include "llvm/Pass.h"
44#include <utility>
45using namespace llvm;
46
47#define DEBUG_TYPE "simplifycfg"
48
50 "bonus-inst-threshold", cl::Hidden, cl::init(1),
51 cl::desc("Control the number of bonus instructions (default = 1)"));
52
54 "keep-loops", cl::Hidden, cl::init(true),
55 cl::desc("Preserve canonical loop structure (default = true)"));
56
58 "switch-range-to-icmp", cl::Hidden, cl::init(false),
60 "Convert switches into an integer range comparison (default = false)"));
61
63 "switch-to-lookup", cl::Hidden, cl::init(false),
64 cl::desc("Convert switches to lookup tables (default = false)"));
65
67 "forward-switch-cond", cl::Hidden, cl::init(false),
68 cl::desc("Forward switch condition to phi ops (default = false)"));
69
71 "hoist-common-insts", cl::Hidden, cl::init(false),
72 cl::desc("hoist common instructions (default = false)"));
73
75 "hoist-loads-stores-with-cond-faulting", cl::Hidden, cl::init(false),
76 cl::desc("Hoist loads/stores if the target supports conditional faulting "
77 "(default = false)"));
78
80 "sink-common-insts", cl::Hidden, cl::init(false),
81 cl::desc("Sink common instructions (default = false)"));
82
84 "speculate-unpredictables", cl::Hidden, cl::init(false),
85 cl::desc("Speculate unpredictable branches (default = false)"));
86
87STATISTIC(NumSimpl, "Number of blocks simplified");
88
89static bool
91 std::vector<DominatorTree::UpdateType> *Updates) {
93
94 // We don't want to change IR just because we can.
95 // Only do that if there are at least two blocks we'll tail-merge.
96 if (BBs.size() < 2)
97 return false;
98
99 if (Updates)
100 Updates->reserve(Updates->size() + BBs.size());
101
102 BasicBlock *CanonicalBB;
103 Instruction *CanonicalTerm;
104 {
105 auto *Term = BBs[0]->getTerminator();
106
107 // Create a canonical block for this function terminator type now,
108 // placing it *before* the first block that will branch to it.
109 CanonicalBB = BasicBlock::Create(
110 F.getContext(), Twine("common.") + Term->getOpcodeName(), &F, BBs[0]);
111 // We'll also need a PHI node per each operand of the terminator.
112 NewOps.resize(Term->getNumOperands());
113 for (auto I : zip(Term->operands(), NewOps)) {
114 std::get<1>(I) = PHINode::Create(std::get<0>(I)->getType(),
115 /*NumReservedValues=*/BBs.size(),
116 CanonicalBB->getName() + ".op");
117 std::get<1>(I)->insertInto(CanonicalBB, CanonicalBB->end());
118 }
119 // Make it so that this canonical block actually has the right
120 // terminator.
121 CanonicalTerm = Term->clone();
122 CanonicalTerm->insertInto(CanonicalBB, CanonicalBB->end());
123 // If the canonical terminator has operands, rewrite it to take PHI's.
124 for (auto I : zip(NewOps, CanonicalTerm->operands()))
125 std::get<1>(I) = std::get<0>(I);
126 }
127
128 // Now, go through each block (with the current terminator type)
129 // we've recorded, and rewrite it to branch to the new common block.
130 DebugLoc CommonDebugLoc;
131 for (BasicBlock *BB : BBs) {
132 auto *Term = BB->getTerminator();
133 assert(Term->getOpcode() == CanonicalTerm->getOpcode() &&
134 "All blocks to be tail-merged must be the same "
135 "(function-terminating) terminator type.");
136
137 // Aha, found a new non-canonical function terminator. If it has operands,
138 // forward them to the PHI nodes in the canonical block.
139 for (auto I : zip(Term->operands(), NewOps))
140 std::get<1>(I)->addIncoming(std::get<0>(I), BB);
141
142 // Compute the debug location common to all the original terminators.
143 if (!CommonDebugLoc)
144 CommonDebugLoc = Term->getDebugLoc();
145 else
146 CommonDebugLoc =
147 DebugLoc::getMergedLocation(CommonDebugLoc, Term->getDebugLoc());
148
149 // And turn BB into a block that just unconditionally branches
150 // to the canonical block.
151 Instruction *BI = BranchInst::Create(CanonicalBB, BB);
152 BI->setDebugLoc(Term->getDebugLoc());
153 Term->eraseFromParent();
154
155 if (Updates)
156 Updates->push_back({DominatorTree::Insert, BB, CanonicalBB});
157 }
158
159 CanonicalTerm->setDebugLoc(CommonDebugLoc);
160
161 return true;
162}
163
165 DomTreeUpdater *DTU) {
166 SmallMapVector<unsigned /*TerminatorOpcode*/, SmallVector<BasicBlock *, 2>, 4>
167 Structure;
168
169 // Scan all the blocks in the function, record the interesting-ones.
170 for (BasicBlock &BB : F) {
171 if (DTU && DTU->isBBPendingDeletion(&BB))
172 continue;
173
174 // We are only interested in function-terminating blocks.
175 if (!succ_empty(&BB))
176 continue;
177
178 auto *Term = BB.getTerminator();
179
180 // Fow now only support `ret`/`resume` function terminators.
181 // FIXME: lift this restriction.
182 switch (Term->getOpcode()) {
183 case Instruction::Ret:
184 case Instruction::Resume:
185 break;
186 default:
187 continue;
188 }
189
190 // We can't tail-merge block that contains a musttail call.
191 if (BB.getTerminatingMustTailCall())
192 continue;
193
194 // Calls to experimental_deoptimize must be followed by a return
195 // of the value computed by experimental_deoptimize.
196 // I.e., we can not change `ret` to `br` for this block.
197 if (auto *CI = dyn_cast_or_null<CallInst>(Term->getPrevNode())) {
198 if (Function *F = CI->getCalledFunction())
199 if (Intrinsic::ID ID = F->getIntrinsicID())
200 if (ID == Intrinsic::experimental_deoptimize)
201 continue;
202 }
203
204 // PHI nodes cannot have token type, so if the terminator has an operand
205 // with token type, we can not tail-merge this kind of function terminators.
206 if (any_of(Term->operands(),
207 [](Value *Op) { return Op->getType()->isTokenTy(); }))
208 continue;
209
210 // Canonical blocks are uniqued based on the terminator type (opcode).
211 Structure[Term->getOpcode()].emplace_back(&BB);
212 }
213
214 bool Changed = false;
215
216 std::vector<DominatorTree::UpdateType> Updates;
217
218 for (ArrayRef<BasicBlock *> BBs : make_second_range(Structure))
219 Changed |= performBlockTailMerging(F, BBs, DTU ? &Updates : nullptr);
220
221 if (DTU)
222 DTU->applyUpdates(Updates);
223
224 return Changed;
225}
226
227/// Call SimplifyCFG on all the blocks in the function,
228/// iterating until no more changes are made.
230 DomTreeUpdater *DTU,
232 bool Changed = false;
233 bool LocalChange = true;
234
236 FindFunctionBackedges(F, Edges);
237 SmallPtrSet<BasicBlock *, 16> UniqueLoopHeaders;
238 for (const auto &Edge : Edges)
239 UniqueLoopHeaders.insert(const_cast<BasicBlock *>(Edge.second));
240
241 SmallVector<WeakVH, 16> LoopHeaders(UniqueLoopHeaders.begin(),
242 UniqueLoopHeaders.end());
243
244 unsigned IterCnt = 0;
245 (void)IterCnt;
246 while (LocalChange) {
247 assert(IterCnt++ < 1000 && "Iterative simplification didn't converge!");
248 LocalChange = false;
249
250 // Loop over all of the basic blocks and remove them if they are unneeded.
251 for (Function::iterator BBIt = F.begin(); BBIt != F.end(); ) {
252 BasicBlock &BB = *BBIt++;
253 if (DTU) {
254 assert(
255 !DTU->isBBPendingDeletion(&BB) &&
256 "Should not end up trying to simplify blocks marked for removal.");
257 // Make sure that the advanced iterator does not point at the blocks
258 // that are marked for removal, skip over all such blocks.
259 while (BBIt != F.end() && DTU->isBBPendingDeletion(&*BBIt))
260 ++BBIt;
261 }
262 if (simplifyCFG(&BB, TTI, DTU, Options, LoopHeaders)) {
263 LocalChange = true;
264 ++NumSimpl;
265 }
266 }
267 Changed |= LocalChange;
268 }
269 return Changed;
270}
271
273 DominatorTree *DT,
275 DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Eager);
276
277 bool EverChanged = removeUnreachableBlocks(F, DT ? &DTU : nullptr);
278 EverChanged |=
280 EverChanged |= iterativelySimplifyCFG(F, TTI, DT ? &DTU : nullptr, Options);
281
282 // If neither pass changed anything, we're done.
283 if (!EverChanged) return false;
284
285 // iterativelySimplifyCFG can (rarely) make some loops dead. If this happens,
286 // removeUnreachableBlocks is needed to nuke them, which means we should
287 // iterate between the two optimizations. We structure the code like this to
288 // avoid rerunning iterativelySimplifyCFG if the second pass of
289 // removeUnreachableBlocks doesn't do anything.
290 if (!removeUnreachableBlocks(F, DT ? &DTU : nullptr))
291 return true;
292
293 do {
294 EverChanged = iterativelySimplifyCFG(F, TTI, DT ? &DTU : nullptr, Options);
295 EverChanged |= removeUnreachableBlocks(F, DT ? &DTU : nullptr);
296 } while (EverChanged);
297
298 return true;
299}
300
302 DominatorTree *DT,
305 (DT && DT->verify(DominatorTree::VerificationLevel::Full))) &&
306 "Original domtree is invalid?");
307
308 bool Changed = simplifyFunctionCFGImpl(F, TTI, DT, Options);
309
311 (DT && DT->verify(DominatorTree::VerificationLevel::Full))) &&
312 "Failed to maintain validity of domtree!");
313
314 return Changed;
315}
316
317// Command-line settings override compile-time settings.
319 if (UserBonusInstThreshold.getNumOccurrences())
320 Options.BonusInstThreshold = UserBonusInstThreshold;
322 Options.ForwardSwitchCondToPhi = UserForwardSwitchCond;
324 Options.ConvertSwitchRangeToICmp = UserSwitchRangeToICmp;
326 Options.ConvertSwitchToLookupTable = UserSwitchToLookup;
328 Options.NeedCanonicalLoop = UserKeepLoops;
330 Options.HoistCommonInsts = UserHoistCommonInsts;
332 Options.HoistLoadsStoresWithCondFaulting =
335 Options.SinkCommonInsts = UserSinkCommonInsts;
337 Options.SpeculateUnpredictables = UserSpeculateUnpredictables;
338}
339
342}
343
345 : Options(Opts) {
347}
348
350 raw_ostream &OS, function_ref<StringRef(StringRef)> MapClassName2PassName) {
351 static_cast<PassInfoMixin<SimplifyCFGPass> *>(this)->printPipeline(
352 OS, MapClassName2PassName);
353 OS << '<';
354 OS << "bonus-inst-threshold=" << Options.BonusInstThreshold << ';';
355 OS << (Options.ForwardSwitchCondToPhi ? "" : "no-") << "forward-switch-cond;";
356 OS << (Options.ConvertSwitchRangeToICmp ? "" : "no-")
357 << "switch-range-to-icmp;";
358 OS << (Options.ConvertSwitchToLookupTable ? "" : "no-")
359 << "switch-to-lookup;";
360 OS << (Options.NeedCanonicalLoop ? "" : "no-") << "keep-loops;";
361 OS << (Options.HoistCommonInsts ? "" : "no-") << "hoist-common-insts;";
362 OS << (Options.HoistLoadsStoresWithCondFaulting ? "" : "no-")
363 << "hoist-loads-stores-with-cond-faulting;";
364 OS << (Options.SinkCommonInsts ? "" : "no-") << "sink-common-insts;";
365 OS << (Options.SpeculateBlocks ? "" : "no-") << "speculate-blocks;";
366 OS << (Options.SimplifyCondBranch ? "" : "no-") << "simplify-cond-branch;";
367 OS << (Options.SpeculateUnpredictables ? "" : "no-")
368 << "speculate-unpredictables";
369 OS << '>';
370}
371
374 auto &TTI = AM.getResult<TargetIRAnalysis>(F);
375 Options.AC = &AM.getResult<AssumptionAnalysis>(F);
376 DominatorTree *DT = nullptr;
379 if (!simplifyFunctionCFG(F, TTI, DT, Options))
380 return PreservedAnalyses::all();
384 return PA;
385}
386
387namespace {
388struct CFGSimplifyPass : public FunctionPass {
389 static char ID;
391 std::function<bool(const Function &)> PredicateFtor;
392
393 CFGSimplifyPass(SimplifyCFGOptions Options_ = SimplifyCFGOptions(),
394 std::function<bool(const Function &)> Ftor = nullptr)
395 : FunctionPass(ID), Options(Options_), PredicateFtor(std::move(Ftor)) {
396
398
399 // Check for command-line overrides of options for debug/customization.
401 }
402
403 bool runOnFunction(Function &F) override {
404 if (skipFunction(F) || (PredicateFtor && !PredicateFtor(F)))
405 return false;
406
407 Options.AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
408 DominatorTree *DT = nullptr;
410 DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
411
412 auto &TTI = getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
413 return simplifyFunctionCFG(F, TTI, DT, Options);
414 }
415 void getAnalysisUsage(AnalysisUsage &AU) const override {
423 }
424};
425}
426
427char CFGSimplifyPass::ID = 0;
428INITIALIZE_PASS_BEGIN(CFGSimplifyPass, "simplifycfg", "Simplify the CFG", false,
429 false)
433INITIALIZE_PASS_END(CFGSimplifyPass, "simplifycfg", "Simplify the CFG", false,
434 false)
435
436// Public interface to the CFGSimplification pass
439 std::function<bool(const Function &)> Ftor) {
440 return new CFGSimplifyPass(Options, std::move(Ftor));
441}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
aarch64 promote const
This file contains the simple types necessary to represent the attributes associated with functions a...
Performs the initial survey of the specified function
static bool runOnFunction(Function &F, bool PostInlining)
Flatten the CFG
This is the interface for a simple mod/ref and alias analysis over globals.
This file provides various utilities for inspecting and working with the control flow graph in LLVM I...
static LVOptions Options
Definition: LVOptions.cpp:25
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
This file implements a map that provides insertion order iteration.
#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
std::pair< BasicBlock *, BasicBlock * > Edge
raw_pwrite_stream & OS
static cl::opt< bool > UserSwitchRangeToICmp("switch-range-to-icmp", cl::Hidden, cl::init(false), cl::desc("Convert switches into an integer range comparison (default = false)"))
static cl::opt< bool > UserSinkCommonInsts("sink-common-insts", cl::Hidden, cl::init(false), cl::desc("Sink common instructions (default = false)"))
static bool iterativelySimplifyCFG(Function &F, const TargetTransformInfo &TTI, DomTreeUpdater *DTU, const SimplifyCFGOptions &Options)
Call SimplifyCFG on all the blocks in the function, iterating until no more changes are made.
static cl::opt< unsigned > UserBonusInstThreshold("bonus-inst-threshold", cl::Hidden, cl::init(1), cl::desc("Control the number of bonus instructions (default = 1)"))
static bool simplifyFunctionCFGImpl(Function &F, const TargetTransformInfo &TTI, DominatorTree *DT, const SimplifyCFGOptions &Options)
static bool simplifyFunctionCFG(Function &F, const TargetTransformInfo &TTI, DominatorTree *DT, const SimplifyCFGOptions &Options)
static cl::opt< bool > UserSwitchToLookup("switch-to-lookup", cl::Hidden, cl::init(false), cl::desc("Convert switches to lookup tables (default = false)"))
static cl::opt< bool > UserHoistLoadsStoresWithCondFaulting("hoist-loads-stores-with-cond-faulting", cl::Hidden, cl::init(false), cl::desc("Hoist loads/stores if the target supports conditional faulting " "(default = false)"))
static cl::opt< bool > UserKeepLoops("keep-loops", cl::Hidden, cl::init(true), cl::desc("Preserve canonical loop structure (default = true)"))
static cl::opt< bool > UserHoistCommonInsts("hoist-common-insts", cl::Hidden, cl::init(false), cl::desc("hoist common instructions (default = false)"))
simplifycfg
static cl::opt< bool > UserSpeculateUnpredictables("speculate-unpredictables", cl::Hidden, cl::init(false), cl::desc("Speculate unpredictable branches (default = false)"))
static void applyCommandLineOverridesToOptions(SimplifyCFGOptions &Options)
static bool tailMergeBlocksWithSimilarFunctionTerminators(Function &F, DomTreeUpdater *DTU)
static cl::opt< bool > UserForwardSwitchCond("forward-switch-cond", cl::Hidden, cl::init(false), cl::desc("Forward switch condition to phi ops (default = false)"))
static bool performBlockTailMerging(Function &F, ArrayRef< BasicBlock * > BBs, std::vector< DominatorTree::UpdateType > *Updates)
This file provides the interface for the pass responsible for both simplifying and canonicalizing the...
This file defines the SmallPtrSet class.
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)
Definition: Statistic.h:167
static SymbolRef::Type getType(const Symbol *Sym)
Definition: TapiFile.cpp:39
This pass exposes codegen information to IR-level passes.
A container for analyses that lazily runs them and caches their results.
Definition: PassManager.h:255
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Definition: PassManager.h:412
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.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:147
A function analysis which provides an AssumptionCache.
An immutable pass that tracks lazily created AssumptionCache objects.
LLVM Basic Block Representation.
Definition: BasicBlock.h:62
iterator end()
Definition: BasicBlock.h:472
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Definition: BasicBlock.h:206
static BranchInst * Create(BasicBlock *IfTrue, InsertPosition InsertBefore=nullptr)
This class represents an Operation in the Expression.
A debug info location.
Definition: DebugLoc.h:124
static LLVM_ABI DebugLoc getMergedLocation(DebugLoc LocA, DebugLoc LocB)
When two instructions are combined into a single instruction we also need to combine the original loc...
Definition: DebugLoc.cpp:183
Analysis pass which computes a DominatorTree.
Definition: Dominators.h:284
bool verify(VerificationLevel VL=VerificationLevel::Full) const
verify - checks if the tree is correct.
Legacy analysis pass which computes a DominatorTree.
Definition: Dominators.h:322
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Definition: Dominators.h:165
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:314
BasicBlockListType::iterator iterator
Definition: Function.h:69
void applyUpdates(ArrayRef< UpdateT > Updates)
Submit updates to all available trees.
bool isBBPendingDeletion(BasicBlockT *DelBB) const
Returns true if DelBB is awaiting deletion.
Legacy wrapper pass to provide the GlobalsAAResult object.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
Definition: Instruction.h:312
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
Definition: Instruction.h:510
LLVM_ABI InstListType::iterator insertInto(BasicBlock *ParentBB, InstListType::iterator It)
Inserts an unlinked instruction into ParentBB at position It and returns the iterator of the inserted...
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...
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
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Run the pass over the function.
LLVM_ABI SimplifyCFGPass()
The default constructor sets the pass options to create canonical IR, rather than optimal IR.
LLVM_ABI void printPipeline(raw_ostream &OS, function_ref< StringRef(StringRef)> MapClassName2PassName)
iterator end() const
Definition: SmallPtrSet.h:499
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
Definition: SmallPtrSet.h:401
iterator begin() const
Definition: SmallPtrSet.h:494
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
Definition: SmallPtrSet.h:541
void reserve(size_type N)
Definition: SmallVector.h:664
void resize(size_type N)
Definition: SmallVector.h:639
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1197
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:55
Analysis pass providing the TargetTransformInfo.
Wrapper pass for TargetTransformInfo.
This pass provides access to the codegen interfaces that are needed for IR-level transformations.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:82
op_range operands()
Definition: User.h:292
LLVM Value Representation.
Definition: Value.h:75
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition: Value.cpp:322
int getNumOccurrences() const
Definition: CommandLine.h:400
An efficient, type-erasing, non-owning reference to a callable.
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:53
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:444
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
detail::zippy< detail::zip_shortest, T, U, Args... > zip(T &&t, U &&u, Args &&...args)
zip iterator for two or more iteratable types.
Definition: STLExtras.h:860
LLVM_ABI FunctionPass * createCFGSimplificationPass(SimplifyCFGOptions Options=SimplifyCFGOptions(), std::function< bool(const Function &)> Ftor=nullptr)
bool succ_empty(const Instruction *I)
Definition: CFG.h:256
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1751
LLVM_ABI cl::opt< bool > RequireAndPreserveDomTree
This function is used to do simplification of a CFG.
auto make_second_range(ContainerTy &&c)
Given a container of pairs, return a range over the second elements.
Definition: STLExtras.h:1454
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1886
LLVM_ABI bool simplifyCFG(BasicBlock *BB, const TargetTransformInfo &TTI, DomTreeUpdater *DTU=nullptr, const SimplifyCFGOptions &Options={}, ArrayRef< WeakVH > LoopHeaders={})
LLVM_ABI void FindFunctionBackedges(const Function &F, SmallVectorImpl< std::pair< const BasicBlock *, const BasicBlock * > > &Result)
Analyze the specified function to find all of the loop backedges in the function and return them.
Definition: CFG.cpp:35
LLVM_ABI bool removeUnreachableBlocks(Function &F, DomTreeUpdater *DTU=nullptr, MemorySSAUpdater *MSSAU=nullptr)
Remove all blocks that can not be reached from the function's entry.
Definition: Local.cpp:2883
LLVM_ABI void initializeCFGSimplifyPassPass(PassRegistry &)
Implement std::hash so that hash_code can be used in STL containers.
Definition: BitVector.h:856
A CRTP mix-in to automatically provide informational APIs needed for passes.
Definition: PassManager.h:70
A MapVector that performs no allocations if smaller than a certain size.
Definition: MapVector.h:249