1 //===- ReduceBasicBlocks.cpp - Specialized Delta Pass ---------------------===//
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
7 //===----------------------------------------------------------------------===//
9 // This file implements a function which calls the Generic Delta pass in order
10 // to reduce uninteresting BasicBlocks from defined functions.
12 //===----------------------------------------------------------------------===//
14 #include "ReduceBasicBlocks.h"
16 #include "llvm/ADT/DenseSet.h"
17 #include "llvm/IR/BasicBlock.h"
18 #include "llvm/IR/Constants.h"
19 #include "llvm/IR/Instruction.h"
20 #include "llvm/IR/Instructions.h"
21 #include "llvm/IR/LLVMContext.h"
22 #include "llvm/IR/Value.h"
23 #include "llvm/Support/Casting.h"
24 #include "llvm/Support/raw_ostream.h"
25 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
26 #include "llvm/Transforms/Utils/Local.h"
30 #define DEBUG_TYPE "llvm-reduce"
34 /// Replaces BB Terminator with one that only contains Chunk BBs
35 static void replaceBranchTerminator(BasicBlock
&BB
,
36 const DenseSet
<BasicBlock
*> &BBsToDelete
) {
37 auto *Term
= BB
.getTerminator();
38 std::vector
<BasicBlock
*> ChunkSuccessors
;
39 for (auto *Succ
: successors(&BB
)) {
40 if (!BBsToDelete
.count(Succ
))
41 ChunkSuccessors
.push_back(Succ
);
44 // BB only references Chunk BBs
45 if (ChunkSuccessors
.size() == Term
->getNumSuccessors())
48 // TODO: Handle these without failing verifier.
49 if (isa
<CatchSwitchInst
>(Term
))
52 bool IsBranch
= isa
<BranchInst
>(Term
);
53 if (InvokeInst
*Invoke
= dyn_cast
<InvokeInst
>(Term
)) {
54 BasicBlock
*UnwindDest
= Invoke
->getUnwindDest();
55 Instruction
*LP
= UnwindDest
->getFirstNonPHI();
57 // Remove landingpad instruction if the containing block isn't used by other
60 // TODO: Handle catchswitch, catchpad, catchret, and cleanupret
61 if (isa
<LandingPadInst
>(LP
) &&
62 none_of(UnwindDest
->users(), [Invoke
](User
*U
) {
63 return U
!= Invoke
&& isa
<InvokeInst
>(U
);
65 LP
->replaceAllUsesWith(getDefaultValue(LP
->getType()));
66 LP
->eraseFromParent();
67 } else if (!ChunkSuccessors
.empty() &&
68 ChunkSuccessors
[0] == LP
->getParent()) {
69 // If the selected successor is the landing pad, clear the chunk
70 // successors to avoid creating a regular branch to the landing pad which
71 // would result in invalid IR.
72 ChunkSuccessors
.clear();
77 Value
*Address
= nullptr;
78 if (auto *IndBI
= dyn_cast
<IndirectBrInst
>(Term
))
79 Address
= IndBI
->getAddress();
81 Term
->replaceAllUsesWith(getDefaultValue(Term
->getType()));
82 Term
->eraseFromParent();
84 if (ChunkSuccessors
.empty()) {
85 // If that fails then resort to replacing with a ret.
86 auto *FnRetTy
= BB
.getParent()->getReturnType();
87 ReturnInst::Create(BB
.getContext(),
88 FnRetTy
->isVoidTy() ? nullptr : getDefaultValue(FnRetTy
),
94 BranchInst::Create(ChunkSuccessors
[0], &BB
);
98 IndirectBrInst::Create(Address
, ChunkSuccessors
.size(), &BB
);
99 for (auto *Dest
: ChunkSuccessors
)
100 NewIndBI
->addDestination(Dest
);
104 /// Removes uninteresting BBs from switch, if the default case ends up being
105 /// uninteresting, the switch is replaced with a void return (since it has to be
106 /// replace with something)
108 removeUninterestingBBsFromSwitch(SwitchInst
&SwInst
,
109 const DenseSet
<BasicBlock
*> &BBsToDelete
) {
110 for (int I
= 0, E
= SwInst
.getNumCases(); I
!= E
; ++I
) {
111 auto Case
= SwInst
.case_begin() + I
;
112 if (BBsToDelete
.count(Case
->getCaseSuccessor())) {
113 SwInst
.removeCase(Case
);
119 if (BBsToDelete
.count(SwInst
.getDefaultDest())) {
120 if (SwInst
.getNumCases() == 0) {
121 auto *FnRetTy
= SwInst
.getParent()->getParent()->getReturnType();
123 FnRetTy
->isVoidTy() ? nullptr : getDefaultValue(FnRetTy
);
124 ReturnInst::Create(SwInst
.getContext(), RetValue
, SwInst
.getParent());
125 SwInst
.eraseFromParent();
129 // Replace the default dest with one of the other cases
130 auto Case
= SwInst
.case_begin();
132 BasicBlock
*NewDefault
= Case
->getCaseSuccessor();
133 SwInst
.setDefaultDest(NewDefault
);
135 for (PHINode
&SuccPHI
: NewDefault
->phis()) {
136 SuccPHI
.addIncoming(SuccPHI
.getIncomingValueForBlock(SwInst
.getParent()),
142 /// Removes out-of-chunk arguments from functions, and modifies their calls
143 /// accordingly. It also removes allocations of out-of-chunk arguments.
144 static void extractBasicBlocksFromModule(Oracle
&O
, ReducerWorkItem
&WorkItem
) {
145 DenseSet
<BasicBlock
*> BBsToDelete
;
146 df_iterator_default_set
<BasicBlock
*> Reachable
;
148 for (auto &F
: WorkItem
.getModule()) {
152 BasicBlock
&Entry
= F
.getEntryBlock();
153 for (auto *BB
: depth_first_ext(&Entry
, Reachable
))
156 // Skip any function with unreachable blocks. It's somewhat difficult to
157 // avoid producing invalid IR without deleting them.
159 // We also do not want to unconditionally delete them, as doing so would
160 // break the invariant of changing the number of chunks during counting.
162 const bool HasUnreachableBlocks
= Reachable
.size() != F
.size();
165 if (HasUnreachableBlocks
) {
166 LLVM_DEBUG(dbgs() << "Skipping function with unreachable blocks\n");
170 for (BasicBlock
&BB
: F
) {
171 if (&BB
!= &Entry
&& !O
.shouldKeep())
172 BBsToDelete
.insert(&BB
);
175 // Replace terminators that reference out-of-chunk BBs
176 for (BasicBlock
&BB
: F
) {
177 if (auto *SwInst
= dyn_cast
<SwitchInst
>(BB
.getTerminator()))
178 removeUninterestingBBsFromSwitch(*SwInst
, BBsToDelete
);
180 replaceBranchTerminator(BB
, BBsToDelete
);
183 // Cleanup any blocks that are now dead after eliminating this set. This
184 // will likely be larger than the number of blocks the oracle told us to
186 EliminateUnreachableBlocks(F
);
191 void llvm::reduceBasicBlocksDeltaPass(TestRunner
&Test
) {
192 runDeltaPass(Test
, extractBasicBlocksFromModule
, "Reducing Basic Blocks");
195 static void removeUnreachableBasicBlocksFromModule(Oracle
&O
,
196 ReducerWorkItem
&WorkItem
) {
197 std::vector
<BasicBlock
*> DeadBlocks
;
198 df_iterator_default_set
<BasicBlock
*> Reachable
;
200 for (Function
&F
: WorkItem
.getModule()) {
204 // Mark all reachable blocks.
205 for (BasicBlock
*BB
: depth_first_ext(&F
, Reachable
))
208 if (Reachable
.size() != F
.size() && !O
.shouldKeep()) {
209 for (BasicBlock
&BB
: F
) {
210 if (!Reachable
.count(&BB
))
211 DeadBlocks
.push_back(&BB
);
214 // Delete the dead blocks.
215 DeleteDeadBlocks(DeadBlocks
, nullptr, /*KeepOneInputPHIs*/ false);
223 void llvm::reduceUnreachableBasicBlocksDeltaPass(TestRunner
&Test
) {
224 runDeltaPass(Test
, removeUnreachableBasicBlocksFromModule
,
225 "Removing Unreachable Basic Blocks");