summaryrefslogtreecommitdiffstats
path: root/llvm/tools/bugpoint/ExtractFunction.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/tools/bugpoint/ExtractFunction.cpp')
-rw-r--r--llvm/tools/bugpoint/ExtractFunction.cpp67
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;
+}
OpenPOWER on IntegriCloud