Add a method to extract a loop


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@12391 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/tools/bugpoint/ExtractFunction.cpp b/tools/bugpoint/ExtractFunction.cpp
index 41b5641..8e39261 100644
--- a/tools/bugpoint/ExtractFunction.cpp
+++ b/tools/bugpoint/ExtractFunction.cpp
@@ -117,7 +117,7 @@
   std::swap(Program, M);
 
   if (Failed) {
-    std::cerr << "Final cleanups failed.  Sorry.  :(\n";
+    std::cerr << "Final cleanups failed.  Sorry. :(  Please report a bug!\n";
   } else {
     delete M;
     M = ParseInputFile(Filename);
@@ -132,6 +132,42 @@
 }
 
 
+/// ExtractLoop - Given a module, extract up to one loop from it into a new
+/// function.  This returns null if there are no extractable loops in the
+/// program or if the loop extractor crashes.
+Module *BugDriver::ExtractLoop(Module *M) {
+  std::vector<const PassInfo*> LoopExtractPasses;
+  LoopExtractPasses.push_back(getPI(createSingleLoopExtractorPass()));
+
+  std::swap(Program, M);
+  std::string Filename;
+  bool Failed = runPasses(LoopExtractPasses, Filename);
+  std::swap(Program, M);
+
+  if (Failed) {
+    std::cerr << "Loop extraction failed.  Sorry. :(  Please report a bug!\n";
+    return 0;
+  } else {
+    Module *NewM = ParseInputFile(Filename);
+    if (NewM == 0) {
+      std::cerr << getToolName() << ": Error reading bytecode file '"
+                << Filename << "'!\n";
+      exit(1);
+    }
+    removeFile(Filename);
+
+    // Check to see if we created any new functions.  If not, no loops were
+    // extracted and we should return null.
+    if (M->size() != NewM->size()) {
+      delete NewM;
+      return 0;
+    }
+
+    return NewM;
+  }
+}
+
+
 // DeleteFunctionBody - "Remove" the function by deleting all of its basic
 // blocks, making it external.
 //