LLVM 24.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 = UncondBrInst::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++ < 2000 && "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 // Avoid scanning instructions to reduce compile-time.
291 if (!removeUnreachableBlocks(F, DT ? &DTU : nullptr, /*MSSAU=*/nullptr,
292 /*FoldInstsToUnreachable=*/false))
293 return true;
294
295 do {
296 EverChanged = iterativelySimplifyCFG(F, TTI, DT ? &DTU : nullptr, Options);
297 EverChanged |=
298 removeUnreachableBlocks(F, DT ? &DTU : nullptr, /*MSSAU=*/nullptr,
299 /*FoldInstsToUnreachable=*/false);
300 } while (EverChanged);
301
302 return true;
303}
304
306 DominatorTree *DT,
309 (DT && DT->verify(DominatorTree::VerificationLevel::Full))) &&
310 "Original domtree is invalid?");
311
313
315 (DT && DT->verify(DominatorTree::VerificationLevel::Full))) &&
316 "Failed to maintain validity of domtree!");
317
318 return Changed;
319}
320
321// Command-line settings override compile-time settings.
323 if (UserBonusInstThreshold.getNumOccurrences())
324 Options.BonusInstThreshold = UserBonusInstThreshold;
325 if (UserForwardSwitchCond.getNumOccurrences())
326 Options.ForwardSwitchCondToPhi = UserForwardSwitchCond;
327 if (UserSwitchRangeToICmp.getNumOccurrences())
328 Options.ConvertSwitchRangeToICmp = UserSwitchRangeToICmp;
329 if (UserSwitchToLookup.getNumOccurrences())
330 Options.ConvertSwitchToLookupTable = UserSwitchToLookup;
331 if (UserKeepLoops.getNumOccurrences())
332 Options.NeedCanonicalLoop = UserKeepLoops;
333 if (UserHoistCommonInsts.getNumOccurrences())
334 Options.HoistCommonInsts = UserHoistCommonInsts;
335 if (UserHoistLoadsStoresWithCondFaulting.getNumOccurrences())
336 Options.HoistLoadsStoresWithCondFaulting =
338 if (UserSinkCommonInsts.getNumOccurrences())
339 Options.SinkCommonInsts = UserSinkCommonInsts;
340 if (UserSpeculateUnpredictables.getNumOccurrences())
341 Options.SpeculateUnpredictables = UserSpeculateUnpredictables;
342}
343
347
352
354 raw_ostream &OS, function_ref<StringRef(StringRef)> MapClassName2PassName) {
355 static_cast<PassInfoMixin<SimplifyCFGPass> *>(this)->printPipeline(
356 OS, MapClassName2PassName);
357 OS << '<';
358 OS << "bonus-inst-threshold=" << Options.BonusInstThreshold << ';';
359 OS << (Options.ForwardSwitchCondToPhi ? "" : "no-") << "forward-switch-cond;";
360 OS << (Options.ConvertSwitchRangeToICmp ? "" : "no-")
361 << "switch-range-to-icmp;";
362 OS << (Options.ConvertSwitchToArithmetic ? "" : "no-")
363 << "switch-to-arithmetic;";
364 OS << (Options.ConvertSwitchToLookupTable ? "" : "no-")
365 << "switch-to-lookup;";
366 OS << (Options.NeedCanonicalLoop ? "" : "no-") << "keep-loops;";
367 OS << (Options.HoistCommonInsts ? "" : "no-") << "hoist-common-insts;";
368 OS << (Options.HoistLoadsStoresWithCondFaulting ? "" : "no-")
369 << "hoist-loads-stores-with-cond-faulting;";
370 OS << (Options.SinkCommonInsts ? "" : "no-") << "sink-common-insts;";
371 OS << (Options.SpeculateBlocks ? "" : "no-") << "speculate-blocks;";
372 OS << (Options.SimplifyCondBranch ? "" : "no-") << "simplify-cond-branch;";
373 OS << (Options.SpeculateUnpredictables ? "" : "no-")
374 << "speculate-unpredictables";
375 OS << '>';
376}
377
380 auto &TTI = AM.getResult<TargetIRAnalysis>(F);
381 Options.AC = &AM.getResult<AssumptionAnalysis>(F);
382 DominatorTree *DT = nullptr;
385 if (!simplifyFunctionCFG(F, TTI, DT, Options))
386 return PreservedAnalyses::all();
387 // If we removed some blocks, update block numbers to keep dense numbering.
388 F.renumberBlocks();
391 DT->updateBlockNumbers();
393 }
394 return PA;
395}
396
397namespace {
398struct CFGSimplifyPass : public FunctionPass {
399 static char ID;
401 std::function<bool(const Function &)> PredicateFtor;
402
403 CFGSimplifyPass(SimplifyCFGOptions Options_ = SimplifyCFGOptions(),
404 std::function<bool(const Function &)> Ftor = nullptr)
405 : FunctionPass(ID), Options(Options_), PredicateFtor(std::move(Ftor)) {
406
408
409 // Check for command-line overrides of options for debug/customization.
411 }
412
413 bool runOnFunction(Function &F) override {
414 if (skipFunction(F) || (PredicateFtor && !PredicateFtor(F)))
415 return false;
416
417 Options.AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
418 DominatorTree *DT = nullptr;
420 DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
421
422 auto &TTI = getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
423 return simplifyFunctionCFG(F, TTI, DT, Options);
424 }
425 void getAnalysisUsage(AnalysisUsage &AU) const override {
426 AU.addRequired<AssumptionCacheTracker>();
428 AU.addRequired<DominatorTreeWrapperPass>();
429 AU.addRequired<TargetTransformInfoWrapperPass>();
431 AU.addPreserved<DominatorTreeWrapperPass>();
432 AU.addPreserved<GlobalsAAWrapperPass>();
433 }
434};
435}
436
437char CFGSimplifyPass::ID = 0;
438INITIALIZE_PASS_BEGIN(CFGSimplifyPass, "simplifycfg", "Simplify the CFG", false,
439 false)
443INITIALIZE_PASS_END(CFGSimplifyPass, "simplifycfg", "Simplify the CFG", false,
444 false)
445
446// Public interface to the CFGSimplification pass
449 std::function<bool(const Function &)> Ftor) {
450 return new CFGSimplifyPass(Options, std::move(Ftor));
451}
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...
static bool runOnFunction(Function &F, bool PostInlining)
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:54
#define I(x, y, z)
Definition MD5.cpp:57
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
dot regions Print regions of function to dot true view regions View regions of function(with no function bodies)"
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)"))
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:171
static SymbolRef::Type getType(const Symbol *Sym)
Definition TapiFile.cpp:39
This pass exposes codegen information to IR-level passes.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
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
size_t size() const
Get the array size.
Definition ArrayRef.h:141
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:459
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Definition BasicBlock.h:206
A debug info location.
Definition DebugLoc.h:126
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:172
Analysis pass which computes a DominatorTree.
Definition Dominators.h:241
bool verify(VerificationLevel VL=VerificationLevel::Full) const
verify - checks if the tree is correct.
Legacy analysis pass which computes a DominatorTree.
Definition Dominators.h:277
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Definition Dominators.h:122
FunctionPass class - This class is used to implement most global optimizations.
Definition Pass.h:314
BasicBlockListType::iterator iterator
Definition Function.h:70
void applyUpdates(ArrayRef< UpdateT > Updates)
Submit updates to all available trees.
bool isBBPendingDeletion(BasicBlockT *DelBB) const
Returns true if DelBB is awaiting deletion.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
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
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
iterator begin() const
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
void resize(size_type N)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
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
static UncondBrInst * Create(BasicBlock *Target, InsertPosition InsertBefore=nullptr)
op_range operands()
Definition User.h:267
LLVM Value Representation.
Definition Value.h:75
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:319
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
Changed
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
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:830
LLVM_ABI FunctionPass * createCFGSimplificationPass(SimplifyCFGOptions Options=SimplifyCFGOptions(), std::function< bool(const Function &)> Ftor=nullptr)
bool succ_empty(const Instruction *I)
Definition CFG.h:141
LLVM_ABI bool removeUnreachableBlocks(Function &F, DomTreeUpdater *DTU=nullptr, MemorySSAUpdater *MSSAU=nullptr, bool FoldInstsToUnreachable=true)
Remove all blocks that can not be reached from the function's entry.
Definition Local.cpp:2922
auto dyn_cast_or_null(const Y &Val)
Definition Casting.h:753
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:1746
TargetTransformInfo TTI
LLVM_ABI cl::opt< bool > RequireAndPreserveDomTree
This function is used to do simplification of a CFG.
DWARFExpression::Operation Op
auto make_second_range(ContainerTy &&c)
Given a container of pairs, return a range over the second elements.
Definition STLExtras.h:1409
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:1917
LLVM_ABI bool simplifyCFG(BasicBlock *BB, const TargetTransformInfo &TTI, DomTreeUpdater *DTU=nullptr, const SimplifyCFGOptions &Options={}, ArrayRef< WeakVH > LoopHeaders={})
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
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:36
LLVM_ABI void initializeCFGSimplifyPassPass(PassRegistry &)
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:878
A CRTP mix-in to automatically provide informational APIs needed for passes.
Definition PassManager.h:89
A MapVector that performs no allocations if smaller than a certain size.
Definition MapVector.h:342