diff options
| -rw-r--r-- | llvm/tools/bugpoint/BugDriver.h | 4 | ||||
| -rw-r--r-- | llvm/tools/bugpoint/CrashDebugger.cpp | 41 | ||||
| -rw-r--r-- | llvm/tools/bugpoint/ListReducer.h | 13 | ||||
| -rw-r--r-- | llvm/tools/bugpoint/Miscompilation.cpp | 21 | ||||
| -rw-r--r-- | llvm/tools/bugpoint/bugpoint.cpp | 10 | 
5 files changed, 59 insertions, 30 deletions
diff --git a/llvm/tools/bugpoint/BugDriver.h b/llvm/tools/bugpoint/BugDriver.h index 51798d29a56..192ed527178 100644 --- a/llvm/tools/bugpoint/BugDriver.h +++ b/llvm/tools/bugpoint/BugDriver.h @@ -35,6 +35,10 @@ class GCC;  extern bool DisableSimplifyCFG; +/// BugpointIsInterrupted - Set to true when the user presses ctrl-c. +/// +extern bool BugpointIsInterrupted; +  class BugDriver {    const std::string ToolName;  // Name of bugpoint    std::string ReferenceOutputFile; // Name of `good' output file diff --git a/llvm/tools/bugpoint/CrashDebugger.cpp b/llvm/tools/bugpoint/CrashDebugger.cpp index b63ce219e89..0d04b2563fe 100644 --- a/llvm/tools/bugpoint/CrashDebugger.cpp +++ b/llvm/tools/bugpoint/CrashDebugger.cpp @@ -261,8 +261,6 @@ bool ReduceCrashingBlocks::TestBlocks(std::vector<const BasicBlock*> &BBs) {  /// on a program, try to destructively reduce the program while still keeping  /// the predicate true.  static bool DebugACrash(BugDriver &BD,  bool (*TestFn)(BugDriver &, Module *)) { -  bool AnyReduction = false; -    // See if we can get away with nuking all of the global variable initializers    // in the program...    if (BD.getProgram()->global_begin() != BD.getProgram()->global_end()) { @@ -282,7 +280,6 @@ static bool DebugACrash(BugDriver &BD,  bool (*TestFn)(BugDriver &, Module *)) {        std::cout << "\nChecking to see if we can delete global inits: ";        if (TestFn(BD, M)) {  // Still crashes?          BD.setNewProgram(M); -        AnyReduction = true;          std::cout << "\n*** Able to remove all global initializers!\n";        } else {                       // No longer crashes?          std::cout << "  - Removing all global inits hides problem!\n"; @@ -298,17 +295,15 @@ static bool DebugACrash(BugDriver &BD,  bool (*TestFn)(BugDriver &, Module *)) {      if (!I->isExternal())        Functions.push_back(I); -  if (Functions.size() > 1) { +  if (Functions.size() > 1 && !BugpointIsInterrupted) {      std::cout << "\n*** Attempting to reduce the number of functions "        "in the testcase\n";      unsigned OldSize = Functions.size();      ReduceCrashingFunctions(BD, TestFn).reduceList(Functions); -    if (Functions.size() < OldSize) { +    if (Functions.size() < OldSize)        BD.EmitProgressBytecode("reduced-function"); -      AnyReduction = true; -    }    }    // Attempt to delete entire basic blocks at a time to speed up @@ -316,7 +311,7 @@ static bool DebugACrash(BugDriver &BD,  bool (*TestFn)(BugDriver &, Module *)) {    // to a return instruction then running simplifycfg, which can potentially    // shrinks the code dramatically quickly    // -  if (!DisableSimplifyCFG) { +  if (!DisableSimplifyCFG && !BugpointIsInterrupted) {      std::vector<const BasicBlock*> Blocks;      for (Module::const_iterator I = BD.getProgram()->begin(),             E = BD.getProgram()->end(); I != E; ++I) @@ -329,6 +324,7 @@ static bool DebugACrash(BugDriver &BD,  bool (*TestFn)(BugDriver &, Module *)) {    // larger chunks of instructions at a time!    unsigned Simplification = 2;    do { +    if (BugpointIsInterrupted) break;      --Simplification;      std::cout << "\n*** Attempting to reduce testcase by deleting instruc"                << "tions: Simplification Level #" << Simplification << '\n'; @@ -357,6 +353,8 @@ static bool DebugACrash(BugDriver &BD,  bool (*TestFn)(BugDriver &, Module *)) {              if (InstructionsToSkipBeforeDeleting) {                --InstructionsToSkipBeforeDeleting;              } else { +              if (BugpointIsInterrupted) goto ExitLoops; +                std::cout << "Checking instruction '" << I->getName() << "': ";                Module *M = BD.deleteInstructionFromProgram(I, Simplification); @@ -365,7 +363,6 @@ static bool DebugACrash(BugDriver &BD,  bool (*TestFn)(BugDriver &, Module *)) {                  // Yup, it does, we delete the old module, and continue trying                  // to reduce the testcase...                  BD.setNewProgram(M); -                AnyReduction = true;                  InstructionsToSkipBeforeDeleting = CurInstructionNum;                  goto TryAgain;  // I wish I had a multi-level break here!                } @@ -381,22 +378,23 @@ static bool DebugACrash(BugDriver &BD,  bool (*TestFn)(BugDriver &, Module *)) {      }    } while (Simplification); +ExitLoops:    // Try to clean up the testcase by running funcresolve and globaldce... -  std::cout << "\n*** Attempting to perform final cleanups: "; -  Module *M = CloneModule(BD.getProgram()); -  M = BD.performFinalCleanups(M, true); +  if (!BugpointIsInterrupted) { +    std::cout << "\n*** Attempting to perform final cleanups: "; +    Module *M = CloneModule(BD.getProgram()); +    M = BD.performFinalCleanups(M, true); -  // Find out if the pass still crashes on the cleaned up program... -  if (TestFn(BD, M)) { -    BD.setNewProgram(M);     // Yup, it does, keep the reduced version... -    AnyReduction = true; -  } else { -    delete M; +    // Find out if the pass still crashes on the cleaned up program... +    if (TestFn(BD, M)) { +      BD.setNewProgram(M);     // Yup, it does, keep the reduced version... +    } else { +      delete M; +    }    } -  if (AnyReduction) -    BD.EmitProgressBytecode("reduced-simplified"); +  BD.EmitProgressBytecode("reduced-simplified");    return false;  } @@ -414,7 +412,8 @@ bool BugDriver::debugOptimizerCrash() {    // Reduce the list of passes which causes the optimizer to crash...    unsigned OldSize = PassesToRun.size(); -  ReducePassList(*this).reduceList(PassesToRun); +  if (!BugpointIsInterrupted) +    ReducePassList(*this).reduceList(PassesToRun);    std::cout << "\n*** Found crashing pass"              << (PassesToRun.size() == 1 ? ": " : "es: ") diff --git a/llvm/tools/bugpoint/ListReducer.h b/llvm/tools/bugpoint/ListReducer.h index daeadba8854..ff2a11d5e91 100644 --- a/llvm/tools/bugpoint/ListReducer.h +++ b/llvm/tools/bugpoint/ListReducer.h @@ -19,6 +19,8 @@  #include <iostream>  namespace llvm { +   +  extern bool BugpointIsInterrupted;  template<typename ElTy>  struct ListReducer { @@ -62,6 +64,12 @@ struct ListReducer {      unsigned MidTop = TheList.size();      while (MidTop > 1) { +      // Halt if the user presses ctrl-c. +      if (BugpointIsInterrupted) { +        std::cerr << "\n\n*** Reduction Interrupted, cleaning up...\n\n"; +        return true; +      } +              unsigned Mid = MidTop / 2;        std::vector<ElTy> Prefix(TheList.begin(), TheList.begin()+Mid);        std::vector<ElTy> Suffix(TheList.begin()+Mid, TheList.end()); @@ -97,6 +105,11 @@ struct ListReducer {          Changed = false;          std::vector<ElTy> TrimmedList;          for (unsigned i = 1; i < TheList.size()-1; ++i) { // Check interior elts +          if (BugpointIsInterrupted) { +            std::cerr << "\n\n*** Reduction Interrupted, cleaning up...\n\n"; +            return true; +          } +                      std::vector<ElTy> TestList(TheList);            TestList.erase(TestList.begin()+i); diff --git a/llvm/tools/bugpoint/Miscompilation.cpp b/llvm/tools/bugpoint/Miscompilation.cpp index dc43126670c..834e6879958 100644 --- a/llvm/tools/bugpoint/Miscompilation.cpp +++ b/llvm/tools/bugpoint/Miscompilation.cpp @@ -407,6 +407,8 @@ bool ReduceMiscompiledBlocks::TestFuncs(const std::vector<BasicBlock*> &BBs) {  static bool ExtractBlocks(BugDriver &BD,                            bool (*TestFn)(BugDriver &, Module *, Module *),                            std::vector<Function*> &MiscompiledFunctions) { +  if (BugpointIsInterrupted) return false; +      std::vector<BasicBlock*> Blocks;    for (unsigned i = 0, e = MiscompiledFunctions.size(); i != e; ++i)      for (Function::iterator I = MiscompiledFunctions[i]->begin(), @@ -493,7 +495,8 @@ DebugAMiscompilation(BugDriver &BD,        MiscompiledFunctions.push_back(I);    // Do the reduction... -  ReduceMiscompilingFunctions(BD, TestFn).reduceList(MiscompiledFunctions); +  if (!BugpointIsInterrupted) +    ReduceMiscompilingFunctions(BD, TestFn).reduceList(MiscompiledFunctions);    std::cout << "\n*** The following function"              << (MiscompiledFunctions.size() == 1 ? " is" : "s are") @@ -513,7 +516,8 @@ DebugAMiscompilation(BugDriver &BD,      DisambiguateGlobalSymbols(BD.getProgram());      // Do the reduction... -    ReduceMiscompilingFunctions(BD, TestFn).reduceList(MiscompiledFunctions); +    if (!BugpointIsInterrupted) +      ReduceMiscompilingFunctions(BD, TestFn).reduceList(MiscompiledFunctions);      std::cout << "\n*** The following function"                << (MiscompiledFunctions.size() == 1 ? " is" : "s are") @@ -570,11 +574,12 @@ static bool TestOptimizer(BugDriver &BD, Module *Test, Module *Safe) {  ///  bool BugDriver::debugMiscompilation() {    // Make sure something was miscompiled... -  if (!ReduceMiscompilingPasses(*this).reduceList(PassesToRun)) { -    std::cerr << "*** Optimized program matches reference output!  No problem " -              << "detected...\nbugpoint can't help you with your problem!\n"; -    return false; -  } +  if (!BugpointIsInterrupted) +    if (!ReduceMiscompilingPasses(*this).reduceList(PassesToRun)) { +      std::cerr << "*** Optimized program matches reference output!  No problem" +                << " detected...\nbugpoint can't help you with your problem!\n"; +      return false; +    }    std::cout << "\n*** Found miscompiling pass"              << (getPassesToRun().size() == 1 ? "" : "es") << ": " @@ -663,7 +668,7 @@ static void CleanupAndPrepareModules(BugDriver &BD, Module *&Test,    for (Module::iterator F = Safe->begin(), E = Safe->end(); F != E; ++F) {      if (F->isExternal() && !F->use_empty() && &*F != resolverFunc &&          F->getIntrinsicID() == 0 /* ignore intrinsics */) { -      Function *TestFn = Test->getFunction(F->getName(), F->getFunctionType()); +      Function *TestFn = Test->getNamedFunction(F->getName());        // Don't forward functions which are external in the test module too.        if (TestFn && !TestFn->isExternal()) { diff --git a/llvm/tools/bugpoint/bugpoint.cpp b/llvm/tools/bugpoint/bugpoint.cpp index 3cbb4c0ff67..a4442c7ef97 100644 --- a/llvm/tools/bugpoint/bugpoint.cpp +++ b/llvm/tools/bugpoint/bugpoint.cpp @@ -32,13 +32,21 @@ InputFilenames(cl::Positional, cl::OneOrMore,  static cl::list<const PassInfo*, bool, PassNameParser>  PassList(cl::desc("Passes available:"), cl::ZeroOrMore); +/// BugpointIsInterrupted - Set to true when the user presses ctrl-c. +bool llvm::BugpointIsInterrupted = false; + +static void BugpointInterruptFunction() { +  BugpointIsInterrupted = true; +} +  int main(int argc, char **argv) {    cl::ParseCommandLineOptions(argc, argv,                                " LLVM automatic testcase reducer. See\nhttp://"                                "llvm.cs.uiuc.edu/docs/CommandGuide/bugpoint.html"                                " for more information.\n");    sys::PrintStackTraceOnErrorSignal(); - +  sys::SetInterruptFunction(BugpointInterruptFunction); +      BugDriver D(argv[0]);    if (D.addSources(InputFilenames)) return 1;    D.addPasses(PassList.begin(), PassList.end());  | 

