[InstCombine] Signed saturation tests. NFC
[llvm-complete.git] / tools / llvm-reduce / deltas / ReduceBasicBlocks.cpp
blob03c3962d2fd9daa51b29948c4fb6daca3b80fc3b
1 //===- ReduceArguments.cpp - Specialized Delta 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 a function which calls the Generic Delta pass in order
10 // to reduce uninteresting Arguments from defined functions.
12 //===----------------------------------------------------------------------===//
14 #include "ReduceBasicBlocks.h"
15 #include "llvm/IR/BasicBlock.h"
16 #include "llvm/IR/Instruction.h"
17 #include "llvm/IR/Instructions.h"
18 #include "llvm/IR/LLVMContext.h"
19 #include "llvm/IR/Value.h"
20 #include "llvm/Support/Casting.h"
21 #include "llvm/Support/raw_ostream.h"
22 #include <vector>
24 using namespace llvm;
26 /// Replaces BB Terminator with one that only contains Chunk BBs
27 static void replaceBranchTerminator(BasicBlock &BB,
28 std::set<BasicBlock *> BBsToKeep) {
29 auto Term = BB.getTerminator();
30 std::vector<BasicBlock *> ChunkSucessors;
31 for (auto Succ : successors(&BB))
32 if (BBsToKeep.count(Succ))
33 ChunkSucessors.push_back(Succ);
35 // BB only references Chunk BBs
36 if (ChunkSucessors.size() == Term->getNumSuccessors())
37 return;
39 bool IsBranch = isa<BranchInst>(Term);
40 Value *Address = nullptr;
41 if (auto IndBI = dyn_cast<IndirectBrInst>(Term))
42 Address = IndBI->getAddress();
44 Term->eraseFromParent();
46 if (ChunkSucessors.empty()) {
47 ReturnInst::Create(BB.getContext(), nullptr, &BB);
48 return;
51 if (IsBranch)
52 BranchInst::Create(ChunkSucessors[0], &BB);
54 if (Address) {
55 auto NewIndBI =
56 IndirectBrInst::Create(Address, ChunkSucessors.size(), &BB);
57 for (auto Dest : ChunkSucessors)
58 NewIndBI->addDestination(Dest);
62 /// Removes uninteresting BBs from switch, if the default case ends up being
63 /// uninteresting, the switch is replaced with a void return (since it has to be
64 /// replace with something)
65 static void removeUninterestingBBsFromSwitch(SwitchInst &SwInst,
66 std::set<BasicBlock *> BBsToKeep) {
67 if (!BBsToKeep.count(SwInst.getDefaultDest())) {
68 ReturnInst::Create(SwInst.getContext(), nullptr, SwInst.getParent());
69 SwInst.eraseFromParent();
70 } else
71 for (int I = 0, E = SwInst.getNumCases(); I != E; ++I) {
72 auto Case = SwInst.case_begin() + I;
73 if (!BBsToKeep.count(Case->getCaseSuccessor())) {
74 SwInst.removeCase(Case);
75 --I;
76 --E;
81 /// Removes out-of-chunk arguments from functions, and modifies their calls
82 /// accordingly. It also removes allocations of out-of-chunk arguments.
83 static void extractBasicBlocksFromModule(std::vector<Chunk> ChunksToKeep,
84 Module *Program) {
85 int I = 0, BBCount = 0;
86 std::set<BasicBlock *> BBsToKeep;
88 for (auto &F : *Program)
89 for (auto &BB : F)
90 if (I < (int)ChunksToKeep.size()) {
91 if (ChunksToKeep[I].contains(++BBCount))
92 BBsToKeep.insert(&BB);
93 if (ChunksToKeep[I].end == BBCount)
94 ++I;
97 std::vector<BasicBlock *> BBsToDelete;
98 for (auto &F : *Program)
99 for (auto &BB : F) {
100 if (!BBsToKeep.count(&BB)) {
101 BBsToDelete.push_back(&BB);
102 // Remove out-of-chunk BB from successor phi nodes
103 for (auto *Succ : successors(&BB))
104 Succ->removePredecessor(&BB);
108 // Replace terminators that reference out-of-chunk BBs
109 for (auto &F : *Program)
110 for (auto &BB : F) {
111 if (auto *SwInst = dyn_cast<SwitchInst>(BB.getTerminator()))
112 removeUninterestingBBsFromSwitch(*SwInst, BBsToKeep);
113 else
114 replaceBranchTerminator(BB, BBsToKeep);
117 // Replace out-of-chunk switch uses
118 for (auto &BB : BBsToDelete) {
119 // Instructions might be referenced in other BBs
120 for (auto &I : *BB)
121 I.replaceAllUsesWith(UndefValue::get(I.getType()));
122 BB->eraseFromParent();
126 /// Counts the amount of basic blocks and prints their name & respective index
127 static int countBasicBlocks(Module *Program) {
128 // TODO: Silence index with --quiet flag
129 outs() << "----------------------------\n";
130 int BBCount = 0;
131 for (auto &F : *Program)
132 for (auto &BB : F) {
133 if (BB.hasName())
134 outs() << "\t" << ++BBCount << ": " << BB.getName() << "\n";
135 else
136 outs() << "\t" << ++BBCount << ": Unnamed\n";
139 return BBCount;
142 void llvm::reduceBasicBlocksDeltaPass(TestRunner &Test) {
143 outs() << "*** Reducing Basic Blocks...\n";
144 int BBCount = countBasicBlocks(Test.getProgram());
145 runDeltaPass(Test, BBCount, extractBasicBlocksFromModule);