Do not crash when dealing with invoke and unwind instructions!
[oota-llvm.git] / tools / bugpoint / ListReducer.h
index 7b9a2f1141249b11ba92801cd83d18a1958812f0..0ad24065cf3cf9e7fea34852e710df1aa2a97ba3 100644 (file)
@@ -1,4 +1,11 @@
 //===- ListReducer.h - Trim down list while retaining property --*- C++ -*-===//
+// 
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// 
+//===----------------------------------------------------------------------===//
 //
 // This class is to be used as a base class for operations that want to zero in
 // on a subset of the input which still causes the bug we are tracking.
@@ -10,6 +17,8 @@
 
 #include <vector>
 
+namespace llvm {
+
 template<typename ElTy>
 struct ListReducer {
   enum TestResult {
@@ -30,18 +39,35 @@ struct ListReducer {
   // list while still maintaining the "test" property.  This is the core of the
   // "work" that bugpoint does.
   //
-  void reduceList(std::vector<ElTy> &TheList) {
+  bool reduceList(std::vector<ElTy> &TheList) {
+    std::vector<ElTy> empty;
+    switch (doTest(TheList, empty)) {
+    case KeepPrefix:
+      if (TheList.size() == 1) // we are done, it's the base case and it fails
+        return true;
+      else 
+        break; // there's definitely an error, but we need to narrow it down
+
+    case KeepSuffix:
+      // cannot be reached!
+      std::cerr << "bugpoint ListReducer internal error: selected empty set.\n";
+      abort();
+
+    case NoFailure:
+      return false; // there is no failure with the full set of passes/funcs!
+    }
+
     unsigned MidTop = TheList.size();
     while (MidTop > 1) {
       unsigned Mid = MidTop / 2;
-      std::vector<ElTy> Prefix(TheList.begin()+Mid, TheList.end());
-      std::vector<ElTy> Kept  (TheList.begin(), TheList.begin()+Mid);
+      std::vector<ElTy> Prefix(TheList.begin(), TheList.begin()+Mid);
+      std::vector<ElTy> Suffix(TheList.begin()+Mid, TheList.end());
 
-      switch (doTest(Prefix, Kept)) {
+      switch (doTest(Prefix, Suffix)) {
       case KeepSuffix:
         // The property still holds.  We can just drop the prefix elements, and
         // shorten the list to the "kept" elements.
-        TheList.swap(Kept);
+        TheList.swap(Suffix);
         MidTop = TheList.size();
         break;
       case KeepPrefix:
@@ -51,7 +77,7 @@ struct ListReducer {
         break;
       case NoFailure:
         // Otherwise the property doesn't hold.  Some of the elements we removed
-        // must be neccesary to maintain the property.
+        // must be necessary to maintain the property.
         MidTop = Mid;
         break;
       }
@@ -80,7 +106,11 @@ struct ListReducer {
         }
       }
     }
+
+    return true; // there are some failure and we've narrowed them down
   }
 };
 
+} // End llvm namespace
+
 #endif