LLVM: lib/Transforms/IPO/BlockExtractor.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
26
27using namespace llvm;
28
29#define DEBUG_TYPE "block-extractor"
30
31STATISTIC(NumExtracted, "Number of basic blocks extracted");
32
35 cl::desc("A file containing list of basic blocks to extract"), cl::Hidden);
36
39 cl::desc("Erase the existing functions"),
41namespace {
42class BlockExtractor {
43public:
44 BlockExtractor(bool EraseFunctions) : EraseFunctions(EraseFunctions) {}
45 bool runOnModule(Module &M);
46 void
47 init(const std::vector<std::vector<BasicBlock *>> &GroupsOfBlocksToExtract) {
48 GroupsOfBlocks = GroupsOfBlocksToExtract;
51 }
52
53private:
54 std::vector<std::vector<BasicBlock *>> GroupsOfBlocks;
55 bool EraseFunctions;
56
58 BlocksByName;
59
61 void splitLandingPadPreds(Function &F);
62};
63
64}
65
66
67void BlockExtractor::loadFile() {
69 if (ErrOrBuf.getError())
71
72 auto &Buf = *ErrOrBuf;
73 SmallVector<StringRef, 16> Lines;
74 Buf->getBuffer().split(Lines, '\n', -1,
75 false);
76 for (const auto &Line : Lines) {
78 Line.split(LineSplit, ' ', -1,
79 false);
80 if (LineSplit.empty())
81 continue;
82 if (LineSplit.size()!=2)
84 "Invalid line format, expecting lines like: 'funcname bb1[;bb2..]'");
86 LineSplit[1].split(BBNames, ';', -1,
87 false);
88 if (BBNames.empty())
90 BlocksByName.push_back(
91 {std::string(LineSplit[0]), {BBNames.begin(), BBNames.end()}});
92 }
93}
94
95
96
97void BlockExtractor::splitLandingPadPreds(Function &F) {
98 for (BasicBlock &BB : F) {
99 for (Instruction &I : BB) {
101 continue;
105
106
107
108 bool Split = false;
110 if (PredBB->isLandingPad() && PredBB != Parent &&
113 break;
114 }
115 }
116
117 if (!Split)
118 continue;
119
122 }
123 }
124}
125
126bool BlockExtractor::runOnModule(Module &M) {
128
129
131 for (Function &F : M) {
132 splitLandingPadPreds(F);
134 }
135
136
137 unsigned NextGroupIdx = GroupsOfBlocks.size();
138 GroupsOfBlocks.resize(NextGroupIdx + BlocksByName.size());
139 for (const auto &BInfo : BlocksByName) {
140 Function *F = M.getFunction(BInfo.first);
141 if ()
143 "Invalid function name specified in the input file");
144 for (const auto &BBInfo : BInfo.second) {
146 *F, [&](const BasicBlock &BB) { return BB.getName() == BBInfo; });
147 if (Res == F->end())
149 GroupsOfBlocks[NextGroupIdx].push_back(&*Res);
150 }
151 ++NextGroupIdx;
152 }
153
154
155 for (auto &BBs : GroupsOfBlocks) {
157 for (BasicBlock *BB : BBs) {
158
163 << "\n");
164 BlocksToExtractVec.push_back(BB);
166 BlocksToExtractVec.push_back(II->getUnwindDest());
167 ++NumExtracted;
169 }
170 CodeExtractorAnalysisCache CEAC(*BBs[0]->getParent());
171 Function *F = CodeExtractor(BlocksToExtractVec).extractCodeRegion(CEAC);
172 if (F)
173 LLVM_DEBUG(dbgs() << "Extracted group '" << (*BBs.begin())->getName()
174 << "' in: " << F->getName() << '\n');
175 else
177 << (*BBs.begin())->getName() << "'\n");
178 }
179
180
182 for (Function *F : Functions) {
183 LLVM_DEBUG(dbgs() << "BlockExtractor: Trying to delete " << F->getName()
184 << "\n");
185 F->deleteBody();
186 }
187
188 for (Function &F : M)
191 }
192
194}
195
197 std::vector<std::vector<BasicBlock *>> &&GroupsOfBlocks,
198 bool EraseFunctions)
199 : GroupsOfBlocks(GroupsOfBlocks), EraseFunctions(EraseFunctions) {}
200
203 BlockExtractor BE(EraseFunctions);
204 BE.init(GroupsOfBlocks);
207}
static const Function * getParent(const Value *V)
static std::unique_ptr< Module > loadFile(const std::string &FileName, LLVMContext &Context)
Module.h This file contains the declarations for the Module class.
This header defines various interfaces for pass management in LLVM.
Machine Check Debug Module
uint64_t IntrinsicInst * II
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
const Function * getParent() const
Return the enclosing method, or null if none.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
Module * getParent()
Get the module that this global value is contained inside of...
@ ExternalLinkage
Externally visible function.
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFile(const Twine &Filename, bool IsText=false, bool RequiresNullTerminator=true, bool IsVolatile=false, std::optional< Align > Alignment=std::nullopt)
Open the specified file as a MemoryBuffer, returning a new MemoryBuffer if successful,...
A Module instance is used to store all the information related to an LLVM module.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
void push_back(const T &Elt)
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
@ BasicBlock
Various leaf nodes.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
decltype(auto) dyn_cast(const From &Val)
dyn_cast - Return the argument parameter cast to the specified type.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ABI void SplitLandingPadPredecessors(BasicBlock *OrigBB, ArrayRef< BasicBlock * > Preds, const char *Suffix, const char *Suffix2, SmallVectorImpl< BasicBlock * > &NewBBs, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, bool PreserveLCSSA=false)
This method transforms the landing pad, OrigBB, by introducing two new basic blocks into the function...
decltype(auto) cast(const From &Val)
cast - Return the argument parameter cast to the specified type.
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
auto predecessors(const MachineBasicBlock *BB)
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
LLVM_ABI void reportFatalUsageError(Error Err)
Report a fatal error that does not indicate a bug in LLVM.