diff options
Diffstat (limited to 'llvm/tools/bugpoint/ExtractFunction.cpp')
-rw-r--r-- | llvm/tools/bugpoint/ExtractFunction.cpp | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/llvm/tools/bugpoint/ExtractFunction.cpp b/llvm/tools/bugpoint/ExtractFunction.cpp index 9f8dca8abd0..ecc2652556e 100644 --- a/llvm/tools/bugpoint/ExtractFunction.cpp +++ b/llvm/tools/bugpoint/ExtractFunction.cpp @@ -22,6 +22,7 @@ #include "llvm/Transforms/IPO.h" #include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Utils/Cloning.h" +#include "llvm/Transforms/Utils/FunctionUtils.h" #include "llvm/Target/TargetData.h" #include "Support/CommandLine.h" #include "Support/Debug.h" @@ -199,3 +200,69 @@ Module *llvm::SplitFunctionsOutOfModule(Module *M, DeleteFunctionBody(I); return New; } + +//===----------------------------------------------------------------------===// +// Basic Block Extraction Code +//===----------------------------------------------------------------------===// + +namespace { + std::vector<BasicBlock*> BlocksToNotExtract; + + /// 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 Pass { + bool run(Module &M); + }; + RegisterOpt<BlockExtractorPass> + XX("extract-bbs", "Extract Basic Blocks From Module (for bugpoint use)"); +} + +bool BlockExtractorPass::run(Module &M) { + 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(), F->getFunctionType()); + + // 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); + } + + // Now that we know which blocks to not extract, figure out which ones we WANT + // to extract. + std::vector<BasicBlock*> BlocksToExtract; + for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) + for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) + if (!TranslatedBlocksToNotExtract.count(BB)) + BlocksToExtract.push_back(BB); + + for (unsigned i = 0, e = BlocksToExtract.size(); i != e; ++i) + ExtractBasicBlock(BlocksToExtract[i]); + + return !BlocksToExtract.empty(); +} + +/// ExtractMappedBlocksFromModule - Extract all but the specified basic blocks +/// into their own functions. The only detail is that M is actually a module +/// cloned from the one the BBs are in, so some mapping needs to be performed. +/// If this operation fails for some reason (ie the implementation is buggy), +/// this function should return null, otherwise it returns a new Module. +Module *BugDriver::ExtractMappedBlocksFromModule(const + std::vector<BasicBlock*> &BBs, + Module *M) { + // Set the global list so that pass will be able to access it. + BlocksToNotExtract = BBs; + + std::vector<const PassInfo*> PI; + PI.push_back(getPI(new BlockExtractorPass())); + Module *Ret = runPassesOn(M, PI); + BlocksToNotExtract.clear(); + if (Ret == 0) + std::cout << "*** Basic Block extraction failed, please report a bug!\n"; + return Ret; +} |