29#define DEBUG_TYPE "block-extractor"
31STATISTIC(NumExtracted,
"Number of basic blocks extracted");
39 cl::desc(
"Erase the existing functions"),
44 BlockExtractor(
bool EraseFunctions) : EraseFunctions(EraseFunctions) {}
45 bool runOnModule(
Module &M);
47 init(
const std::vector<std::vector<BasicBlock *>> &GroupsOfBlocksToExtract) {
48 GroupsOfBlocks = GroupsOfBlocksToExtract;
54 std::vector<std::vector<BasicBlock *>> GroupsOfBlocks;
67void BlockExtractor::loadFile() {
69 if (ErrOrBuf.getError())
72 auto &Buf = *ErrOrBuf;
74 Buf->getBuffer().split(Lines,
'\n', -1,
76 for (
const auto &Line : Lines) {
78 Line.split(LineSplit,
' ', -1,
80 if (LineSplit.
empty())
82 if (LineSplit.
size()!=2)
83 report_fatal_error(
"Invalid line format, expecting lines like: 'funcname bb1[;bb2..]'",
86 LineSplit[1].split(BBNames,
';', -1,
90 BlocksByName.push_back(
91 {std::string(LineSplit[0]), {BBNames.
begin(), BBNames.
end()}});
97void BlockExtractor::splitLandingPadPreds(
Function &
F) {
100 if (!isa<InvokeInst>(&
I))
110 if (PredBB->isLandingPad() && PredBB != Parent &&
126bool BlockExtractor::runOnModule(
Module &M) {
127 bool Changed =
false;
132 splitLandingPadPreds(
F);
137 unsigned NextGroupIdx = GroupsOfBlocks.size();
138 GroupsOfBlocks.resize(NextGroupIdx + BlocksByName.size());
139 for (
const auto &BInfo : BlocksByName) {
144 for (
const auto &BBInfo : BInfo.second) {
150 GroupsOfBlocks[NextGroupIdx].push_back(&*Res);
156 for (
auto &BBs : GroupsOfBlocks) {
174 LLVM_DEBUG(
dbgs() <<
"Extracted group '" << (*BBs.begin())->getName()
175 <<
"' in: " <<
F->getName() <<
'\n');
178 << (*BBs.begin())->getName() <<
"'\n");
184 LLVM_DEBUG(
dbgs() <<
"BlockExtractor: Trying to delete " <<
F->getName()
198 std::vector<std::vector<BasicBlock *>> &&GroupsOfBlocks,
200 : GroupsOfBlocks(GroupsOfBlocks), EraseFunctions(EraseFunctions) {}
204 BlockExtractor BE(EraseFunctions);
205 BE.init(GroupsOfBlocks);
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.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
A container for analyses that lazily runs them and caches their results.
LLVM Basic Block Representation.
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.
const BasicBlock * getParent() const
BasicBlock * getUnwindDest() const
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)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef getName() const
Return a constant reference to the value's name.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
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...
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)