LLVM  8.0.1
BlockExtractor.cpp
Go to the documentation of this file.
1 //===- BlockExtractor.cpp - Extracts blocks into their own functions ------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This pass extracts the specified basic blocks from the module into their
11 // own functions.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #include "llvm/ADT/STLExtras.h"
16 #include "llvm/ADT/Statistic.h"
17 #include "llvm/IR/Instructions.h"
18 #include "llvm/IR/Module.h"
19 #include "llvm/Pass.h"
21 #include "llvm/Support/Debug.h"
23 #include "llvm/Transforms/IPO.h"
26 using namespace llvm;
27 
28 #define DEBUG_TYPE "block-extractor"
29 
30 STATISTIC(NumExtracted, "Number of basic blocks extracted");
31 
33  "extract-blocks-file", cl::value_desc("filename"),
34  cl::desc("A file containing list of basic blocks to extract"), cl::Hidden);
35 
36 cl::opt<bool> BlockExtractorEraseFuncs("extract-blocks-erase-funcs",
37  cl::desc("Erase the existing functions"),
38  cl::Hidden);
39 
40 namespace {
41 class BlockExtractor : public ModulePass {
43  bool EraseFunctions;
45 
46 public:
47  static char ID;
48  BlockExtractor(const SmallVectorImpl<BasicBlock *> &BlocksToExtract,
49  bool EraseFunctions)
50  : ModulePass(ID), Blocks(BlocksToExtract.begin(), BlocksToExtract.end()),
51  EraseFunctions(EraseFunctions) {
52  if (!BlockExtractorFile.empty())
53  loadFile();
54  }
55  BlockExtractor() : BlockExtractor(SmallVector<BasicBlock *, 0>(), false) {}
56  bool runOnModule(Module &M) override;
57 
58 private:
59  void loadFile();
60  void splitLandingPadPreds(Function &F);
61 };
62 } // end anonymous namespace
63 
64 char BlockExtractor::ID = 0;
65 INITIALIZE_PASS(BlockExtractor, "extract-blocks",
66  "Extract basic blocks from module", false, false)
67 
68 ModulePass *llvm::createBlockExtractorPass() { return new BlockExtractor(); }
70  const SmallVectorImpl<BasicBlock *> &BlocksToExtract, bool EraseFunctions) {
71  return new BlockExtractor(BlocksToExtract, EraseFunctions);
72 }
73 
74 /// Gets all of the blocks specified in the input file.
77  if (ErrOrBuf.getError())
78  report_fatal_error("BlockExtractor couldn't load the file.");
79  // Read the file.
80  auto &Buf = *ErrOrBuf;
82  Buf->getBuffer().split(Lines, '\n', /*MaxSplit=*/-1,
83  /*KeepEmpty=*/false);
84  for (const auto &Line : Lines) {
85  auto FBPair = Line.split(' ');
86  BlocksByName.push_back({FBPair.first, FBPair.second});
87  }
88 }
89 
90 /// Extracts the landing pads to make sure all of them have only one
91 /// predecessor.
92 void BlockExtractor::splitLandingPadPreds(Function &F) {
93  for (BasicBlock &BB : F) {
94  for (Instruction &I : BB) {
95  if (!isa<InvokeInst>(&I))
96  continue;
97  InvokeInst *II = cast<InvokeInst>(&I);
98  BasicBlock *Parent = II->getParent();
99  BasicBlock *LPad = II->getUnwindDest();
100 
101  // Look through the landing pad's predecessors. If one of them ends in an
102  // 'invoke', then we want to split the landing pad.
103  bool Split = false;
104  for (auto PredBB : predecessors(LPad)) {
105  if (PredBB->isLandingPad() && PredBB != Parent &&
106  isa<InvokeInst>(Parent->getTerminator())) {
107  Split = true;
108  break;
109  }
110  }
111 
112  if (!Split)
113  continue;
114 
116  SplitLandingPadPredecessors(LPad, Parent, ".1", ".2", NewBBs);
117  }
118  }
119 }
120 
121 bool BlockExtractor::runOnModule(Module &M) {
122 
123  bool Changed = false;
124 
125  // Get all the functions.
126  SmallVector<Function *, 4> Functions;
127  for (Function &F : M) {
128  splitLandingPadPreds(F);
129  Functions.push_back(&F);
130  }
131 
132  // Get all the blocks specified in the input file.
133  for (const auto &BInfo : BlocksByName) {
134  Function *F = M.getFunction(BInfo.first);
135  if (!F)
136  report_fatal_error("Invalid function name specified in the input file");
137  auto Res = llvm::find_if(*F, [&](const BasicBlock &BB) {
138  return BB.getName().equals(BInfo.second);
139  });
140  if (Res == F->end())
141  report_fatal_error("Invalid block name specified in the input file");
142  Blocks.push_back(&*Res);
143  }
144 
145  // Extract basic blocks.
146  for (BasicBlock *BB : Blocks) {
147  // Check if the module contains BB.
148  if (BB->getParent()->getParent() != &M)
149  report_fatal_error("Invalid basic block");
150  LLVM_DEBUG(dbgs() << "BlockExtractor: Extracting "
151  << BB->getParent()->getName() << ":" << BB->getName()
152  << "\n");
153  SmallVector<BasicBlock *, 2> BlocksToExtractVec;
154  BlocksToExtractVec.push_back(BB);
155  if (const InvokeInst *II = dyn_cast<InvokeInst>(BB->getTerminator()))
156  BlocksToExtractVec.push_back(II->getUnwindDest());
157  CodeExtractor(BlocksToExtractVec).extractCodeRegion();
158  ++NumExtracted;
159  Changed = true;
160  }
161 
162  // Erase the functions.
163  if (EraseFunctions || BlockExtractorEraseFuncs) {
164  for (Function *F : Functions) {
165  LLVM_DEBUG(dbgs() << "BlockExtractor: Trying to delete " << F->getName()
166  << "\n");
167  F->deleteBody();
168  }
169  // Set linkage as ExternalLinkage to avoid erasing unreachable functions.
170  for (Function &F : M)
172  Changed = true;
173  }
174 
175  return Changed;
176 }
const Function & getFunction() const
Definition: Function.h:134
const_iterator end(StringRef path)
Get end iterator over path.
Definition: Path.cpp:259
Utility class for extracting code into a new function.
Definition: CodeExtractor.h:52
const_iterator begin(StringRef path, Style style=Style::native)
Get begin iterator over path.
Definition: Path.cpp:250
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:140
This class represents lattice values for constants.
Definition: AllocatorList.h:24
A Module instance is used to store all the information related to an LLVM module. ...
Definition: Module.h:65
iterator end()
Definition: Function.h:658
Function * extractCodeRegion()
Perform the extraction, returning the new function.
Externally visible function.
Definition: GlobalValue.h:49
STATISTIC(NumFunctions, "Total number of functions")
cl::opt< bool > BlockExtractorEraseFuncs("extract-blocks-erase-funcs", cl::desc("Erase the existing functions"), cl::Hidden)
F(f)
static std::unique_ptr< Module > loadFile(const std::string &FileName, LLVMContext &Context)
ModulePass * createBlockExtractorPass()
createBlockExtractorPass - This pass extracts all the specified blocks from the functions in the modu...
void SplitLandingPadPredecessors(BasicBlock *OrigBB, ArrayRef< BasicBlock *> Preds, const char *Suffix, const char *Suffix2, SmallVectorImpl< BasicBlock *> &NewBBs, DominatorTree *DT=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...
INITIALIZE_PASS(BlockExtractor, "extract-blocks", "Extract basic blocks from module", false, false) ModulePass *llvm
LLVM Basic Block Representation.
Definition: BasicBlock.h:58
void deleteBody()
deleteBody - This method deletes the body of the function, and converts the linkage to external...
Definition: Function.h:609
auto find_if(R &&Range, UnaryPredicate P) -> decltype(adl_begin(Range))
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly...
Definition: STLExtras.h:1214
static cl::opt< std::string > BlockExtractorFile("extract-blocks-file", cl::value_desc("filename"), cl::desc("A file containing list of basic blocks to extract"), cl::Hidden)
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:847
Module.h This file contains the declarations for the Module class.
pred_range predecessors(BasicBlock *BB)
Definition: CFG.h:125
void setLinkage(LinkageTypes LT)
Definition: GlobalValue.h:445
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:133
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool equals(StringRef RHS) const
equals - Check for string equality, this is more efficient than compare() when the relative ordering ...
Definition: StringRef.h:169
StringRef getName() const
Return a constant reference to the value&#39;s name.
Definition: Value.cpp:214
#define I(x, y, z)
Definition: MD5.cpp:58
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
Definition: Pass.h:225
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFile(const Twine &Filename, int64_t FileSize=-1, bool RequiresNullTerminator=true, bool IsVolatile=false)
Open the specified file as a MemoryBuffer, returning a new MemoryBuffer if successful, otherwise returning null.
BasicBlock * getUnwindDest() const
Invoke instruction.
static void Split(std::vector< std::string > &V, StringRef S)
Splits a string of comma separated items in to a vector of strings.
#define LLVM_DEBUG(X)
Definition: Debug.h:123
const BasicBlock * getParent() const
Definition: Instruction.h:67