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 "ScalarOptions.h"
24#include "llvm/ADT/MapVector.h"
27#include "llvm/ADT/Statistic.h"
29#include "llvm/Analysis/CFG.h"
33#include "llvm/IR/Attributes.h"
34#include "llvm/IR/CFG.h"
35#include "llvm/IR/Dominators.h"
37#include "llvm/IR/ValueHandle.h"
39#include "llvm/Pass.h"
44#include <utility>
45using namespace llvm;
46
47#define DEBUG_TYPE "simplifycfg"
48
49STATISTIC(NumSimpl, "Number of blocks simplified");
50
51static bool
53 std::vector<DominatorTree::UpdateType> *Updates) {
55
56 // We don't want to change IR just because we can.
57 // Only do that if there are at least two blocks we'll tail-merge.
58 if (BBs.size() < 2)
59 return false;
60
61 if (Updates)
62 Updates->reserve(Updates->size() + BBs.size());
63
64 BasicBlock *CanonicalBB;
65 Instruction *CanonicalTerm;
66 {
67 auto *Term = BBs[0]->getTerminator();
68
69 // Create a canonical block for this function terminator type now,
70 // placing it *before* the first block that will branch to it.
71 CanonicalBB = BasicBlock::Create(
72 F.getContext(), Twine("common.") + Term->getOpcodeName(), &F, BBs[0]);
73 // We'll also need a PHI node per each operand of the terminator.
74 NewOps.resize(Term->getNumOperands());
75 for (auto I : zip(Term->operands(), NewOps)) {
76 std::get<1>(I) = PHINode::Create(std::get<0>(I)->getType(),
77 /*NumReservedValues=*/BBs.size(),
78 CanonicalBB->getName() + ".op");
79 std::get<1>(I)->insertInto(CanonicalBB, CanonicalBB->end());
80 }
81 // Make it so that this canonical block actually has the right
82 // terminator.
83 CanonicalTerm = Term->clone();
84 CanonicalTerm->insertInto(CanonicalBB, CanonicalBB->end());
85 // If the canonical terminator has operands, rewrite it to take PHI's.
86 for (auto I : zip(NewOps, CanonicalTerm->operands()))
87 std::get<1>(I) = std::get<0>(I);
88 }
89
90 // Now, go through each block (with the current terminator type)
91 // we've recorded, and rewrite it to branch to the new common block.
92 DebugLoc CommonDebugLoc;
93 for (BasicBlock *BB : BBs) {
94 auto *Term = BB->getTerminator();
95 assert(Term->getOpcode() == CanonicalTerm->getOpcode() &&
96 "All blocks to be tail-merged must be the same "
97 "(function-terminating) terminator type.");
98
99 // Aha, found a new non-canonical function terminator. If it has operands,
100 // forward them to the PHI nodes in the canonical block.
101 for (auto I : zip(Term->operands(), NewOps))
102 std::get<1>(I)->addIncoming(std::get<0>(I), BB);
103
104 // Compute the debug location common to all the original terminators.
105 if (!CommonDebugLoc)
106 CommonDebugLoc = Term->getDebugLoc();
107 else
108 CommonDebugLoc =
109 DebugLoc::getMergedLocation(CommonDebugLoc, Term->getDebugLoc());
110
111 // And turn BB into a block that just unconditionally branches
112 // to the canonical block.
113 Instruction *BI = UncondBrInst::Create(CanonicalBB, BB);
114 BI->setDebugLoc(Term->getDebugLoc());
115 Term->eraseFromParent();
116
117 if (Updates)
118 Updates->push_back({DominatorTree::Insert, BB, CanonicalBB});
119 }
120
121 CanonicalTerm->setDebugLoc(CommonDebugLoc);
122
123 return true;
124}
125
127 DomTreeUpdater *DTU) {
128 SmallMapVector<unsigned /*TerminatorOpcode*/, SmallVector<BasicBlock *, 2>, 4>
129 Structure;
130
131 // Scan all the blocks in the function, record the interesting-ones.
132 for (BasicBlock &BB : F) {
133 if (DTU && DTU->isBBPendingDeletion(&BB))
134 continue;
135
136 // We are only interested in function-terminating blocks.
137 if (!succ_empty(&BB))
138 continue;
139
140 auto *Term = BB.getTerminator();
141
142 // Fow now only support `ret`/`resume` function terminators.
143 // FIXME: lift this restriction.
144 switch (Term->getOpcode()) {
145 case Instruction::Ret:
146 case Instruction::Resume:
147 break;
148 default:
149 continue;
150 }
151
152 // We can't tail-merge block that contains a musttail call.
153 if (BB.getTerminatingMustTailCall())
154 continue;
155
156 // Calls to experimental_deoptimize must be followed by a return
157 // of the value computed by experimental_deoptimize.
158 // I.e., we can not change `ret` to `br` for this block.
159 if (auto *CI = dyn_cast_or_null<CallInst>(Term->getPrevNode())) {
160 if (Function *F = CI->getCalledFunction())
161 if (Intrinsic::ID ID = F->getIntrinsicID())
162 if (ID == Intrinsic::experimental_deoptimize)
163 continue;
164 }
165
166 // PHI nodes cannot have token type, so if the terminator has an operand
167 // with token type, we can not tail-merge this kind of function terminators.
168 if (any_of(Term->operands(),
169 [](Value *Op) { return Op->getType()->isTokenTy(); }))
170 continue;
171
172 // Canonical blocks are uniqued based on the terminator type (opcode).
173 Structure[Term->getOpcode()].emplace_back(&BB);
174 }
175
176 bool Changed = false;
177
178 std::vector<DominatorTree::UpdateType> Updates;
179
180 for (ArrayRef<BasicBlock *> BBs : make_second_range(Structure))
181 Changed |= performBlockTailMerging(F, BBs, DTU ? &Updates : nullptr);
182
183 if (DTU)
184 DTU->applyUpdates(Updates);
185
186 return Changed;
187}
188
189/// Call SimplifyCFG on all the blocks in the function,
190/// iterating until no more changes are made.
192 DomTreeUpdater *DTU,
194 bool Changed = false;
195 bool LocalChange = true;
196
198 FindFunctionBackedges(F, Edges);
199 SmallPtrSet<BasicBlock *, 16> UniqueLoopHeaders;
200 for (const auto &Edge : Edges)
201 UniqueLoopHeaders.insert(const_cast<BasicBlock *>(Edge.second));
202
203 SmallVector<WeakVH, 16> LoopHeaders(UniqueLoopHeaders.begin(),
204 UniqueLoopHeaders.end());
205
206 unsigned IterCnt = 0;
207 (void)IterCnt;
208 while (LocalChange) {
209 assert(IterCnt++ < 2000 && "Iterative simplification didn't converge!");
210 LocalChange = false;
211
212 // Loop over all of the basic blocks and remove them if they are unneeded.
213 for (Function::iterator BBIt = F.begin(); BBIt != F.end(); ) {
214 BasicBlock &BB = *BBIt++;
215 if (DTU) {
216 assert(
217 !DTU->isBBPendingDeletion(&BB) &&
218 "Should not end up trying to simplify blocks marked for removal.");
219 // Make sure that the advanced iterator does not point at the blocks
220 // that are marked for removal, skip over all such blocks.
221 while (BBIt != F.end() && DTU->isBBPendingDeletion(&*BBIt))
222 ++BBIt;
223 }
224 if (simplifyCFG(&BB, TTI, DTU, Options, LoopHeaders)) {
225 LocalChange = true;
226 ++NumSimpl;
227 }
228 }
229 Changed |= LocalChange;
230 }
231 return Changed;
232}
233
235 DominatorTree *DT,
237 DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Eager);
238
239 bool EverChanged = removeUnreachableBlocks(F, DT ? &DTU : nullptr);
240 EverChanged |=
242 EverChanged |= iterativelySimplifyCFG(F, TTI, DT ? &DTU : nullptr, Options);
243
244 // If neither pass changed anything, we're done.
245 if (!EverChanged) return false;
246
247 // iterativelySimplifyCFG can (rarely) make some loops dead. If this happens,
248 // removeUnreachableBlocks is needed to nuke them, which means we should
249 // iterate between the two optimizations. We structure the code like this to
250 // avoid rerunning iterativelySimplifyCFG if the second pass of
251 // removeUnreachableBlocks doesn't do anything.
252 // Avoid scanning instructions to reduce compile-time.
253 if (!removeUnreachableBlocks(F, DT ? &DTU : nullptr, /*MSSAU=*/nullptr,
254 /*FoldInstsToUnreachable=*/false))
255 return true;
256
257 do {
258 EverChanged = iterativelySimplifyCFG(F, TTI, DT ? &DTU : nullptr, Options);
259 EverChanged |=
260 removeUnreachableBlocks(F, DT ? &DTU : nullptr, /*MSSAU=*/nullptr,
261 /*FoldInstsToUnreachable=*/false);
262 } while (EverChanged);
263
264 return true;
265}
266
268 DominatorTree *DT,
271 (DT && DT->verify(DominatorTree::VerificationLevel::Full))) &&
272 "Original domtree is invalid?");
273
275
277 (DT && DT->verify(DominatorTree::VerificationLevel::Full))) &&
278 "Failed to maintain validity of domtree!");
279
280 return Changed;
281}
282
283// Command-line settings override compile-time settings.
285 const ScalarOptions &Opts = ScalarOptions::Global;
286 if (Opts.bonus_inst_threshold)
287 Options.BonusInstThreshold = *Opts.bonus_inst_threshold;
288 Options.ForwardSwitchCondToPhi =
289 valueOr(Opts.forward_switch_cond, Options.ForwardSwitchCondToPhi);
290 Options.ConvertSwitchRangeToICmp =
291 valueOr(Opts.switch_range_to_icmp, Options.ConvertSwitchRangeToICmp);
292 Options.ConvertSwitchToLookupTable =
293 valueOr(Opts.switch_to_lookup, Options.ConvertSwitchToLookupTable);
294 Options.NeedCanonicalLoop =
295 valueOr(Opts.keep_loops, Options.NeedCanonicalLoop);
296 Options.HoistCommonInsts =
297 valueOr(Opts.hoist_common_insts, Options.HoistCommonInsts);
298 Options.HoistLoadsStoresWithCondFaulting =
299 valueOr(Opts.hoist_loads_stores_with_cond_faulting,
300 Options.HoistLoadsStoresWithCondFaulting);
301 Options.SinkCommonInsts =
302 valueOr(Opts.sink_common_insts, Options.SinkCommonInsts);
303 Options.SpeculateUnpredictables =
304 valueOr(Opts.speculate_unpredictables, Options.SpeculateUnpredictables);
305}
306
310
315
317 raw_ostream &OS, function_ref<StringRef(StringRef)> MapClassName2PassName) {
318 static_cast<PassInfoMixin<SimplifyCFGPass> *>(this)->printPipeline(
319 OS, MapClassName2PassName);
320 OS << '<';
321 OS << "bonus-inst-threshold=" << Options.BonusInstThreshold << ';';
322 OS << (Options.ForwardSwitchCondToPhi ? "" : "no-") << "forward-switch-cond;";
323 OS << (Options.ConvertSwitchRangeToICmp ? "" : "no-")
324 << "switch-range-to-icmp;";
325 OS << (Options.ConvertSwitchToArithmetic ? "" : "no-")
326 << "switch-to-arithmetic;";
327 OS << (Options.ConvertSwitchToLookupTable ? "" : "no-")
328 << "switch-to-lookup;";
329 OS << (Options.NeedCanonicalLoop ? "" : "no-") << "keep-loops;";
330 OS << (Options.HoistCommonInsts ? "" : "no-") << "hoist-common-insts;";
331 OS << (Options.HoistLoadsStoresWithCondFaulting ? "" : "no-")
332 << "hoist-loads-stores-with-cond-faulting;";
333 OS << (Options.SinkCommonInsts ? "" : "no-") << "sink-common-insts;";
334 OS << (Options.SpeculateBlocks ? "" : "no-") << "speculate-blocks;";
335 OS << (Options.SimplifyCondBranch ? "" : "no-") << "simplify-cond-branch;";
336 OS << (Options.SpeculateUnpredictables ? "" : "no-")
337 << "speculate-unpredictables";
338 OS << '>';
339}
340
343 auto &TTI = AM.getResult<TargetIRAnalysis>(F);
344 Options.AC = &AM.getResult<AssumptionAnalysis>(F);
345 DominatorTree *DT = nullptr;
348 if (!simplifyFunctionCFG(F, TTI, DT, Options))
349 return PreservedAnalyses::all();
350 // If we removed some blocks, update block numbers to keep dense numbering.
351 F.renumberBlocks();
354 DT->updateBlockNumbers();
356 }
357 return PA;
358}
359
360namespace {
361struct CFGSimplifyPass : public FunctionPass {
362 static char ID;
364 std::function<bool(const Function &)> PredicateFtor;
365
366 CFGSimplifyPass(SimplifyCFGOptions Options_ = SimplifyCFGOptions(),
367 std::function<bool(const Function &)> Ftor = nullptr)
368 : FunctionPass(ID), Options(Options_), PredicateFtor(std::move(Ftor)) {
369
371
372 // Check for command-line overrides of options for debug/customization.
374 }
375
376 bool runOnFunction(Function &F) override {
377 if (skipFunction(F) || (PredicateFtor && !PredicateFtor(F)))
378 return false;
379
380 Options.AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
381 DominatorTree *DT = nullptr;
383 DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
384
385 auto &TTI = getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
386 return simplifyFunctionCFG(F, TTI, DT, Options);
387 }
388 void getAnalysisUsage(AnalysisUsage &AU) const override {
389 AU.addRequired<AssumptionCacheTracker>();
391 AU.addRequired<DominatorTreeWrapperPass>();
392 AU.addRequired<TargetTransformInfoWrapperPass>();
394 AU.addPreserved<DominatorTreeWrapperPass>();
395 AU.addPreserved<GlobalsAAWrapperPass>();
396 }
397};
398}
399
400char CFGSimplifyPass::ID = 0;
401INITIALIZE_PASS_BEGIN(CFGSimplifyPass, "simplifycfg", "Simplify the CFG", false,
402 false)
406INITIALIZE_PASS_END(CFGSimplifyPass, "simplifycfg", "Simplify the CFG", false,
407 false)
408
409// Public interface to the CFGSimplification pass
412 std::function<bool(const Function &)> Ftor) {
413 return new CFGSimplifyPass(Options, std::move(Ftor));
414}
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 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 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 void applyCommandLineOverridesToOptions(SimplifyCFGOptions &Options)
static bool tailMergeBlocksWithSimilarFunctionTerminators(Function &F, DomTreeUpdater *DTU)
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:186
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
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:846
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:2916
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:1762
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:1425
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:1933
LLVM_ABI bool simplifyCFG(BasicBlock *BB, const TargetTransformInfo &TTI, DomTreeUpdater *DTU=nullptr, const SimplifyCFGOptions &Options={}, ArrayRef< WeakVH > LoopHeaders={})
constexpr bool valueOr(BoolOrDefault X, bool Default)
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 MapVector that performs no allocations if smaller than a certain size.
Definition MapVector.h:342