diff options
author | Volkan Keles <vkeles@apple.com> | 2018-01-23 21:51:34 +0000 |
---|---|---|
committer | Volkan Keles <vkeles@apple.com> | 2018-01-23 21:51:34 +0000 |
commit | dc40be75f8537e036b593f454765940e69ef7025 (patch) | |
tree | 0e01c174c0301c8793ac3db35f3de778124e452a /llvm/lib/Transforms/IPO/LoopExtractor.cpp | |
parent | bf3c39877ee3c0b593c3de21e67d55fa7d804621 (diff) | |
download | bcm5719-llvm-dc40be75f8537e036b593f454765940e69ef7025.tar.gz bcm5719-llvm-dc40be75f8537e036b593f454765940e69ef7025.zip |
[llvm-extract] Support extracting basic blocks
Summary:
Currently, there is no way to extract a basic block from a function easily. This patch
extends llvm-extract to extract the specified basic block(s).
Reviewers: loladiro, rafael, bogner
Reviewed By: bogner
Subscribers: hintonda, mgorny, qcolombet, llvm-commits
Differential Revision: https://reviews.llvm.org/D41638
llvm-svn: 323266
Diffstat (limited to 'llvm/lib/Transforms/IPO/LoopExtractor.cpp')
-rw-r--r-- | llvm/lib/Transforms/IPO/LoopExtractor.cpp | 152 |
1 files changed, 0 insertions, 152 deletions
diff --git a/llvm/lib/Transforms/IPO/LoopExtractor.cpp b/llvm/lib/Transforms/IPO/LoopExtractor.cpp index 36b6bdba2cd..6964235df06 100644 --- a/llvm/lib/Transforms/IPO/LoopExtractor.cpp +++ b/llvm/lib/Transforms/IPO/LoopExtractor.cpp @@ -158,155 +158,3 @@ bool LoopExtractor::runOnLoop(Loop *L, LPPassManager &LPM) { Pass *llvm::createSingleLoopExtractorPass() { return new SingleLoopExtractor(); } - - -// BlockFile - A file which contains a list of blocks that should not be -// extracted. -static cl::opt<std::string> -BlockFile("extract-blocks-file", cl::value_desc("filename"), - cl::desc("A file containing list of basic blocks to not extract"), - cl::Hidden); - -namespace { - /// BlockExtractorPass - This pass is used by bugpoint to extract all blocks - /// from the module into their own functions except for those specified by the - /// BlocksToNotExtract list. - class BlockExtractorPass : public ModulePass { - void LoadFile(const char *Filename); - void SplitLandingPadPreds(Function *F); - - std::vector<BasicBlock*> BlocksToNotExtract; - std::vector<std::pair<std::string, std::string> > BlocksToNotExtractByName; - public: - static char ID; // Pass identification, replacement for typeid - BlockExtractorPass() : ModulePass(ID) { - if (!BlockFile.empty()) - LoadFile(BlockFile.c_str()); - } - - bool runOnModule(Module &M) override; - }; -} - -char BlockExtractorPass::ID = 0; -INITIALIZE_PASS(BlockExtractorPass, "extract-blocks", - "Extract Basic Blocks From Module (for bugpoint use)", - false, false) - -// createBlockExtractorPass - This pass extracts all blocks (except those -// specified in the argument list) from the functions in the module. -// -ModulePass *llvm::createBlockExtractorPass() { - return new BlockExtractorPass(); -} - -void BlockExtractorPass::LoadFile(const char *Filename) { - // Load the BlockFile... - std::ifstream In(Filename); - if (!In.good()) { - errs() << "WARNING: BlockExtractor couldn't load file '" << Filename - << "'!\n"; - return; - } - while (In) { - std::string FunctionName, BlockName; - In >> FunctionName; - In >> BlockName; - if (!BlockName.empty()) - BlocksToNotExtractByName.push_back( - std::make_pair(FunctionName, BlockName)); - } -} - -/// SplitLandingPadPreds - The landing pad needs to be extracted with the invoke -/// instruction. The critical edge breaker will refuse to break critical edges -/// to a landing pad. So do them here. After this method runs, all landing pads -/// should have only one predecessor. -void BlockExtractorPass::SplitLandingPadPreds(Function *F) { - for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I) { - InvokeInst *II = dyn_cast<InvokeInst>(I); - if (!II) continue; - BasicBlock *Parent = II->getParent(); - BasicBlock *LPad = II->getUnwindDest(); - - // Look through the landing pad's predecessors. If one of them ends in an - // 'invoke', then we want to split the landing pad. - bool Split = false; - for (pred_iterator - PI = pred_begin(LPad), PE = pred_end(LPad); PI != PE; ++PI) { - BasicBlock *BB = *PI; - if (BB->isLandingPad() && BB != Parent && - isa<InvokeInst>(Parent->getTerminator())) { - Split = true; - break; - } - } - - if (!Split) continue; - - SmallVector<BasicBlock*, 2> NewBBs; - SplitLandingPadPredecessors(LPad, Parent, ".1", ".2", NewBBs); - } -} - -bool BlockExtractorPass::runOnModule(Module &M) { - if (skipModule(M)) - return false; - - std::set<BasicBlock*> TranslatedBlocksToNotExtract; - for (unsigned i = 0, e = BlocksToNotExtract.size(); i != e; ++i) { - BasicBlock *BB = BlocksToNotExtract[i]; - Function *F = BB->getParent(); - - // Map the corresponding function in this module. - Function *MF = M.getFunction(F->getName()); - assert(MF->getFunctionType() == F->getFunctionType() && "Wrong function?"); - - // Figure out which index the basic block is in its function. - Function::iterator BBI = MF->begin(); - std::advance(BBI, std::distance(F->begin(), Function::iterator(BB))); - TranslatedBlocksToNotExtract.insert(&*BBI); - } - - while (!BlocksToNotExtractByName.empty()) { - // There's no way to find BBs by name without looking at every BB inside - // every Function. Fortunately, this is always empty except when used by - // bugpoint in which case correctness is more important than performance. - - std::string &FuncName = BlocksToNotExtractByName.back().first; - std::string &BlockName = BlocksToNotExtractByName.back().second; - - for (Function &F : M) { - if (F.getName() != FuncName) continue; - - for (BasicBlock &BB : F) { - if (BB.getName() != BlockName) continue; - - TranslatedBlocksToNotExtract.insert(&BB); - } - } - - BlocksToNotExtractByName.pop_back(); - } - - // Now that we know which blocks to not extract, figure out which ones we WANT - // to extract. - std::vector<BasicBlock*> BlocksToExtract; - for (Function &F : M) { - SplitLandingPadPreds(&F); - for (BasicBlock &BB : F) - if (!TranslatedBlocksToNotExtract.count(&BB)) - BlocksToExtract.push_back(&BB); - } - - for (BasicBlock *BlockToExtract : BlocksToExtract) { - SmallVector<BasicBlock*, 2> BlocksToExtractVec; - BlocksToExtractVec.push_back(BlockToExtract); - if (const InvokeInst *II = - dyn_cast<InvokeInst>(BlockToExtract->getTerminator())) - BlocksToExtractVec.push_back(II->getUnwindDest()); - CodeExtractor(BlocksToExtractVec).extractCodeRegion(); - } - - return !BlocksToExtract.empty(); -} |