[llvm] r280691 - Revert "bugpoint: Stop threading errors through APIs that never fail"

Justin Bogner via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 5 21:45:37 PDT 2016


Author: bogner
Date: Mon Sep  5 23:45:37 2016
New Revision: 280691

URL: http://llvm.org/viewvc/llvm-project?rev=280691&view=rev
Log:
Revert "bugpoint: Stop threading errors through APIs that never fail"

This isn't the right thing to do - it turns out a number of the APIs
that "never fail" just exit(1) if something bad happens. We can and
should thread Error through this instead.

That diff will make more sense with this reverted. Sorry for the
noise.

This reverts r280690

Modified:
    llvm/trunk/tools/bugpoint/BugDriver.cpp
    llvm/trunk/tools/bugpoint/BugDriver.h
    llvm/trunk/tools/bugpoint/CrashDebugger.cpp
    llvm/trunk/tools/bugpoint/FindBugs.cpp
    llvm/trunk/tools/bugpoint/ListReducer.h
    llvm/trunk/tools/bugpoint/Miscompilation.cpp
    llvm/trunk/tools/bugpoint/bugpoint.cpp

Modified: llvm/trunk/tools/bugpoint/BugDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/bugpoint/BugDriver.cpp?rev=280691&r1=280690&r2=280691&view=diff
==============================================================================
--- llvm/trunk/tools/bugpoint/BugDriver.cpp (original)
+++ llvm/trunk/tools/bugpoint/BugDriver.cpp Mon Sep  5 23:45:37 2016
@@ -146,11 +146,11 @@ bool BugDriver::addSources(const std::ve
 /// run - The top level method that is invoked after all of the instance
 /// variables are set up from command line arguments.
 ///
-bool BugDriver::run() {
+bool BugDriver::run(std::string &ErrMsg) {
   if (run_find_bugs) {
     // Rearrange the passes and apply them to the program. Repeat this process
     // until the user kills the program or we find a bug.
-    return runManyPasses(PassesToRun);
+    return runManyPasses(PassesToRun, ErrMsg);
   }
 
   // If we're not running as a child, the first thing that we must do is
@@ -176,7 +176,7 @@ bool BugDriver::run() {
   compileProgram(Program, &Error);
   if (!Error.empty()) {
     outs() << Error;
-    return debugCodeGeneratorCrash();
+    return debugCodeGeneratorCrash(ErrMsg);
   }
   outs() << '\n';
 
@@ -188,7 +188,7 @@ bool BugDriver::run() {
   if (ReferenceOutputFile.empty()) {
     outs() << "Generating reference output from raw program: ";
     if (!createReferenceFile(Program)) {
-      return debugCodeGeneratorCrash();
+      return debugCodeGeneratorCrash(ErrMsg);
     }
     CreatedOutput = true;
   }
@@ -205,14 +205,14 @@ bool BugDriver::run() {
   bool Diff = diffProgram(Program, "", "", false, &Error);
   if (!Error.empty()) {
     errs() << Error;
-    return debugCodeGeneratorCrash();
+    return debugCodeGeneratorCrash(ErrMsg);
   }
   if (!Diff) {
     outs() << "\n*** Output matches: Debugging miscompilation!\n";
     debugMiscompilation(&Error);
     if (!Error.empty()) {
       errs() << Error;
-      return debugCodeGeneratorCrash();
+      return debugCodeGeneratorCrash(ErrMsg);
     }
     return false;
   }
@@ -222,7 +222,7 @@ bool BugDriver::run() {
   bool Failure = debugCodeGenerator(&Error);
   if (!Error.empty()) {
     errs() << Error;
-    return debugCodeGeneratorCrash();
+    return debugCodeGeneratorCrash(ErrMsg);
   }
   return Failure;
 }

Modified: llvm/trunk/tools/bugpoint/BugDriver.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/bugpoint/BugDriver.h?rev=280691&r1=280690&r2=280691&view=diff
==============================================================================
--- llvm/trunk/tools/bugpoint/BugDriver.h (original)
+++ llvm/trunk/tools/bugpoint/BugDriver.h Mon Sep  5 23:45:37 2016
@@ -85,7 +85,7 @@ public:
   /// variables are set up from command line arguments. The \p as_child argument
   /// indicates whether the driver is to run in parent mode or child mode.
   ///
-  bool run();
+  bool run(std::string &ErrMsg);
 
   /// debugOptimizerCrash - This method is called when some optimizer pass
   /// crashes on input.  It attempts to prune down the testcase to something
@@ -96,7 +96,7 @@ public:
   /// debugCodeGeneratorCrash - This method is called when the code generator
   /// crashes on an input.  It attempts to reduce the input as much as possible
   /// while still causing the code generator to crash.
-  bool debugCodeGeneratorCrash();
+  bool debugCodeGeneratorCrash(std::string &Error);
 
   /// debugMiscompilation - This method is used when the passes selected are not
   /// crashing, but the generated output is semantically different from the
@@ -266,7 +266,8 @@ public:
   /// If the passes did not compile correctly, output the command required to
   /// recreate the failure. This returns true if a compiler error is found.
   ///
-  bool runManyPasses(const std::vector<std::string> &AllPasses);
+  bool runManyPasses(const std::vector<std::string> &AllPasses,
+                     std::string &ErrMsg);
 
   /// writeProgramToFile - This writes the current "Program" to the named
   /// bitcode file.  If an error occurs, true is returned.

Modified: llvm/trunk/tools/bugpoint/CrashDebugger.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/bugpoint/CrashDebugger.cpp?rev=280691&r1=280690&r2=280691&view=diff
==============================================================================
--- llvm/trunk/tools/bugpoint/CrashDebugger.cpp (original)
+++ llvm/trunk/tools/bugpoint/CrashDebugger.cpp Mon Sep  5 23:45:37 2016
@@ -71,13 +71,14 @@ public:
   // passes.  If we return true, we update the current module of bugpoint.
   //
   TestResult doTest(std::vector<std::string> &Removed,
-                    std::vector<std::string> &Kept) override;
+                    std::vector<std::string> &Kept,
+                    std::string &Error) override;
 };
 }
 
 ReducePassList::TestResult
 ReducePassList::doTest(std::vector<std::string> &Prefix,
-                       std::vector<std::string> &Suffix) {
+                       std::vector<std::string> &Suffix, std::string &Error) {
   std::string PrefixOutput;
   Module *OrigProgram = nullptr;
   if (!Prefix.empty()) {
@@ -128,7 +129,8 @@ public:
       : BD(bd), TestFn(testFn) {}
 
   TestResult doTest(std::vector<GlobalVariable *> &Prefix,
-                    std::vector<GlobalVariable *> &Kept) override {
+                    std::vector<GlobalVariable *> &Kept,
+                    std::string &Error) override {
     if (!Kept.empty() && TestGlobalVariables(Kept))
       return KeepSuffix;
     if (!Prefix.empty() && TestGlobalVariables(Prefix))
@@ -197,7 +199,8 @@ public:
       : BD(bd), TestFn(testFn) {}
 
   TestResult doTest(std::vector<Function *> &Prefix,
-                    std::vector<Function *> &Kept) override {
+                    std::vector<Function *> &Kept,
+                    std::string &Error) override {
     if (!Kept.empty() && TestFuncs(Kept))
       return KeepSuffix;
     if (!Prefix.empty() && TestFuncs(Prefix))
@@ -370,7 +373,8 @@ public:
       : BD(BD), TestFn(testFn) {}
 
   TestResult doTest(std::vector<const BasicBlock *> &Prefix,
-                    std::vector<const BasicBlock *> &Kept) override {
+                    std::vector<const BasicBlock *> &Kept,
+                    std::string &Error) override {
     if (!Kept.empty() && TestBlocks(Kept))
       return KeepSuffix;
     if (!Prefix.empty() && TestBlocks(Prefix))
@@ -491,7 +495,8 @@ public:
       : BD(bd), TestFn(testFn), Direction(Direction) {}
 
   TestResult doTest(std::vector<const BasicBlock *> &Prefix,
-                    std::vector<const BasicBlock *> &Kept) override {
+                    std::vector<const BasicBlock *> &Kept,
+                    std::string &Error) override {
     if (!Kept.empty() && TestBlocks(Kept))
       return KeepSuffix;
     if (!Prefix.empty() && TestBlocks(Prefix))
@@ -598,7 +603,8 @@ public:
       : BD(bd), TestFn(testFn), TTI(bd.getProgram()->getDataLayout()) {}
 
   TestResult doTest(std::vector<const BasicBlock *> &Prefix,
-                    std::vector<const BasicBlock *> &Kept) override {
+                    std::vector<const BasicBlock *> &Kept,
+                    std::string &Error) override {
     if (!Kept.empty() && TestBlocks(Kept))
       return KeepSuffix;
     if (!Prefix.empty() && TestBlocks(Prefix))
@@ -692,7 +698,8 @@ public:
       : BD(bd), TestFn(testFn) {}
 
   TestResult doTest(std::vector<const Instruction *> &Prefix,
-                    std::vector<const Instruction *> &Kept) override {
+                    std::vector<const Instruction *> &Kept,
+                    std::string &Error) override {
     if (!Kept.empty() && TestInsts(Kept))
       return KeepSuffix;
     if (!Prefix.empty() && TestInsts(Prefix))
@@ -768,7 +775,8 @@ public:
       : BD(bd), TestFn(testFn) {}
 
   TestResult doTest(std::vector<std::string> &Prefix,
-                    std::vector<std::string> &Kept) override {
+                    std::vector<std::string> &Kept,
+                    std::string &Error) override {
     if (!Kept.empty() && TestNamedMDs(Kept))
       return KeepSuffix;
     if (!Prefix.empty() && TestNamedMDs(Prefix))
@@ -837,7 +845,8 @@ public:
       : BD(bd), TestFn(testFn) {}
 
   TestResult doTest(std::vector<const MDNode *> &Prefix,
-                    std::vector<const MDNode *> &Kept) override {
+                    std::vector<const MDNode *> &Kept,
+                    std::string &Error) override {
     if (!Kept.empty() && TestNamedMDOps(Kept))
       return KeepSuffix;
     if (!Prefix.empty() && TestNamedMDOps(Prefix))
@@ -900,7 +909,8 @@ bool ReduceCrashingNamedMDOps::TestNamed
 
 static void ReduceGlobalInitializers(BugDriver &BD,
                                      bool (*TestFn)(const BugDriver &,
-                                                    Module *)) {
+                                                    Module *),
+                                     std::string &Error) {
   if (BD.getProgram()->global_begin() != BD.getProgram()->global_end()) {
     // Now try to reduce the number of global variable initializers in the
     // module to something small.
@@ -942,7 +952,8 @@ static void ReduceGlobalInitializers(Bug
                  << "variables in the testcase\n";
 
           unsigned OldSize = GVs.size();
-          ReduceCrashingGlobalVariables(BD, TestFn).reduceList(GVs);
+          ReduceCrashingGlobalVariables(BD, TestFn).reduceList(GVs, Error);
+          assert(!Error.empty());
 
           if (GVs.size() < OldSize)
             BD.EmitProgressBitcode(BD.getProgram(), "reduced-global-variables");
@@ -953,7 +964,8 @@ static void ReduceGlobalInitializers(Bug
 }
 
 static void ReduceInsts(BugDriver &BD,
-                        bool (*TestFn)(const BugDriver &, Module *)) {
+                        bool (*TestFn)(const BugDriver &, Module *),
+                        std::string &Error) {
   // Attempt to delete instructions using bisection. This should help out nasty
   // cases with large basic blocks where the problem is at one end.
   if (!BugpointIsInterrupted) {
@@ -964,7 +976,7 @@ static void ReduceInsts(BugDriver &BD,
           if (!isa<TerminatorInst>(&I))
             Insts.push_back(&I);
 
-    ReduceCrashingInstructions(BD, TestFn).reduceList(Insts);
+    ReduceCrashingInstructions(BD, TestFn).reduceList(Insts, Error);
   }
 
   unsigned Simplification = 2;
@@ -1034,11 +1046,12 @@ static void ReduceInsts(BugDriver &BD,
 /// on a program, try to destructively reduce the program while still keeping
 /// the predicate true.
 static bool DebugACrash(BugDriver &BD,
-                        bool (*TestFn)(const BugDriver &, Module *)) {
+                        bool (*TestFn)(const BugDriver &, Module *),
+                        std::string &Error) {
   // See if we can get away with nuking some of the global variable initializers
   // in the program...
   if (!NoGlobalRM)
-    ReduceGlobalInitializers(BD, TestFn);
+    ReduceGlobalInitializers(BD, TestFn, Error);
 
   // Now try to reduce the number of functions in the module to something small.
   std::vector<Function *> Functions;
@@ -1051,7 +1064,7 @@ static bool DebugACrash(BugDriver &BD,
               "in the testcase\n";
 
     unsigned OldSize = Functions.size();
-    ReduceCrashingFunctions(BD, TestFn).reduceList(Functions);
+    ReduceCrashingFunctions(BD, TestFn).reduceList(Functions, Error);
 
     if (Functions.size() < OldSize)
       BD.EmitProgressBitcode(BD.getProgram(), "reduced-function");
@@ -1065,8 +1078,8 @@ static bool DebugACrash(BugDriver &BD,
       for (BasicBlock &BB : F)
         Blocks.push_back(&BB);
     unsigned OldSize = Blocks.size();
-    ReduceCrashingConditionals(BD, TestFn, true).reduceList(Blocks);
-    ReduceCrashingConditionals(BD, TestFn, false).reduceList(Blocks);
+    ReduceCrashingConditionals(BD, TestFn, true).reduceList(Blocks, Error);
+    ReduceCrashingConditionals(BD, TestFn, false).reduceList(Blocks, Error);
     if (Blocks.size() < OldSize)
       BD.EmitProgressBitcode(BD.getProgram(), "reduced-conditionals");
   }
@@ -1082,7 +1095,7 @@ static bool DebugACrash(BugDriver &BD,
       for (BasicBlock &BB : F)
         Blocks.push_back(&BB);
     unsigned OldSize = Blocks.size();
-    ReduceCrashingBlocks(BD, TestFn).reduceList(Blocks);
+    ReduceCrashingBlocks(BD, TestFn).reduceList(Blocks, Error);
     if (Blocks.size() < OldSize)
       BD.EmitProgressBitcode(BD.getProgram(), "reduced-blocks");
   }
@@ -1093,7 +1106,7 @@ static bool DebugACrash(BugDriver &BD,
       for (BasicBlock &BB : F)
         Blocks.push_back(&BB);
     unsigned OldSize = Blocks.size();
-    ReduceSimplifyCFG(BD, TestFn).reduceList(Blocks);
+    ReduceSimplifyCFG(BD, TestFn).reduceList(Blocks, Error);
     if (Blocks.size() < OldSize)
       BD.EmitProgressBitcode(BD.getProgram(), "reduced-simplifycfg");
   }
@@ -1101,7 +1114,7 @@ static bool DebugACrash(BugDriver &BD,
   // Attempt to delete instructions using bisection. This should help out nasty
   // cases with large basic blocks where the problem is at one end.
   if (!BugpointIsInterrupted)
-    ReduceInsts(BD, TestFn);
+    ReduceInsts(BD, TestFn, Error);
 
   if (!NoNamedMDRM) {
     if (!BugpointIsInterrupted) {
@@ -1111,7 +1124,7 @@ static bool DebugACrash(BugDriver &BD,
       std::vector<std::string> NamedMDNames;
       for (auto &NamedMD : BD.getProgram()->named_metadata())
         NamedMDNames.push_back(NamedMD.getName().str());
-      ReduceCrashingNamedMD(BD, TestFn).reduceList(NamedMDNames);
+      ReduceCrashingNamedMD(BD, TestFn).reduceList(NamedMDNames, Error);
     }
 
     if (!BugpointIsInterrupted) {
@@ -1121,7 +1134,7 @@ static bool DebugACrash(BugDriver &BD,
       for (auto &NamedMD : BD.getProgram()->named_metadata())
         for (auto op : NamedMD.operands())
           NamedMDOps.push_back(op);
-      ReduceCrashingNamedMDOps(BD, TestFn).reduceList(NamedMDOps);
+      ReduceCrashingNamedMDOps(BD, TestFn).reduceList(NamedMDOps, Error);
     }
     BD.EmitProgressBitcode(BD.getProgram(), "reduced-named-md");
   }
@@ -1156,9 +1169,11 @@ static bool TestForOptimizerCrash(const
 bool BugDriver::debugOptimizerCrash(const std::string &ID) {
   outs() << "\n*** Debugging optimizer crash!\n";
 
+  std::string Error;
   // Reduce the list of passes which causes the optimizer to crash...
   if (!BugpointIsInterrupted && !DontReducePassList)
-    ReducePassList(*this).reduceList(PassesToRun);
+    ReducePassList(*this).reduceList(PassesToRun, Error);
+  assert(Error.empty());
 
   outs() << "\n*** Found crashing pass"
          << (PassesToRun.size() == 1 ? ": " : "es: ")
@@ -1166,7 +1181,8 @@ bool BugDriver::debugOptimizerCrash(cons
 
   EmitProgressBitcode(Program, ID);
 
-  bool Success = DebugACrash(*this, TestForOptimizerCrash);
+  bool Success = DebugACrash(*this, TestForOptimizerCrash, Error);
+  assert(Error.empty());
   return Success;
 }
 
@@ -1187,8 +1203,8 @@ static bool TestForCodeGenCrash(const Bu
 /// debugCodeGeneratorCrash - This method is called when the code generator
 /// crashes on an input.  It attempts to reduce the input as much as possible
 /// while still causing the code generator to crash.
-bool BugDriver::debugCodeGeneratorCrash() {
+bool BugDriver::debugCodeGeneratorCrash(std::string &Error) {
   errs() << "*** Debugging code generator crash!\n";
 
-  return DebugACrash(*this, TestForCodeGenCrash);
+  return DebugACrash(*this, TestForCodeGenCrash, Error);
 }

Modified: llvm/trunk/tools/bugpoint/FindBugs.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/bugpoint/FindBugs.cpp?rev=280691&r1=280690&r2=280691&view=diff
==============================================================================
--- llvm/trunk/tools/bugpoint/FindBugs.cpp (original)
+++ llvm/trunk/tools/bugpoint/FindBugs.cpp Mon Sep  5 23:45:37 2016
@@ -30,7 +30,8 @@ using namespace llvm;
 /// If the passes did not compile correctly, output the command required to
 /// recreate the failure. This returns true if a compiler error is found.
 ///
-bool BugDriver::runManyPasses(const std::vector<std::string> &AllPasses) {
+bool BugDriver::runManyPasses(const std::vector<std::string> &AllPasses,
+                              std::string &ErrMsg) {
   setPassesToRun(AllPasses);
   outs() << "Starting bug finding procedure...\n\n";
 
@@ -81,7 +82,7 @@ bool BugDriver::runManyPasses(const std:
     if (!Error.empty()) {
       outs() << "\n*** compileProgram threw an exception: ";
       outs() << Error;
-      return debugCodeGeneratorCrash();
+      return debugCodeGeneratorCrash(ErrMsg);
     }
     outs() << '\n';
 
@@ -99,7 +100,7 @@ bool BugDriver::runManyPasses(const std:
     }
     if (!Error.empty()) {
       errs() << Error;
-      debugCodeGeneratorCrash();
+      debugCodeGeneratorCrash(ErrMsg);
       return true;
     }
     outs() << "\n*** diff'd output matches!\n";

Modified: llvm/trunk/tools/bugpoint/ListReducer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/bugpoint/ListReducer.h?rev=280691&r1=280690&r2=280691&view=diff
==============================================================================
--- llvm/trunk/tools/bugpoint/ListReducer.h (original)
+++ llvm/trunk/tools/bugpoint/ListReducer.h Mon Sep  5 23:45:37 2016
@@ -15,6 +15,7 @@
 #ifndef LLVM_TOOLS_BUGPOINT_LISTREDUCER_H
 #define LLVM_TOOLS_BUGPOINT_LISTREDUCER_H
 
+#include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/raw_ostream.h"
 #include <algorithm>
 #include <cstdlib>
@@ -38,16 +39,16 @@ template <typename ElTy> struct ListRedu
   /// test desired.  The testcase is only required to test to see if the Kept
   /// list still satisfies the property, but if it is going to check the prefix
   /// anyway, it can.
-  virtual TestResult doTest(std::vector<ElTy> &Prefix,
-                            std::vector<ElTy> &Kept) = 0;
+  virtual TestResult doTest(std::vector<ElTy> &Prefix, std::vector<ElTy> &Kept,
+                            std::string &Error) = 0;
 
   /// This function attempts to reduce the length of the specified list while
   /// still maintaining the "test" property.  This is the core of the "work"
   /// that bugpoint does.
-  bool reduceList(std::vector<ElTy> &TheList) {
+  bool reduceList(std::vector<ElTy> &TheList, std::string &Error) {
     std::vector<ElTy> empty;
     std::srand(0x6e5ea738); // Seed the random number generator
-    switch (doTest(TheList, empty)) {
+    switch (doTest(TheList, empty, Error)) {
     case KeepPrefix:
       if (TheList.size() == 1) // we are done, it's the base case and it fails
         return true;
@@ -63,6 +64,7 @@ template <typename ElTy> struct ListRedu
       return false; // there is no failure with the full set of passes/funcs!
 
     case InternalError:
+      assert(!Error.empty());
       return true;
     }
 
@@ -95,7 +97,7 @@ template <typename ElTy> struct ListRedu
         std::random_shuffle(ShuffledList.begin(), ShuffledList.end());
         errs() << "\n\n*** Testing shuffled set...\n\n";
         // Check that random shuffle doesn't loose the bug
-        if (doTest(ShuffledList, empty) == KeepPrefix) {
+        if (doTest(ShuffledList, empty, Error) == KeepPrefix) {
           // If the bug is still here, use the shuffled list.
           TheList.swap(ShuffledList);
           MidTop = TheList.size();
@@ -114,7 +116,7 @@ template <typename ElTy> struct ListRedu
       std::vector<ElTy> Prefix(TheList.begin(), TheList.begin() + Mid);
       std::vector<ElTy> Suffix(TheList.begin() + Mid, TheList.end());
 
-      switch (doTest(Prefix, Suffix)) {
+      switch (doTest(Prefix, Suffix, Error)) {
       case KeepSuffix:
         // The property still holds.  We can just drop the prefix elements, and
         // shorten the list to the "kept" elements.
@@ -139,8 +141,9 @@ template <typename ElTy> struct ListRedu
         NumOfIterationsWithoutProgress++;
         break;
       case InternalError:
-        return true;
+        return true; // Error was set by doTest.
       }
+      assert(Error.empty() && "doTest did not return InternalError for error");
     }
 
     // Probability of backjumping from the trimming loop back to the binary
@@ -176,18 +179,14 @@ template <typename ElTy> struct ListRedu
           std::vector<ElTy> TestList(TheList);
           TestList.erase(TestList.begin() + i);
 
-          switch (doTest(EmptyList, TestList)) {
-          case KeepSuffix:
+          if (doTest(EmptyList, TestList, Error) == KeepSuffix) {
             // We can trim down the list!
             TheList.swap(TestList);
             --i; // Don't skip an element of the list
             Changed = true;
-            break;
-          case InternalError:
-            return true;
-          default:
-            break;
           }
+          if (!Error.empty())
+            return true;
         }
         if (TrimIterations >= MaxTrimIterationsWithoutBackJump)
           break;

Modified: llvm/trunk/tools/bugpoint/Miscompilation.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/bugpoint/Miscompilation.cpp?rev=280691&r1=280690&r2=280691&view=diff
==============================================================================
--- llvm/trunk/tools/bugpoint/Miscompilation.cpp (original)
+++ llvm/trunk/tools/bugpoint/Miscompilation.cpp Mon Sep  5 23:45:37 2016
@@ -46,14 +46,13 @@ static llvm::cl::opt<bool> DisableBlockE
 
 class ReduceMiscompilingPasses : public ListReducer<std::string> {
   BugDriver &BD;
-  std::string &Error;
 
 public:
-  ReduceMiscompilingPasses(BugDriver &bd, std::string &Error)
-      : BD(bd), Error(Error) {}
+  ReduceMiscompilingPasses(BugDriver &bd) : BD(bd) {}
 
   TestResult doTest(std::vector<std::string> &Prefix,
-                    std::vector<std::string> &Suffix) override;
+                    std::vector<std::string> &Suffix,
+                    std::string &Error) override;
 };
 } // end anonymous namespace
 
@@ -62,7 +61,8 @@ public:
 ///
 ReduceMiscompilingPasses::TestResult
 ReduceMiscompilingPasses::doTest(std::vector<std::string> &Prefix,
-                                 std::vector<std::string> &Suffix) {
+                                 std::vector<std::string> &Suffix,
+                                 std::string &Error) {
   // First, run the program with just the Suffix passes.  If it is still broken
   // with JUST the kept passes, discard the prefix passes.
   outs() << "Checking to see if '" << getPassesString(Suffix)
@@ -181,26 +181,25 @@ class ReduceMiscompilingFunctions : publ
   BugDriver &BD;
   bool (*TestFn)(BugDriver &, std::unique_ptr<Module>, std::unique_ptr<Module>,
                  std::string &);
-  std::string &Error;
 
 public:
   ReduceMiscompilingFunctions(BugDriver &bd,
                               bool (*F)(BugDriver &, std::unique_ptr<Module>,
-                                        std::unique_ptr<Module>, std::string &),
-                              std::string &Error)
-      : BD(bd), TestFn(F), Error(Error) {}
+                                        std::unique_ptr<Module>, std::string &))
+      : BD(bd), TestFn(F) {}
 
   TestResult doTest(std::vector<Function *> &Prefix,
-                    std::vector<Function *> &Suffix) override {
+                    std::vector<Function *> &Suffix,
+                    std::string &Error) override {
     if (!Suffix.empty()) {
-      bool Ret = TestFuncs(Suffix);
+      bool Ret = TestFuncs(Suffix, Error);
       if (!Error.empty())
         return InternalError;
       if (Ret)
         return KeepSuffix;
     }
     if (!Prefix.empty()) {
-      bool Ret = TestFuncs(Prefix);
+      bool Ret = TestFuncs(Prefix, Error);
       if (!Error.empty())
         return InternalError;
       if (Ret)
@@ -209,7 +208,7 @@ public:
     return NoFailure;
   }
 
-  bool TestFuncs(const std::vector<Function *> &Prefix);
+  bool TestFuncs(const std::vector<Function *> &Prefix, std::string &Error);
 };
 } // end anonymous namespace
 
@@ -239,7 +238,7 @@ static std::unique_ptr<Module> testMerge
 /// accordingly. Each group of functions becomes a separate Module.
 ///
 bool ReduceMiscompilingFunctions::TestFuncs(
-    const std::vector<Function *> &Funcs) {
+    const std::vector<Function *> &Funcs, std::string &Error) {
   // Test to see if the function is misoptimized if we ONLY run it on the
   // functions listed in Funcs.
   outs() << "Checking to see if the program is misoptimized when "
@@ -445,27 +444,26 @@ class ReduceMiscompiledBlocks : public L
   bool (*TestFn)(BugDriver &, std::unique_ptr<Module>, std::unique_ptr<Module>,
                  std::string &);
   std::vector<Function *> FunctionsBeingTested;
-  std::string &Error;
 
 public:
   ReduceMiscompiledBlocks(BugDriver &bd,
                           bool (*F)(BugDriver &, std::unique_ptr<Module>,
                                     std::unique_ptr<Module>, std::string &),
-                          const std::vector<Function *> &Fns,
-                          std::string &Error)
-      : BD(bd), TestFn(F), FunctionsBeingTested(Fns), Error(Error) {}
+                          const std::vector<Function *> &Fns)
+      : BD(bd), TestFn(F), FunctionsBeingTested(Fns) {}
 
   TestResult doTest(std::vector<BasicBlock *> &Prefix,
-                    std::vector<BasicBlock *> &Suffix) override {
+                    std::vector<BasicBlock *> &Suffix,
+                    std::string &Error) override {
     if (!Suffix.empty()) {
-      bool Ret = TestFuncs(Suffix);
+      bool Ret = TestFuncs(Suffix, Error);
       if (!Error.empty())
         return InternalError;
       if (Ret)
         return KeepSuffix;
     }
     if (!Prefix.empty()) {
-      bool Ret = TestFuncs(Prefix);
+      bool Ret = TestFuncs(Prefix, Error);
       if (!Error.empty())
         return InternalError;
       if (Ret)
@@ -474,14 +472,15 @@ public:
     return NoFailure;
   }
 
-  bool TestFuncs(const std::vector<BasicBlock *> &BBs);
+  bool TestFuncs(const std::vector<BasicBlock *> &BBs, std::string &Error);
 };
 } // end anonymous namespace
 
 /// TestFuncs - Extract all blocks for the miscompiled functions except for the
 /// specified blocks.  If the problem still exists, return true.
 ///
-bool ReduceMiscompiledBlocks::TestFuncs(const std::vector<BasicBlock *> &BBs) {
+bool ReduceMiscompiledBlocks::TestFuncs(const std::vector<BasicBlock *> &BBs,
+                                        std::string &Error) {
   // Test to see if the function is misoptimized if we ONLY run it on the
   // functions listed in Funcs.
   outs() << "Checking to see if the program is misoptimized when all ";
@@ -551,15 +550,15 @@ static bool ExtractBlocks(BugDriver &BD,
   unsigned OldSize = Blocks.size();
 
   // Check to see if all blocks are extractible first.
-  bool Ret = ReduceMiscompiledBlocks(BD, TestFn, MiscompiledFunctions, Error)
-                 .TestFuncs(std::vector<BasicBlock *>());
+  bool Ret = ReduceMiscompiledBlocks(BD, TestFn, MiscompiledFunctions)
+                 .TestFuncs(std::vector<BasicBlock *>(), Error);
   if (!Error.empty())
     return false;
   if (Ret) {
     Blocks.clear();
   } else {
-    ReduceMiscompiledBlocks(BD, TestFn, MiscompiledFunctions, Error)
-        .reduceList(Blocks);
+    ReduceMiscompiledBlocks(BD, TestFn, MiscompiledFunctions)
+        .reduceList(Blocks, Error);
     if (!Error.empty())
       return false;
     if (Blocks.size() == OldSize)
@@ -629,8 +628,8 @@ DebugAMiscompilation(BugDriver &BD,
 
   // Do the reduction...
   if (!BugpointIsInterrupted)
-    ReduceMiscompilingFunctions(BD, TestFn, Error)
-        .reduceList(MiscompiledFunctions);
+    ReduceMiscompilingFunctions(BD, TestFn)
+        .reduceList(MiscompiledFunctions, Error);
   if (!Error.empty()) {
     errs() << "\n***Cannot reduce functions: ";
     return MiscompiledFunctions;
@@ -655,8 +654,8 @@ DebugAMiscompilation(BugDriver &BD,
 
       // Do the reduction...
       if (!BugpointIsInterrupted)
-        ReduceMiscompilingFunctions(BD, TestFn, Error)
-            .reduceList(MiscompiledFunctions);
+        ReduceMiscompilingFunctions(BD, TestFn)
+            .reduceList(MiscompiledFunctions, Error);
       if (!Error.empty())
         return MiscompiledFunctions;
 
@@ -678,8 +677,8 @@ DebugAMiscompilation(BugDriver &BD,
       DisambiguateGlobalSymbols(BD.getProgram());
 
       // Do the reduction...
-      ReduceMiscompilingFunctions(BD, TestFn, Error)
-          .reduceList(MiscompiledFunctions);
+      ReduceMiscompilingFunctions(BD, TestFn)
+          .reduceList(MiscompiledFunctions, Error);
       if (!Error.empty())
         return MiscompiledFunctions;
 
@@ -733,7 +732,7 @@ static bool TestOptimizer(BugDriver &BD,
 void BugDriver::debugMiscompilation(std::string *Error) {
   // Make sure something was miscompiled...
   if (!BugpointIsInterrupted)
-    if (!ReduceMiscompilingPasses(*this, *Error).reduceList(PassesToRun)) {
+    if (!ReduceMiscompilingPasses(*this).reduceList(PassesToRun, *Error)) {
       if (Error->empty())
         errs() << "*** Optimized program matches reference output!  No problem"
                << " detected...\nbugpoint can't help you with your problem!\n";

Modified: llvm/trunk/tools/bugpoint/bugpoint.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/bugpoint/bugpoint.cpp?rev=280691&r1=280690&r2=280691&view=diff
==============================================================================
--- llvm/trunk/tools/bugpoint/bugpoint.cpp (original)
+++ llvm/trunk/tools/bugpoint/bugpoint.cpp Mon Sep  5 23:45:37 2016
@@ -197,5 +197,11 @@ int main(int argc, char **argv) {
   sys::Process::PreventCoreFiles();
 #endif
 
-  return D.run();
+  std::string Error;
+  bool Failure = D.run(Error);
+  if (!Error.empty()) {
+    errs() << Error;
+    return 1;
+  }
+  return Failure;
 }




More information about the llvm-commits mailing list