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/SmallPtrSet.h"
24 #include "llvm/ADT/SmallVector.h"
25 #include "llvm/ADT/Statistic.h"
26 #include "llvm/Analysis/AssumptionCache.h"
27 #include "llvm/Analysis/CFG.h"
28 #include "llvm/Analysis/DomTreeUpdater.h"
29 #include "llvm/Analysis/GlobalsModRef.h"
30 #include "llvm/Analysis/TargetTransformInfo.h"
31 #include "llvm/IR/Attributes.h"
32 #include "llvm/IR/CFG.h"
33 #include "llvm/IR/Constants.h"
34 #include "llvm/IR/DataLayout.h"
35 #include "llvm/IR/Dominators.h"
36 #include "llvm/IR/Instructions.h"
37 #include "llvm/IR/IntrinsicInst.h"
38 #include "llvm/IR/Module.h"
39 #include "llvm/IR/ValueHandle.h"
40 #include "llvm/InitializePasses.h"
41 #include "llvm/Pass.h"
42 #include "llvm/Support/CommandLine.h"
43 #include "llvm/Transforms/Scalar.h"
44 #include "llvm/Transforms/Scalar/SimplifyCFG.h"
45 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
46 #include "llvm/Transforms/Utils/Local.h"
47 #include "llvm/Transforms/Utils/SimplifyCFGOptions.h"
48 #include <utility>
49 using namespace llvm;
50
51 #define DEBUG_TYPE "simplifycfg"
52
53 static cl::opt<unsigned> UserBonusInstThreshold(
54 "bonus-inst-threshold", cl::Hidden, cl::init(1),
55 cl::desc("Control the number of bonus instructions (default = 1)"));
56
57 static cl::opt<bool> UserKeepLoops(
58 "keep-loops", cl::Hidden, cl::init(true),
59 cl::desc("Preserve canonical loop structure (default = true)"));
60
61 static cl::opt<bool> UserSwitchToLookup(
62 "switch-to-lookup", cl::Hidden, cl::init(false),
63 cl::desc("Convert switches to lookup tables (default = false)"));
64
65 static cl::opt<bool> UserForwardSwitchCond(
66 "forward-switch-cond", cl::Hidden, cl::init(false),
67 cl::desc("Forward switch condition to phi ops (default = false)"));
68
69 static cl::opt<bool> UserHoistCommonInsts(
70 "hoist-common-insts", cl::Hidden, cl::init(false),
71 cl::desc("hoist common instructions (default = false)"));
72
73 static cl::opt<bool> UserSinkCommonInsts(
74 "sink-common-insts", cl::Hidden, cl::init(false),
75 cl::desc("Sink common instructions (default = false)"));
76
77
78 STATISTIC(NumSimpl, "Number of blocks simplified");
79
80 /// If we have more than one empty (other than phi node) return blocks,
81 /// merge them together to promote recursive block merging.
mergeEmptyReturnBlocks(Function & F,DomTreeUpdater * DTU)82 static bool mergeEmptyReturnBlocks(Function &F, DomTreeUpdater *DTU) {
83 bool Changed = false;
84
85 std::vector<DominatorTree::UpdateType> Updates;
86 SmallVector<BasicBlock *, 8> DeadBlocks;
87
88 BasicBlock *RetBlock = nullptr;
89
90 // Scan all the blocks in the function, looking for empty return blocks.
91 for (BasicBlock &BB : make_early_inc_range(F)) {
92 if (DTU && DTU->isBBPendingDeletion(&BB))
93 continue;
94
95 // Only look at return blocks.
96 ReturnInst *Ret = dyn_cast<ReturnInst>(BB.getTerminator());
97 if (!Ret) continue;
98
99 // Only look at the block if it is empty or the only other thing in it is a
100 // single PHI node that is the operand to the return.
101 if (Ret != &BB.front()) {
102 // Check for something else in the block.
103 BasicBlock::iterator I(Ret);
104 --I;
105 // Skip over debug info.
106 while (isa<DbgInfoIntrinsic>(I) && I != BB.begin())
107 --I;
108 if (!isa<DbgInfoIntrinsic>(I) &&
109 (!isa<PHINode>(I) || I != BB.begin() || Ret->getNumOperands() == 0 ||
110 Ret->getOperand(0) != &*I))
111 continue;
112 }
113
114 // If this is the first returning block, remember it and keep going.
115 if (!RetBlock) {
116 RetBlock = &BB;
117 continue;
118 }
119
120 // Skip merging if this would result in a CallBr instruction with a
121 // duplicate destination. FIXME: See note in CodeGenPrepare.cpp.
122 bool SkipCallBr = false;
123 for (pred_iterator PI = pred_begin(&BB), E = pred_end(&BB);
124 PI != E && !SkipCallBr; ++PI) {
125 if (auto *CBI = dyn_cast<CallBrInst>((*PI)->getTerminator()))
126 for (unsigned i = 0, e = CBI->getNumSuccessors(); i != e; ++i)
127 if (RetBlock == CBI->getSuccessor(i)) {
128 SkipCallBr = true;
129 break;
130 }
131 }
132 if (SkipCallBr)
133 continue;
134
135 // Otherwise, we found a duplicate return block. Merge the two.
136 Changed = true;
137
138 // Case when there is no input to the return or when the returned values
139 // agree is trivial. Note that they can't agree if there are phis in the
140 // blocks.
141 if (Ret->getNumOperands() == 0 ||
142 Ret->getOperand(0) ==
143 cast<ReturnInst>(RetBlock->getTerminator())->getOperand(0)) {
144 // All predecessors of BB should now branch to RetBlock instead.
145 if (DTU) {
146 SmallPtrSet<BasicBlock *, 2> PredsOfBB(pred_begin(&BB), pred_end(&BB));
147 SmallPtrSet<BasicBlock *, 2> PredsOfRetBlock(pred_begin(RetBlock),
148 pred_end(RetBlock));
149 Updates.reserve(Updates.size() + 2 * PredsOfBB.size());
150 for (auto *Predecessor : PredsOfBB)
151 // But, iff Predecessor already branches to RetBlock,
152 // don't (re-)add DomTree edge, because it already exists.
153 if (!PredsOfRetBlock.contains(Predecessor))
154 Updates.push_back({DominatorTree::Insert, Predecessor, RetBlock});
155 for (auto *Predecessor : PredsOfBB)
156 Updates.push_back({DominatorTree::Delete, Predecessor, &BB});
157 }
158 BB.replaceAllUsesWith(RetBlock);
159 DeadBlocks.emplace_back(&BB);
160 continue;
161 }
162
163 // If the canonical return block has no PHI node, create one now.
164 PHINode *RetBlockPHI = dyn_cast<PHINode>(RetBlock->begin());
165 if (!RetBlockPHI) {
166 Value *InVal = cast<ReturnInst>(RetBlock->getTerminator())->getOperand(0);
167 pred_iterator PB = pred_begin(RetBlock), PE = pred_end(RetBlock);
168 RetBlockPHI = PHINode::Create(Ret->getOperand(0)->getType(),
169 std::distance(PB, PE), "merge",
170 &RetBlock->front());
171
172 for (pred_iterator PI = PB; PI != PE; ++PI)
173 RetBlockPHI->addIncoming(InVal, *PI);
174 RetBlock->getTerminator()->setOperand(0, RetBlockPHI);
175 }
176
177 // Turn BB into a block that just unconditionally branches to the return
178 // block. This handles the case when the two return blocks have a common
179 // predecessor but that return different things.
180 RetBlockPHI->addIncoming(Ret->getOperand(0), &BB);
181 BB.getTerminator()->eraseFromParent();
182 BranchInst::Create(RetBlock, &BB);
183 if (DTU)
184 Updates.push_back({DominatorTree::Insert, &BB, RetBlock});
185 }
186
187 if (DTU)
188 DTU->applyUpdates(Updates);
189
190 DeleteDeadBlocks(DeadBlocks, DTU);
191
192 return Changed;
193 }
194
195 /// Call SimplifyCFG on all the blocks in the function,
196 /// iterating until no more changes are made.
iterativelySimplifyCFG(Function & F,const TargetTransformInfo & TTI,DomTreeUpdater * DTU,const SimplifyCFGOptions & Options)197 static bool iterativelySimplifyCFG(Function &F, const TargetTransformInfo &TTI,
198 DomTreeUpdater *DTU,
199 const SimplifyCFGOptions &Options) {
200 bool Changed = false;
201 bool LocalChange = true;
202
203 SmallVector<std::pair<const BasicBlock *, const BasicBlock *>, 32> Edges;
204 FindFunctionBackedges(F, Edges);
205 SmallPtrSet<BasicBlock *, 16> UniqueLoopHeaders;
206 for (unsigned i = 0, e = Edges.size(); i != e; ++i)
207 UniqueLoopHeaders.insert(const_cast<BasicBlock *>(Edges[i].second));
208
209 SmallVector<WeakVH, 16> LoopHeaders(UniqueLoopHeaders.begin(),
210 UniqueLoopHeaders.end());
211
212 while (LocalChange) {
213 LocalChange = false;
214
215 // Loop over all of the basic blocks and remove them if they are unneeded.
216 for (Function::iterator BBIt = F.begin(); BBIt != F.end(); ) {
217 BasicBlock &BB = *BBIt++;
218 if (DTU) {
219 assert(
220 !DTU->isBBPendingDeletion(&BB) &&
221 "Should not end up trying to simplify blocks marked for removal.");
222 // Make sure that the advanced iterator does not point at the blocks
223 // that are marked for removal, skip over all such blocks.
224 while (BBIt != F.end() && DTU->isBBPendingDeletion(&*BBIt))
225 ++BBIt;
226 }
227 if (simplifyCFG(&BB, TTI, DTU, Options, LoopHeaders)) {
228 LocalChange = true;
229 ++NumSimpl;
230 }
231 }
232 Changed |= LocalChange;
233 }
234 return Changed;
235 }
236
simplifyFunctionCFGImpl(Function & F,const TargetTransformInfo & TTI,DominatorTree * DT,const SimplifyCFGOptions & Options)237 static bool simplifyFunctionCFGImpl(Function &F, const TargetTransformInfo &TTI,
238 DominatorTree *DT,
239 const SimplifyCFGOptions &Options) {
240 DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Eager);
241
242 bool EverChanged = removeUnreachableBlocks(F, DT ? &DTU : nullptr);
243 EverChanged |= mergeEmptyReturnBlocks(F, DT ? &DTU : nullptr);
244 EverChanged |= iterativelySimplifyCFG(F, TTI, DT ? &DTU : nullptr, Options);
245
246 // If neither pass changed anything, we're done.
247 if (!EverChanged) return false;
248
249 // iterativelySimplifyCFG can (rarely) make some loops dead. If this happens,
250 // removeUnreachableBlocks is needed to nuke them, which means we should
251 // iterate between the two optimizations. We structure the code like this to
252 // avoid rerunning iterativelySimplifyCFG if the second pass of
253 // removeUnreachableBlocks doesn't do anything.
254 if (!removeUnreachableBlocks(F, DT ? &DTU : nullptr))
255 return true;
256
257 do {
258 EverChanged = iterativelySimplifyCFG(F, TTI, DT ? &DTU : nullptr, Options);
259 EverChanged |= removeUnreachableBlocks(F, DT ? &DTU : nullptr);
260 } while (EverChanged);
261
262 return true;
263 }
264
simplifyFunctionCFG(Function & F,const TargetTransformInfo & TTI,DominatorTree * DT,const SimplifyCFGOptions & Options)265 static bool simplifyFunctionCFG(Function &F, const TargetTransformInfo &TTI,
266 DominatorTree *DT,
267 const SimplifyCFGOptions &Options) {
268 assert((!RequireAndPreserveDomTree ||
269 (DT && DT->verify(DominatorTree::VerificationLevel::Full))) &&
270 "Original domtree is invalid?");
271
272 bool Changed = simplifyFunctionCFGImpl(F, TTI, DT, Options);
273
274 assert((!RequireAndPreserveDomTree ||
275 (DT && DT->verify(DominatorTree::VerificationLevel::Full))) &&
276 "Failed to maintain validity of domtree!");
277
278 return Changed;
279 }
280
281 // Command-line settings override compile-time settings.
applyCommandLineOverridesToOptions(SimplifyCFGOptions & Options)282 static void applyCommandLineOverridesToOptions(SimplifyCFGOptions &Options) {
283 if (UserBonusInstThreshold.getNumOccurrences())
284 Options.BonusInstThreshold = UserBonusInstThreshold;
285 if (UserForwardSwitchCond.getNumOccurrences())
286 Options.ForwardSwitchCondToPhi = UserForwardSwitchCond;
287 if (UserSwitchToLookup.getNumOccurrences())
288 Options.ConvertSwitchToLookupTable = UserSwitchToLookup;
289 if (UserKeepLoops.getNumOccurrences())
290 Options.NeedCanonicalLoop = UserKeepLoops;
291 if (UserHoistCommonInsts.getNumOccurrences())
292 Options.HoistCommonInsts = UserHoistCommonInsts;
293 if (UserSinkCommonInsts.getNumOccurrences())
294 Options.SinkCommonInsts = UserSinkCommonInsts;
295 }
296
SimplifyCFGPass()297 SimplifyCFGPass::SimplifyCFGPass() : Options() {
298 applyCommandLineOverridesToOptions(Options);
299 }
300
SimplifyCFGPass(const SimplifyCFGOptions & Opts)301 SimplifyCFGPass::SimplifyCFGPass(const SimplifyCFGOptions &Opts)
302 : Options(Opts) {
303 applyCommandLineOverridesToOptions(Options);
304 }
305
run(Function & F,FunctionAnalysisManager & AM)306 PreservedAnalyses SimplifyCFGPass::run(Function &F,
307 FunctionAnalysisManager &AM) {
308 auto &TTI = AM.getResult<TargetIRAnalysis>(F);
309 Options.AC = &AM.getResult<AssumptionAnalysis>(F);
310 DominatorTree *DT = nullptr;
311 if (RequireAndPreserveDomTree)
312 DT = &AM.getResult<DominatorTreeAnalysis>(F);
313 if (F.hasFnAttribute(Attribute::OptForFuzzing)) {
314 Options.setSimplifyCondBranch(false).setFoldTwoEntryPHINode(false);
315 } else {
316 Options.setSimplifyCondBranch(true).setFoldTwoEntryPHINode(true);
317 }
318 if (!simplifyFunctionCFG(F, TTI, DT, Options))
319 return PreservedAnalyses::all();
320 PreservedAnalyses PA;
321 if (RequireAndPreserveDomTree)
322 PA.preserve<DominatorTreeAnalysis>();
323 return PA;
324 }
325
326 namespace {
327 struct CFGSimplifyPass : public FunctionPass {
328 static char ID;
329 SimplifyCFGOptions Options;
330 std::function<bool(const Function &)> PredicateFtor;
331
CFGSimplifyPass__anon139d7ff20111::CFGSimplifyPass332 CFGSimplifyPass(SimplifyCFGOptions Options_ = SimplifyCFGOptions(),
333 std::function<bool(const Function &)> Ftor = nullptr)
334 : FunctionPass(ID), Options(Options_), PredicateFtor(std::move(Ftor)) {
335
336 initializeCFGSimplifyPassPass(*PassRegistry::getPassRegistry());
337
338 // Check for command-line overrides of options for debug/customization.
339 applyCommandLineOverridesToOptions(Options);
340 }
341
runOnFunction__anon139d7ff20111::CFGSimplifyPass342 bool runOnFunction(Function &F) override {
343 if (skipFunction(F) || (PredicateFtor && !PredicateFtor(F)))
344 return false;
345
346 Options.AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
347 DominatorTree *DT = nullptr;
348 if (RequireAndPreserveDomTree)
349 DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
350 if (F.hasFnAttribute(Attribute::OptForFuzzing)) {
351 Options.setSimplifyCondBranch(false)
352 .setFoldTwoEntryPHINode(false);
353 } else {
354 Options.setSimplifyCondBranch(true)
355 .setFoldTwoEntryPHINode(true);
356 }
357
358 auto &TTI = getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
359 return simplifyFunctionCFG(F, TTI, DT, Options);
360 }
getAnalysisUsage__anon139d7ff20111::CFGSimplifyPass361 void getAnalysisUsage(AnalysisUsage &AU) const override {
362 AU.addRequired<AssumptionCacheTracker>();
363 if (RequireAndPreserveDomTree)
364 AU.addRequired<DominatorTreeWrapperPass>();
365 AU.addRequired<TargetTransformInfoWrapperPass>();
366 if (RequireAndPreserveDomTree)
367 AU.addPreserved<DominatorTreeWrapperPass>();
368 AU.addPreserved<GlobalsAAWrapperPass>();
369 }
370 };
371 }
372
373 char CFGSimplifyPass::ID = 0;
374 INITIALIZE_PASS_BEGIN(CFGSimplifyPass, "simplifycfg", "Simplify the CFG", false,
375 false)
INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)376 INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
377 INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
378 INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
379 INITIALIZE_PASS_END(CFGSimplifyPass, "simplifycfg", "Simplify the CFG", false,
380 false)
381
382 // Public interface to the CFGSimplification pass
383 FunctionPass *
384 llvm::createCFGSimplificationPass(SimplifyCFGOptions Options,
385 std::function<bool(const Function &)> Ftor) {
386 return new CFGSimplifyPass(Options, std::move(Ftor));
387 }
388