1afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner//===- CrashDebugger.cpp - Debug compilation crashes ----------------------===//
23da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman//
37c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell//                     The LLVM Compiler Infrastructure
47c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell//
521c62da287237d39d0d95004881ea4baae3be6daChris Lattner// This file is distributed under the University of Illinois Open Source
621c62da287237d39d0d95004881ea4baae3be6daChris Lattner// License. See LICENSE.TXT for details.
73da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman//
87c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell//===----------------------------------------------------------------------===//
9afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner//
10afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner// This file defines the bugpoint internals that narrow down compilation crashes
11afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner//
12afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner//===----------------------------------------------------------------------===//
13afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner
14afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner#include "BugDriver.h"
15f1b20d8620b05abaa52f40ac6d21f839b265fb00Chris Lattner#include "ToolRunner.h"
16aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner#include "ListReducer.h"
17e78109eb3a3d177d03cea40b46d9dcfc9bf32210Chris Lattner#include "llvm/Constants.h"
184e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling#include "llvm/DerivedTypes.h"
1947b14a4a6a455c7be169cfd312fcbe796f0ad426Misha Brukman#include "llvm/Instructions.h"
20e49603d79d220a795bd50684c8b1f503ee40f97fMisha Brukman#include "llvm/Module.h"
21e49603d79d220a795bd50684c8b1f503ee40f97fMisha Brukman#include "llvm/Pass.h"
22e49603d79d220a795bd50684c8b1f503ee40f97fMisha Brukman#include "llvm/PassManager.h"
23ef9b9a793949469cdaa4ab6d0173136229dcab7bReid Spencer#include "llvm/ValueSymbolTable.h"
24e032590f58e400ba25e416da5bee10a85ad6d114Nick Lewycky#include "llvm/ADT/SmallPtrSet.h"
25286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner#include "llvm/Analysis/Verifier.h"
26e49603d79d220a795bd50684c8b1f503ee40f97fMisha Brukman#include "llvm/Support/CFG.h"
27286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner#include "llvm/Transforms/Scalar.h"
28aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner#include "llvm/Transforms/Utils/Cloning.h"
29551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#include "llvm/Support/FileUtilities.h"
307c0a93785e283110ff05e4a95062990fd32a8389Andrew Lenharth#include "llvm/Support/CommandLine.h"
31aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner#include <set>
32fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattnerusing namespace llvm;
33afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner
347c0a93785e283110ff05e4a95062990fd32a8389Andrew Lenharthnamespace {
357c0a93785e283110ff05e4a95062990fd32a8389Andrew Lenharth  cl::opt<bool>
367c0a93785e283110ff05e4a95062990fd32a8389Andrew Lenharth  KeepMain("keep-main",
377c0a93785e283110ff05e4a95062990fd32a8389Andrew Lenharth           cl::desc("Force function reduction to keep main"),
387c0a93785e283110ff05e4a95062990fd32a8389Andrew Lenharth           cl::init(false));
3923d471f62eed3518fe7737dbccee52faec4ffe75Torok Edwin  cl::opt<bool>
4023d471f62eed3518fe7737dbccee52faec4ffe75Torok Edwin  NoGlobalRM ("disable-global-remove",
4123d471f62eed3518fe7737dbccee52faec4ffe75Torok Edwin         cl::desc("Do not remove global variables"),
4223d471f62eed3518fe7737dbccee52faec4ffe75Torok Edwin         cl::init(false));
437c0a93785e283110ff05e4a95062990fd32a8389Andrew Lenharth}
447c0a93785e283110ff05e4a95062990fd32a8389Andrew Lenharth
45d0fde30ce850b78371fd1386338350591f9ff494Brian Gaekenamespace llvm {
468261dfed05e32302469ef707cc881fed2c31f85fRafael Espindola  class ReducePassList : public ListReducer<std::string> {
47fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner    BugDriver &BD;
48fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner  public:
4906905db7d2a2b83c1b3236d5552629ada2d8d56dChris Lattner    ReducePassList(BugDriver &bd) : BD(bd) {}
503da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman
51fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner    // doTest - Return true iff running the "removed" passes succeeds, and
52fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner    // running the "Kept" passes fail when run on the output of the "removed"
53fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner    // passes.  If we return true, we update the current module of bugpoint.
54fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner    //
558261dfed05e32302469ef707cc881fed2c31f85fRafael Espindola    virtual TestResult doTest(std::vector<std::string> &Removed,
568261dfed05e32302469ef707cc881fed2c31f85fRafael Espindola                              std::vector<std::string> &Kept,
5722ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky                              std::string &Error);
58fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner  };
59fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner}
60aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner
6106905db7d2a2b83c1b3236d5552629ada2d8d56dChris LattnerReducePassList::TestResult
628261dfed05e32302469ef707cc881fed2c31f85fRafael EspindolaReducePassList::doTest(std::vector<std::string> &Prefix,
638261dfed05e32302469ef707cc881fed2c31f85fRafael Espindola                       std::vector<std::string> &Suffix,
6422ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky                       std::string &Error) {
655f76760c880e6d61c229d2058c5699b033caeae1Reid Spencer  sys::Path PrefixOutput;
66b417c795d2a8832b5edac321dc0d19eca7e3f2f5Chris Lattner  Module *OrigProgram = 0;
67aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner  if (!Prefix.empty()) {
68ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman    outs() << "Checking to see if these passes crash: "
69ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman           << getPassesString(Prefix) << ": ";
705f76760c880e6d61c229d2058c5699b033caeae1Reid Spencer    std::string PfxOutput;
71ca356afe09454b3378165ded4eda294bd6341428Rafael Espindola    if (BD.runPasses(BD.getProgram(), Prefix, PfxOutput))
72aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner      return KeepPrefix;
73b417c795d2a8832b5edac321dc0d19eca7e3f2f5Chris Lattner
74dd04df0ec33a903ee7fc747701bafde622f77d8bReid Spencer    PrefixOutput.set(PfxOutput);
75b417c795d2a8832b5edac321dc0d19eca7e3f2f5Chris Lattner    OrigProgram = BD.Program;
76b417c795d2a8832b5edac321dc0d19eca7e3f2f5Chris Lattner
7774382b7c699120fbec5cb5603c9cf4212eb37f06Chris Lattner    BD.Program = ParseInputFile(PrefixOutput.str(), BD.getContext());
78b417c795d2a8832b5edac321dc0d19eca7e3f2f5Chris Lattner    if (BD.Program == 0) {
7965f57c233cd4499e2e8b52a503201e64edfd6a9eDan Gohman      errs() << BD.getToolName() << ": Error reading bitcode file '"
8074382b7c699120fbec5cb5603c9cf4212eb37f06Chris Lattner             << PrefixOutput.str() << "'!\n";
81b417c795d2a8832b5edac321dc0d19eca7e3f2f5Chris Lattner      exit(1);
82b417c795d2a8832b5edac321dc0d19eca7e3f2f5Chris Lattner    }
83a229c5cce75209047db32c6039aa0b0fd481f049Reid Spencer    PrefixOutput.eraseFromDisk();
84aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner  }
85aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner
86ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman  outs() << "Checking to see if these passes crash: "
87ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman         << getPassesString(Suffix) << ": ";
883da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman
895d8cace94a71169ce8493baa7f3305a27fe0cd84Rafael Espindola  if (BD.runPasses(BD.getProgram(), Suffix)) {
90aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner    delete OrigProgram;            // The suffix crashes alone...
91aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner    return KeepSuffix;
92aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner  }
93aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner
94aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner  // Nothing failed, restore state...
95b417c795d2a8832b5edac321dc0d19eca7e3f2f5Chris Lattner  if (OrigProgram) {
96b417c795d2a8832b5edac321dc0d19eca7e3f2f5Chris Lattner    delete BD.Program;
97b417c795d2a8832b5edac321dc0d19eca7e3f2f5Chris Lattner    BD.Program = OrigProgram;
98b417c795d2a8832b5edac321dc0d19eca7e3f2f5Chris Lattner  }
99aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner  return NoFailure;
100aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner}
101aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner
1024e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendlingnamespace {
1034e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling  /// ReduceCrashingGlobalVariables - This works by removing the global
1044e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling  /// variable's initializer and seeing if the program still crashes. If it
1054e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling  /// does, then we keep that program and try again.
1064e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling  ///
1074e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling  class ReduceCrashingGlobalVariables : public ListReducer<GlobalVariable*> {
1084e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling    BugDriver &BD;
109248d1c65f1ce5bc04b892998b2c2061e6a5f8e1cRafael Espindola    bool (*TestFn)(const BugDriver &, Module *);
1104e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling  public:
1114e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling    ReduceCrashingGlobalVariables(BugDriver &bd,
112248d1c65f1ce5bc04b892998b2c2061e6a5f8e1cRafael Espindola                                  bool (*testFn)(const BugDriver &, Module *))
1134e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling      : BD(bd), TestFn(testFn) {}
1144e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling
11522ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky    virtual TestResult doTest(std::vector<GlobalVariable*> &Prefix,
11622ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky                              std::vector<GlobalVariable*> &Kept,
11722ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky                              std::string &Error) {
1184e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling      if (!Kept.empty() && TestGlobalVariables(Kept))
1194e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling        return KeepSuffix;
1204e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling      if (!Prefix.empty() && TestGlobalVariables(Prefix))
1214e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling        return KeepPrefix;
1224e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling      return NoFailure;
1234e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling    }
1244e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling
12522ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky    bool TestGlobalVariables(std::vector<GlobalVariable*> &GVs);
1264e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling  };
1274e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling}
1284e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling
1294e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendlingbool
1304e3be89cb5cde6e2df294c64db3bc28133b67594Bill WendlingReduceCrashingGlobalVariables::TestGlobalVariables(
13122ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky                              std::vector<GlobalVariable*> &GVs) {
1324e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling  // Clone the program to try hacking it apart...
1331ed219a9d2279ce5a5bbcf16d9b7ccc05cce638cRafael Espindola  ValueToValueMapTy VMap;
134e9916a302f1bacad234d7dafc1df3dc968a6ba0fDevang Patel  Module *M = CloneModule(BD.getProgram(), VMap);
1354e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling
1364e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling  // Convert list to set for fast lookup...
1374e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling  std::set<GlobalVariable*> GVSet;
1384e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling
1394e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling  for (unsigned i = 0, e = GVs.size(); i != e; ++i) {
140e9916a302f1bacad234d7dafc1df3dc968a6ba0fDevang Patel    GlobalVariable* CMGV = cast<GlobalVariable>(VMap[GVs[i]]);
1414e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling    assert(CMGV && "Global Variable not in module?!");
1424e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling    GVSet.insert(CMGV);
1434e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling  }
1444e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling
145ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman  outs() << "Checking for crash with only these global variables: ";
1464e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling  PrintGlobalVariableList(GVs);
147ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman  outs() << ": ";
1484e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling
1494e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling  // Loop over and delete any global variables which we aren't supposed to be
1504e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling  // playing with...
1514e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling  for (Module::global_iterator I = M->global_begin(), E = M->global_end();
1524e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling       I != E; ++I)
153028839db09eb47424cd3955471f2c32c68fee74dNick Lewycky    if (I->hasInitializer() && !GVSet.count(I)) {
1544e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling      I->setInitializer(0);
1554e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling      I->setLinkage(GlobalValue::ExternalLinkage);
1564e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling    }
1574e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling
1584e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling  // Try running the hacked up program...
1594e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling  if (TestFn(BD, M)) {
1604e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling    BD.setNewProgram(M);        // It crashed, keep the trimmed version...
1614e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling
1624e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling    // Make sure to use global variable pointers that point into the now-current
1634e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling    // module.
1644e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling    GVs.assign(GVSet.begin(), GVSet.end());
1654e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling    return true;
1664e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling  }
1674e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling
1684e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling  delete M;
1694e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling  return false;
1704e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling}
1714e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling
1722d24e2a396a1d211baaeedf32148a3b657240170David Blaikienamespace {
1734e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling  /// ReduceCrashingFunctions reducer - This works by removing functions and
1744e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling  /// seeing if the program still crashes. If it does, then keep the newer,
1754e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling  /// smaller program.
1764e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling  ///
177efdc0b505712d1ca4460def27e51c430f033d58dChris Lattner  class ReduceCrashingFunctions : public ListReducer<Function*> {
178fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner    BugDriver &BD;
179248d1c65f1ce5bc04b892998b2c2061e6a5f8e1cRafael Espindola    bool (*TestFn)(const BugDriver &, Module *);
180fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner  public:
1818b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner    ReduceCrashingFunctions(BugDriver &bd,
182248d1c65f1ce5bc04b892998b2c2061e6a5f8e1cRafael Espindola                            bool (*testFn)(const BugDriver &, Module *))
1838b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner      : BD(bd), TestFn(testFn) {}
1843da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman
185efdc0b505712d1ca4460def27e51c430f033d58dChris Lattner    virtual TestResult doTest(std::vector<Function*> &Prefix,
18622ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky                              std::vector<Function*> &Kept,
18722ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky                              std::string &Error) {
188fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner      if (!Kept.empty() && TestFuncs(Kept))
189fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner        return KeepSuffix;
190fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner      if (!Prefix.empty() && TestFuncs(Prefix))
191fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner        return KeepPrefix;
192fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner      return NoFailure;
193fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner    }
1943da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman
195efdc0b505712d1ca4460def27e51c430f033d58dChris Lattner    bool TestFuncs(std::vector<Function*> &Prefix);
196fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner  };
197fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner}
198aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner
199efdc0b505712d1ca4460def27e51c430f033d58dChris Lattnerbool ReduceCrashingFunctions::TestFuncs(std::vector<Function*> &Funcs) {
2007c0a93785e283110ff05e4a95062990fd32a8389Andrew Lenharth
2017c0a93785e283110ff05e4a95062990fd32a8389Andrew Lenharth  //if main isn't present, claim there is no problem
2024e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling  if (KeepMain && find(Funcs.begin(), Funcs.end(),
203688b0490e22eb67623f5aaa24406209be74efcb2Reid Spencer                       BD.getProgram()->getFunction("main")) == Funcs.end())
2047c0a93785e283110ff05e4a95062990fd32a8389Andrew Lenharth    return false;
2057c0a93785e283110ff05e4a95062990fd32a8389Andrew Lenharth
206cf00c4ab3ba308d45d98c5ccab87362cf802facbMisha Brukman  // Clone the program to try hacking it apart...
2071ed219a9d2279ce5a5bbcf16d9b7ccc05cce638cRafael Espindola  ValueToValueMapTy VMap;
208e9916a302f1bacad234d7dafc1df3dc968a6ba0fDevang Patel  Module *M = CloneModule(BD.getProgram(), VMap);
2093da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman
210aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner  // Convert list to set for fast lookup...
211aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner  std::set<Function*> Functions;
212aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner  for (unsigned i = 0, e = Funcs.size(); i != e; ++i) {
213e9916a302f1bacad234d7dafc1df3dc968a6ba0fDevang Patel    Function *CMF = cast<Function>(VMap[Funcs[i]]);
214aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner    assert(CMF && "Function not in module?!");
215ef9b9a793949469cdaa4ab6d0173136229dcab7bReid Spencer    assert(CMF->getFunctionType() == Funcs[i]->getFunctionType() && "wrong ty");
216f6dd0eb5c4a1c4824d7f83fa39586478da618ffdDan Gohman    assert(CMF->getName() == Funcs[i]->getName() && "wrong name");
217f607b79bc78fcbfd8cda01d2d5dbda6cd8253a40Chris Lattner    Functions.insert(CMF);
218aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner  }
219aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner
220ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman  outs() << "Checking for crash with only these functions: ";
221efdc0b505712d1ca4460def27e51c430f033d58dChris Lattner  PrintFunctionList(Funcs);
222ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman  outs() << ": ";
223aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner
224aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner  // Loop over and delete any functions which we aren't supposed to be playing
225aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner  // with...
226aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner  for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
2275cbf985dcbc89fba3208e7baf8b6f488b06d3ec9Reid Spencer    if (!I->isDeclaration() && !Functions.count(I))
228aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner      DeleteFunctionBody(I);
229aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner
230aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner  // Try running the hacked up program...
2318b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner  if (TestFn(BD, M)) {
23206905db7d2a2b83c1b3236d5552629ada2d8d56dChris Lattner    BD.setNewProgram(M);        // It crashed, keep the trimmed version...
233aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner
234aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner    // Make sure to use function pointers that point into the now-current
235aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner    // module.
236aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner    Funcs.assign(Functions.begin(), Functions.end());
237aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner    return true;
238aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner  }
23906905db7d2a2b83c1b3236d5552629ada2d8d56dChris Lattner  delete M;
240aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner  return false;
241aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner}
242aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner
243640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner
244f913f40be8501738fa4bdcae2015dd196dcbfc50Chris Lattnernamespace {
245fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner  /// ReduceCrashingBlocks reducer - This works by setting the terminators of
246fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner  /// all terminators except the specified basic blocks to a 'ret' instruction,
247fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner  /// then running the simplify-cfg pass.  This has the effect of chopping up
248fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner  /// the CFG really fast which can reduce large functions quickly.
249fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner  ///
2508b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner  class ReduceCrashingBlocks : public ListReducer<const BasicBlock*> {
251fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner    BugDriver &BD;
252248d1c65f1ce5bc04b892998b2c2061e6a5f8e1cRafael Espindola    bool (*TestFn)(const BugDriver &, Module *);
253fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner  public:
254248d1c65f1ce5bc04b892998b2c2061e6a5f8e1cRafael Espindola    ReduceCrashingBlocks(BugDriver &bd,
255248d1c65f1ce5bc04b892998b2c2061e6a5f8e1cRafael Espindola                         bool (*testFn)(const BugDriver &, Module *))
2568b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner      : BD(bd), TestFn(testFn) {}
2573da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman
2588b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner    virtual TestResult doTest(std::vector<const BasicBlock*> &Prefix,
25922ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky                              std::vector<const BasicBlock*> &Kept,
26022ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky                              std::string &Error) {
261fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner      if (!Kept.empty() && TestBlocks(Kept))
262fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner        return KeepSuffix;
263fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner      if (!Prefix.empty() && TestBlocks(Prefix))
264fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner        return KeepPrefix;
265fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner      return NoFailure;
266fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner    }
2673da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman
2688b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner    bool TestBlocks(std::vector<const BasicBlock*> &Prefix);
269fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner  };
270fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattner}
271286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner
2728b189277bde5f617405dded0bbd6583e6665f4dfChris Lattnerbool ReduceCrashingBlocks::TestBlocks(std::vector<const BasicBlock*> &BBs) {
273cf00c4ab3ba308d45d98c5ccab87362cf802facbMisha Brukman  // Clone the program to try hacking it apart...
2741ed219a9d2279ce5a5bbcf16d9b7ccc05cce638cRafael Espindola  ValueToValueMapTy VMap;
275e9916a302f1bacad234d7dafc1df3dc968a6ba0fDevang Patel  Module *M = CloneModule(BD.getProgram(), VMap);
2763da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman
277286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner  // Convert list to set for fast lookup...
278e032590f58e400ba25e416da5bee10a85ad6d114Nick Lewycky  SmallPtrSet<BasicBlock*, 8> Blocks;
279e032590f58e400ba25e416da5bee10a85ad6d114Nick Lewycky  for (unsigned i = 0, e = BBs.size(); i != e; ++i)
280e9916a302f1bacad234d7dafc1df3dc968a6ba0fDevang Patel    Blocks.insert(cast<BasicBlock>(VMap[BBs[i]]));
281286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner
282ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman  outs() << "Checking for crash with only these blocks:";
28373b96bd52d9361d5c947e4fb660a46e498f7b407Chris Lattner  unsigned NumPrint = Blocks.size();
28473b96bd52d9361d5c947e4fb660a46e498f7b407Chris Lattner  if (NumPrint > 10) NumPrint = 10;
28573b96bd52d9361d5c947e4fb660a46e498f7b407Chris Lattner  for (unsigned i = 0, e = NumPrint; i != e; ++i)
286ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman    outs() << " " << BBs[i]->getName();
28773b96bd52d9361d5c947e4fb660a46e498f7b407Chris Lattner  if (NumPrint < Blocks.size())
288ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman    outs() << "... <" << Blocks.size() << " total>";
289ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman  outs() << ": ";
290286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner
291286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner  // Loop over and delete any hack up any blocks that are not listed...
292286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner  for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
293286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner    for (Function::iterator BB = I->begin(), E = I->end(); BB != E; ++BB)
2948bc098be0cce48dcc08fea746d28011cac79eef6Chris Lattner      if (!Blocks.count(BB) && BB->getTerminator()->getNumSuccessors()) {
295286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner        // Loop over all of the successors of this block, deleting any PHI nodes
296286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner        // that might include it.
297286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner        for (succ_iterator SI = succ_begin(BB), E = succ_end(BB); SI != E; ++SI)
298286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner          (*SI)->removePredecessor(BB);
299286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner
300e78109eb3a3d177d03cea40b46d9dcfc9bf32210Chris Lattner        TerminatorInst *BBTerm = BB->getTerminator();
301e78109eb3a3d177d03cea40b46d9dcfc9bf32210Chris Lattner
302e49a13e7260b83ce56d01446f2a165cc9f35da7fDan Gohman        if (!BB->getTerminator()->getType()->isVoidTy())
303a7235ea7245028a0723e8ab7fd011386b3900777Owen Anderson          BBTerm->replaceAllUsesWith(Constant::getNullValue(BBTerm->getType()));
3048bc098be0cce48dcc08fea746d28011cac79eef6Chris Lattner
305e78109eb3a3d177d03cea40b46d9dcfc9bf32210Chris Lattner        // Replace the old terminator instruction.
306286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner        BB->getInstList().pop_back();
3071d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson        new UnreachableInst(BB->getContext(), BB);
308286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner      }
309286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner
310286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner  // The CFG Simplifier pass may delete one of the basic blocks we are
311286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner  // interested in.  If it does we need to take the block out of the list.  Make
312286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner  // a "persistent mapping" by turning basic blocks into <function, name> pairs.
313286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner  // This won't work well if blocks are unnamed, but that is just the risk we
314286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner  // have to take.
315866aa0d742b7bc9811fd1b45507af999c605205aRafael Espindola  std::vector<std::pair<std::string, std::string> > BlockInfo;
316286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner
317e032590f58e400ba25e416da5bee10a85ad6d114Nick Lewycky  for (SmallPtrSet<BasicBlock*, 8>::iterator I = Blocks.begin(),
318e032590f58e400ba25e416da5bee10a85ad6d114Nick Lewycky         E = Blocks.end(); I != E; ++I)
319866aa0d742b7bc9811fd1b45507af999c605205aRafael Espindola    BlockInfo.push_back(std::make_pair((*I)->getParent()->getName(),
320866aa0d742b7bc9811fd1b45507af999c605205aRafael Espindola                                       (*I)->getName()));
321286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner
322286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner  // Now run the CFG simplify pass on the function...
323866aa0d742b7bc9811fd1b45507af999c605205aRafael Espindola  std::vector<std::string> Passes;
324866aa0d742b7bc9811fd1b45507af999c605205aRafael Espindola  Passes.push_back("simplifycfg");
325866aa0d742b7bc9811fd1b45507af999c605205aRafael Espindola  Passes.push_back("verify");
326866aa0d742b7bc9811fd1b45507af999c605205aRafael Espindola  Module *New = BD.runPassesOn(M, Passes);
327866aa0d742b7bc9811fd1b45507af999c605205aRafael Espindola  delete M;
328866aa0d742b7bc9811fd1b45507af999c605205aRafael Espindola  if (!New) {
329866aa0d742b7bc9811fd1b45507af999c605205aRafael Espindola    errs() << "simplifycfg failed!\n";
330866aa0d742b7bc9811fd1b45507af999c605205aRafael Espindola    exit(1);
331866aa0d742b7bc9811fd1b45507af999c605205aRafael Espindola  }
332866aa0d742b7bc9811fd1b45507af999c605205aRafael Espindola  M = New;
333286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner
334286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner  // Try running on the hacked up program...
3358b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner  if (TestFn(BD, M)) {
33606905db7d2a2b83c1b3236d5552629ada2d8d56dChris Lattner    BD.setNewProgram(M);      // It crashed, keep the trimmed version...
337286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner
338286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner    // Make sure to use basic block pointers that point into the now-current
339286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner    // module, and that they don't include any deleted blocks.
340286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner    BBs.clear();
341866aa0d742b7bc9811fd1b45507af999c605205aRafael Espindola    const ValueSymbolTable &GST = M->getValueSymbolTable();
342286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner    for (unsigned i = 0, e = BlockInfo.size(); i != e; ++i) {
343866aa0d742b7bc9811fd1b45507af999c605205aRafael Espindola      Function *F = cast<Function>(GST.lookup(BlockInfo[i].first));
344866aa0d742b7bc9811fd1b45507af999c605205aRafael Espindola      ValueSymbolTable &ST = F->getValueSymbolTable();
345ef9b9a793949469cdaa4ab6d0173136229dcab7bReid Spencer      Value* V = ST.lookup(BlockInfo[i].second);
3461d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson      if (V && V->getType() == Type::getLabelTy(V->getContext()))
347ef9b9a793949469cdaa4ab6d0173136229dcab7bReid Spencer        BBs.push_back(cast<BasicBlock>(V));
348286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner    }
349286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner    return true;
350286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner  }
35106905db7d2a2b83c1b3236d5552629ada2d8d56dChris Lattner  delete M;  // It didn't crash, try something else.
352286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner  return false;
353286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner}
354286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner
3554c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewyckynamespace {
3564c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky  /// ReduceCrashingInstructions reducer - This works by removing the specified
3574c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky  /// non-terminator instructions and replacing them with undef.
3584c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky  ///
3594c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky  class ReduceCrashingInstructions : public ListReducer<const Instruction*> {
3604c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky    BugDriver &BD;
361248d1c65f1ce5bc04b892998b2c2061e6a5f8e1cRafael Espindola    bool (*TestFn)(const BugDriver &, Module *);
3624c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky  public:
363248d1c65f1ce5bc04b892998b2c2061e6a5f8e1cRafael Espindola    ReduceCrashingInstructions(BugDriver &bd,
364248d1c65f1ce5bc04b892998b2c2061e6a5f8e1cRafael Espindola                               bool (*testFn)(const BugDriver &, Module *))
3654c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky      : BD(bd), TestFn(testFn) {}
3664c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky
3674c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky    virtual TestResult doTest(std::vector<const Instruction*> &Prefix,
36822ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky                              std::vector<const Instruction*> &Kept,
36922ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky                              std::string &Error) {
3704c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky      if (!Kept.empty() && TestInsts(Kept))
3714c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky        return KeepSuffix;
3724c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky      if (!Prefix.empty() && TestInsts(Prefix))
3734c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky        return KeepPrefix;
3744c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky      return NoFailure;
3754c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky    }
3764c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky
3774c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky    bool TestInsts(std::vector<const Instruction*> &Prefix);
3784c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky  };
3794c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky}
3804c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky
3814c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewyckybool ReduceCrashingInstructions::TestInsts(std::vector<const Instruction*>
3824c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky                                           &Insts) {
3834c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky  // Clone the program to try hacking it apart...
3841ed219a9d2279ce5a5bbcf16d9b7ccc05cce638cRafael Espindola  ValueToValueMapTy VMap;
385e9916a302f1bacad234d7dafc1df3dc968a6ba0fDevang Patel  Module *M = CloneModule(BD.getProgram(), VMap);
3864c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky
3874c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky  // Convert list to set for fast lookup...
3884c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky  SmallPtrSet<Instruction*, 64> Instructions;
3894c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky  for (unsigned i = 0, e = Insts.size(); i != e; ++i) {
3904c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky    assert(!isa<TerminatorInst>(Insts[i]));
391e9916a302f1bacad234d7dafc1df3dc968a6ba0fDevang Patel    Instructions.insert(cast<Instruction>(VMap[Insts[i]]));
3924c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky  }
3934c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky
394ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman  outs() << "Checking for crash with only " << Instructions.size();
3954c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky  if (Instructions.size() == 1)
396ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman    outs() << " instruction: ";
3974c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky  else
398ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman    outs() << " instructions: ";
3994c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky
4004c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky  for (Module::iterator MI = M->begin(), ME = M->end(); MI != ME; ++MI)
4014c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky    for (Function::iterator FI = MI->begin(), FE = MI->end(); FI != FE; ++FI)
4024c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky      for (BasicBlock::iterator I = FI->begin(), E = FI->end(); I != E;) {
4034c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky        Instruction *Inst = I++;
404597362a54bf4bb8de5538b4a1d97c618b18a023cEli Friedman        if (!Instructions.count(Inst) && !isa<TerminatorInst>(Inst) &&
405597362a54bf4bb8de5538b4a1d97c618b18a023cEli Friedman            !isa<LandingPadInst>(Inst)) {
406e49a13e7260b83ce56d01446f2a165cc9f35da7fDan Gohman          if (!Inst->getType()->isVoidTy())
4074c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky            Inst->replaceAllUsesWith(UndefValue::get(Inst->getType()));
4084c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky          Inst->eraseFromParent();
4094c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky        }
4104c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky      }
4114c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky
4124c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky  // Verify that this is still valid.
4134c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky  PassManager Passes;
4144c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky  Passes.add(createVerifierPass());
4154c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky  Passes.run(*M);
4164c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky
4174c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky  // Try running on the hacked up program...
4184c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky  if (TestFn(BD, M)) {
4194c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky    BD.setNewProgram(M);      // It crashed, keep the trimmed version...
4204c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky
4214c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky    // Make sure to use instruction pointers that point into the now-current
4224c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky    // module, and that they don't include any deleted blocks.
4234c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky    Insts.clear();
4244c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky    for (SmallPtrSet<Instruction*, 64>::const_iterator I = Instructions.begin(),
4254c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky             E = Instructions.end(); I != E; ++I)
4264c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky      Insts.push_back(*I);
4274c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky    return true;
4284c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky  }
4294c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky  delete M;  // It didn't crash, try something else.
4304c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky  return false;
4314c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky}
4324c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky
4338b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner/// DebugACrash - Given a predicate that determines whether a component crashes
4348b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner/// on a program, try to destructively reduce the program while still keeping
4358b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner/// the predicate true.
436248d1c65f1ce5bc04b892998b2c2061e6a5f8e1cRafael Espindolastatic bool DebugACrash(BugDriver &BD,
437248d1c65f1ce5bc04b892998b2c2061e6a5f8e1cRafael Espindola                        bool (*TestFn)(const BugDriver &, Module *),
43822ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky                        std::string &Error) {
4394e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling  // See if we can get away with nuking some of the global variable initializers
4405f73e38548c57636ad0ef8c719d040e166761962Chris Lattner  // in the program...
44123d471f62eed3518fe7737dbccee52faec4ffe75Torok Edwin  if (!NoGlobalRM &&
44223d471f62eed3518fe7737dbccee52faec4ffe75Torok Edwin      BD.getProgram()->global_begin() != BD.getProgram()->global_end()) {
4434e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling    // Now try to reduce the number of global variable initializers in the
4444e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling    // module to something small.
445b3d83a3ed5e99cc858141ee4da61fe9f80ec4b00Bill Wendling    Module *M = CloneModule(BD.getProgram());
446b3d83a3ed5e99cc858141ee4da61fe9f80ec4b00Bill Wendling    bool DeletedInit = false;
447b3d83a3ed5e99cc858141ee4da61fe9f80ec4b00Bill Wendling
448b3d83a3ed5e99cc858141ee4da61fe9f80ec4b00Bill Wendling    for (Module::global_iterator I = M->global_begin(), E = M->global_end();
449b3d83a3ed5e99cc858141ee4da61fe9f80ec4b00Bill Wendling         I != E; ++I)
450b3d83a3ed5e99cc858141ee4da61fe9f80ec4b00Bill Wendling      if (I->hasInitializer()) {
451b3d83a3ed5e99cc858141ee4da61fe9f80ec4b00Bill Wendling        I->setInitializer(0);
452b3d83a3ed5e99cc858141ee4da61fe9f80ec4b00Bill Wendling        I->setLinkage(GlobalValue::ExternalLinkage);
453b3d83a3ed5e99cc858141ee4da61fe9f80ec4b00Bill Wendling        DeletedInit = true;
454b3d83a3ed5e99cc858141ee4da61fe9f80ec4b00Bill Wendling      }
455b3d83a3ed5e99cc858141ee4da61fe9f80ec4b00Bill Wendling
456b3d83a3ed5e99cc858141ee4da61fe9f80ec4b00Bill Wendling    if (!DeletedInit) {
457b3d83a3ed5e99cc858141ee4da61fe9f80ec4b00Bill Wendling      delete M;  // No change made...
458b3d83a3ed5e99cc858141ee4da61fe9f80ec4b00Bill Wendling    } else {
459b3d83a3ed5e99cc858141ee4da61fe9f80ec4b00Bill Wendling      // See if the program still causes a crash...
460ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman      outs() << "\nChecking to see if we can delete global inits: ";
461b3d83a3ed5e99cc858141ee4da61fe9f80ec4b00Bill Wendling
462b3d83a3ed5e99cc858141ee4da61fe9f80ec4b00Bill Wendling      if (TestFn(BD, M)) {      // Still crashes?
463b3d83a3ed5e99cc858141ee4da61fe9f80ec4b00Bill Wendling        BD.setNewProgram(M);
464ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman        outs() << "\n*** Able to remove all global initializers!\n";
465b3d83a3ed5e99cc858141ee4da61fe9f80ec4b00Bill Wendling      } else {                  // No longer crashes?
466ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman        outs() << "  - Removing all global inits hides problem!\n";
467b3d83a3ed5e99cc858141ee4da61fe9f80ec4b00Bill Wendling        delete M;
468b3d83a3ed5e99cc858141ee4da61fe9f80ec4b00Bill Wendling
469b3d83a3ed5e99cc858141ee4da61fe9f80ec4b00Bill Wendling        std::vector<GlobalVariable*> GVs;
4703da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman
471b3d83a3ed5e99cc858141ee4da61fe9f80ec4b00Bill Wendling        for (Module::global_iterator I = BD.getProgram()->global_begin(),
472b3d83a3ed5e99cc858141ee4da61fe9f80ec4b00Bill Wendling               E = BD.getProgram()->global_end(); I != E; ++I)
473b3d83a3ed5e99cc858141ee4da61fe9f80ec4b00Bill Wendling          if (I->hasInitializer())
474b3d83a3ed5e99cc858141ee4da61fe9f80ec4b00Bill Wendling            GVs.push_back(I);
4754e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling
476b3d83a3ed5e99cc858141ee4da61fe9f80ec4b00Bill Wendling        if (GVs.size() > 1 && !BugpointIsInterrupted) {
477ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman          outs() << "\n*** Attempting to reduce the number of global "
478b3d83a3ed5e99cc858141ee4da61fe9f80ec4b00Bill Wendling                    << "variables in the testcase\n";
4794e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling
480b3d83a3ed5e99cc858141ee4da61fe9f80ec4b00Bill Wendling          unsigned OldSize = GVs.size();
48122ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky          ReduceCrashingGlobalVariables(BD, TestFn).reduceList(GVs, Error);
48222ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky          if (!Error.empty())
48322ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky            return true;
4844e3be89cb5cde6e2df294c64db3bc28133b67594Bill Wendling
485b3d83a3ed5e99cc858141ee4da61fe9f80ec4b00Bill Wendling          if (GVs.size() < OldSize)
486bae1b71cbb930e419df03db209ebc547a0e4ec72Rafael Espindola            BD.EmitProgressBitcode(BD.getProgram(), "reduced-global-variables");
487b3d83a3ed5e99cc858141ee4da61fe9f80ec4b00Bill Wendling        }
48822706e82d57fd37150d494881a8f90b4043d42a1Bill Wendling      }
4895f73e38548c57636ad0ef8c719d040e166761962Chris Lattner    }
4905f73e38548c57636ad0ef8c719d040e166761962Chris Lattner  }
4913da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman
492aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner  // Now try to reduce the number of functions in the module to something small.
493efdc0b505712d1ca4460def27e51c430f033d58dChris Lattner  std::vector<Function*> Functions;
494efdc0b505712d1ca4460def27e51c430f033d58dChris Lattner  for (Module::iterator I = BD.getProgram()->begin(),
4958b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner         E = BD.getProgram()->end(); I != E; ++I)
4965cbf985dcbc89fba3208e7baf8b6f488b06d3ec9Reid Spencer    if (!I->isDeclaration())
497aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner      Functions.push_back(I);
498afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner
499f9aaae06cd2109082cda2b09ef3f23e0e1cff47bChris Lattner  if (Functions.size() > 1 && !BugpointIsInterrupted) {
500ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman    outs() << "\n*** Attempting to reduce the number of functions "
501aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner      "in the testcase\n";
502afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner
5038b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner    unsigned OldSize = Functions.size();
50422ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky    ReduceCrashingFunctions(BD, TestFn).reduceList(Functions, Error);
505afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner
506f9aaae06cd2109082cda2b09ef3f23e0e1cff47bChris Lattner    if (Functions.size() < OldSize)
507bae1b71cbb930e419df03db209ebc547a0e4ec72Rafael Espindola      BD.EmitProgressBitcode(BD.getProgram(), "reduced-function");
508218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner  }
509218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner
510286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner  // Attempt to delete entire basic blocks at a time to speed up
511286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner  // convergence... this actually works by setting the terminator of the blocks
512286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner  // to a return instruction then running simplifycfg, which can potentially
513286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner  // shrinks the code dramatically quickly
514286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner  //
515f9aaae06cd2109082cda2b09ef3f23e0e1cff47bChris Lattner  if (!DisableSimplifyCFG && !BugpointIsInterrupted) {
5168b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner    std::vector<const BasicBlock*> Blocks;
5178b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner    for (Module::const_iterator I = BD.getProgram()->begin(),
5188b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner           E = BD.getProgram()->end(); I != E; ++I)
5198b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner      for (Function::const_iterator FI = I->begin(), E = I->end(); FI !=E; ++FI)
52047ae4a1cee5eec5767a11403c0fac7c91ec45461Chris Lattner        Blocks.push_back(FI);
5212c235010312f72622acd4b7bb70f87cf31a982f6Torok Edwin    unsigned OldSize = Blocks.size();
52222ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky    ReduceCrashingBlocks(BD, TestFn).reduceList(Blocks, Error);
5232c235010312f72622acd4b7bb70f87cf31a982f6Torok Edwin    if (Blocks.size() < OldSize)
524bae1b71cbb930e419df03db209ebc547a0e4ec72Rafael Espindola      BD.EmitProgressBitcode(BD.getProgram(), "reduced-blocks");
52547ae4a1cee5eec5767a11403c0fac7c91ec45461Chris Lattner  }
5266520785dcd22012535934098942d57c07c7631c2Chris Lattner
5274c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky  // Attempt to delete instructions using bisection. This should help out nasty
5284c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky  // cases with large basic blocks where the problem is at one end.
5294c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky  if (!BugpointIsInterrupted) {
5304c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky    std::vector<const Instruction*> Insts;
5314c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky    for (Module::const_iterator MI = BD.getProgram()->begin(),
5324c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky           ME = BD.getProgram()->end(); MI != ME; ++MI)
5334c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky      for (Function::const_iterator FI = MI->begin(), FE = MI->end(); FI != FE;
5344c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky           ++FI)
5354c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky        for (BasicBlock::const_iterator I = FI->begin(), E = FI->end();
5364c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky             I != E; ++I)
5374c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky          if (!isa<TerminatorInst>(I))
5384c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky            Insts.push_back(I);
5394c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky
54022ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky    ReduceCrashingInstructions(BD, TestFn).reduceList(Insts, Error);
5414c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky  }
5424c8f9af6e0c264a99b41817b2ee78c2297930165Nick Lewycky
543aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner  // FIXME: This should use the list reducer to converge faster by deleting
544aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner  // larger chunks of instructions at a time!
545b2c180f04e4f71a29c8c4a2478179cb1ddd5d859Chris Lattner  unsigned Simplification = 2;
5466520785dcd22012535934098942d57c07c7631c2Chris Lattner  do {
547f9aaae06cd2109082cda2b09ef3f23e0e1cff47bChris Lattner    if (BugpointIsInterrupted) break;
5486520785dcd22012535934098942d57c07c7631c2Chris Lattner    --Simplification;
549ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman    outs() << "\n*** Attempting to reduce testcase by deleting instruc"
550ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman           << "tions: Simplification Level #" << Simplification << '\n';
5516520785dcd22012535934098942d57c07c7631c2Chris Lattner
5525560c9d49ccae132cabf1155f18aa0480dce3edaMisha Brukman    // Now that we have deleted the functions that are unnecessary for the
5535560c9d49ccae132cabf1155f18aa0480dce3edaMisha Brukman    // program, try to remove instructions that are not necessary to cause the
5546520785dcd22012535934098942d57c07c7631c2Chris Lattner    // crash.  To do this, we loop through all of the instructions in the
5556520785dcd22012535934098942d57c07c7631c2Chris Lattner    // remaining functions, deleting them (replacing any values produced with
5566520785dcd22012535934098942d57c07c7631c2Chris Lattner    // nulls), and then running ADCE and SimplifyCFG.  If the transformed input
5576520785dcd22012535934098942d57c07c7631c2Chris Lattner    // still triggers failure, keep deleting until we cannot trigger failure
5586520785dcd22012535934098942d57c07c7631c2Chris Lattner    // anymore.
5596520785dcd22012535934098942d57c07c7631c2Chris Lattner    //
560f66d9069cff9ee8b3658b92d3a13d04d198ada91Chris Lattner    unsigned InstructionsToSkipBeforeDeleting = 0;
5616520785dcd22012535934098942d57c07c7631c2Chris Lattner  TryAgain:
5623da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman
5636520785dcd22012535934098942d57c07c7631c2Chris Lattner    // Loop over all of the (non-terminator) instructions remaining in the
5646520785dcd22012535934098942d57c07c7631c2Chris Lattner    // function, attempting to delete them.
565f66d9069cff9ee8b3658b92d3a13d04d198ada91Chris Lattner    unsigned CurInstructionNum = 0;
5668b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner    for (Module::const_iterator FI = BD.getProgram()->begin(),
5678b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner           E = BD.getProgram()->end(); FI != E; ++FI)
5685cbf985dcbc89fba3208e7baf8b6f488b06d3ec9Reid Spencer      if (!FI->isDeclaration())
5698b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner        for (Function::const_iterator BI = FI->begin(), E = FI->end(); BI != E;
5708b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner             ++BI)
5718b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner          for (BasicBlock::const_iterator I = BI->begin(), E = --BI->end();
572467ef21cafa8be9c62f4adc70a04496607336cd8Bill Wendling               I != E; ++I, ++CurInstructionNum) {
573f66d9069cff9ee8b3658b92d3a13d04d198ada91Chris Lattner            if (InstructionsToSkipBeforeDeleting) {
574f66d9069cff9ee8b3658b92d3a13d04d198ada91Chris Lattner              --InstructionsToSkipBeforeDeleting;
575f66d9069cff9ee8b3658b92d3a13d04d198ada91Chris Lattner            } else {
576f9aaae06cd2109082cda2b09ef3f23e0e1cff47bChris Lattner              if (BugpointIsInterrupted) goto ExitLoops;
577f9aaae06cd2109082cda2b09ef3f23e0e1cff47bChris Lattner
578597362a54bf4bb8de5538b4a1d97c618b18a023cEli Friedman              if (isa<LandingPadInst>(I))
579597362a54bf4bb8de5538b4a1d97c618b18a023cEli Friedman                continue;
580597362a54bf4bb8de5538b4a1d97c618b18a023cEli Friedman
581ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman              outs() << "Checking instruction: " << *I;
582f66d9069cff9ee8b3658b92d3a13d04d198ada91Chris Lattner              Module *M = BD.deleteInstructionFromProgram(I, Simplification);
5833da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman
584f66d9069cff9ee8b3658b92d3a13d04d198ada91Chris Lattner              // Find out if the pass still crashes on this pass...
585f66d9069cff9ee8b3658b92d3a13d04d198ada91Chris Lattner              if (TestFn(BD, M)) {
586f66d9069cff9ee8b3658b92d3a13d04d198ada91Chris Lattner                // Yup, it does, we delete the old module, and continue trying
587f66d9069cff9ee8b3658b92d3a13d04d198ada91Chris Lattner                // to reduce the testcase...
588f66d9069cff9ee8b3658b92d3a13d04d198ada91Chris Lattner                BD.setNewProgram(M);
589f66d9069cff9ee8b3658b92d3a13d04d198ada91Chris Lattner                InstructionsToSkipBeforeDeleting = CurInstructionNum;
590f66d9069cff9ee8b3658b92d3a13d04d198ada91Chris Lattner                goto TryAgain;  // I wish I had a multi-level break here!
591f66d9069cff9ee8b3658b92d3a13d04d198ada91Chris Lattner              }
5923da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman
593f66d9069cff9ee8b3658b92d3a13d04d198ada91Chris Lattner              // This pass didn't crash without this instruction, try the next
594f66d9069cff9ee8b3658b92d3a13d04d198ada91Chris Lattner              // one.
595f66d9069cff9ee8b3658b92d3a13d04d198ada91Chris Lattner              delete M;
5966520785dcd22012535934098942d57c07c7631c2Chris Lattner            }
597467ef21cafa8be9c62f4adc70a04496607336cd8Bill Wendling          }
598f66d9069cff9ee8b3658b92d3a13d04d198ada91Chris Lattner
599f66d9069cff9ee8b3658b92d3a13d04d198ada91Chris Lattner    if (InstructionsToSkipBeforeDeleting) {
600f66d9069cff9ee8b3658b92d3a13d04d198ada91Chris Lattner      InstructionsToSkipBeforeDeleting = 0;
601f66d9069cff9ee8b3658b92d3a13d04d198ada91Chris Lattner      goto TryAgain;
602f66d9069cff9ee8b3658b92d3a13d04d198ada91Chris Lattner    }
6033da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman
6046520785dcd22012535934098942d57c07c7631c2Chris Lattner  } while (Simplification);
605f9aaae06cd2109082cda2b09ef3f23e0e1cff47bChris LattnerExitLoops:
606ba386d943f4a83095d9c625cb0d46c1afe45ed1fChris Lattner
607ba386d943f4a83095d9c625cb0d46c1afe45ed1fChris Lattner  // Try to clean up the testcase by running funcresolve and globaldce...
608f9aaae06cd2109082cda2b09ef3f23e0e1cff47bChris Lattner  if (!BugpointIsInterrupted) {
609ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman    outs() << "\n*** Attempting to perform final cleanups: ";
610f9aaae06cd2109082cda2b09ef3f23e0e1cff47bChris Lattner    Module *M = CloneModule(BD.getProgram());
611f9aaae06cd2109082cda2b09ef3f23e0e1cff47bChris Lattner    M = BD.performFinalCleanups(M, true);
6123da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman
613f9aaae06cd2109082cda2b09ef3f23e0e1cff47bChris Lattner    // Find out if the pass still crashes on the cleaned up program...
614f9aaae06cd2109082cda2b09ef3f23e0e1cff47bChris Lattner    if (TestFn(BD, M)) {
615f9aaae06cd2109082cda2b09ef3f23e0e1cff47bChris Lattner      BD.setNewProgram(M);     // Yup, it does, keep the reduced version...
616f9aaae06cd2109082cda2b09ef3f23e0e1cff47bChris Lattner    } else {
617f9aaae06cd2109082cda2b09ef3f23e0e1cff47bChris Lattner      delete M;
618f9aaae06cd2109082cda2b09ef3f23e0e1cff47bChris Lattner    }
619ba386d943f4a83095d9c625cb0d46c1afe45ed1fChris Lattner  }
620ba386d943f4a83095d9c625cb0d46c1afe45ed1fChris Lattner
621bae1b71cbb930e419df03db209ebc547a0e4ec72Rafael Espindola  BD.EmitProgressBitcode(BD.getProgram(), "reduced-simplified");
622ba386d943f4a83095d9c625cb0d46c1afe45ed1fChris Lattner
6233da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman  return false;
6248b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner}
6258b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner
626248d1c65f1ce5bc04b892998b2c2061e6a5f8e1cRafael Espindolastatic bool TestForOptimizerCrash(const BugDriver &BD, Module *M) {
6278b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner  return BD.runPasses(M);
628afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner}
629d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke
6308b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner/// debugOptimizerCrash - This method is called when some pass crashes on input.
6318b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner/// It attempts to prune down the testcase to something reasonable, and figure
6328b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner/// out exactly which pass is crashing.
6338b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner///
6346a3f31cb707972ebde1e45a61fa8f5bcff132ebaPatrick Jenkinsbool BugDriver::debugOptimizerCrash(const std::string &ID) {
635ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman  outs() << "\n*** Debugging optimizer crash!\n";
6368b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner
63722ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky  std::string Error;
6388b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner  // Reduce the list of passes which causes the optimizer to crash...
639f9aaae06cd2109082cda2b09ef3f23e0e1cff47bChris Lattner  if (!BugpointIsInterrupted)
64022ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky    ReducePassList(*this).reduceList(PassesToRun, Error);
64122ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky  assert(Error.empty());
6428b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner
643ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman  outs() << "\n*** Found crashing pass"
644ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman         << (PassesToRun.size() == 1 ? ": " : "es: ")
645ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman         << getPassesString(PassesToRun) << '\n';
646025262692a6710de29a48e2b3905672cd12d13d2Chris Lattner
647bae1b71cbb930e419df03db209ebc547a0e4ec72Rafael Espindola  EmitProgressBitcode(Program, ID);
6488b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner
64922ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky  bool Success = DebugACrash(*this, TestForOptimizerCrash, Error);
65022ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky  assert(Error.empty());
65122ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky  return Success;
6528b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner}
6538b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner
654248d1c65f1ce5bc04b892998b2c2061e6a5f8e1cRafael Espindolastatic bool TestForCodeGenCrash(const BugDriver &BD, Module *M) {
65522ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky  std::string Error;
65622ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky  BD.compileProgram(M, &Error);
65722ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky  if (!Error.empty()) {
65865f57c233cd4499e2e8b52a503201e64edfd6a9eDan Gohman    errs() << "<crash>\n";
6598b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner    return true;  // Tool is still crashing.
6608b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner  }
66122ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky  errs() << '\n';
66222ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky  return false;
6638b189277bde5f617405dded0bbd6583e6665f4dfChris Lattner}
664025262692a6710de29a48e2b3905672cd12d13d2Chris Lattner
665025262692a6710de29a48e2b3905672cd12d13d2Chris Lattner/// debugCodeGeneratorCrash - This method is called when the code generator
666025262692a6710de29a48e2b3905672cd12d13d2Chris Lattner/// crashes on an input.  It attempts to reduce the input as much as possible
667025262692a6710de29a48e2b3905672cd12d13d2Chris Lattner/// while still causing the code generator to crash.
66822ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewyckybool BugDriver::debugCodeGeneratorCrash(std::string &Error) {
66965f57c233cd4499e2e8b52a503201e64edfd6a9eDan Gohman  errs() << "*** Debugging code generator crash!\n";
670025262692a6710de29a48e2b3905672cd12d13d2Chris Lattner
67122ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky  return DebugACrash(*this, TestForCodeGenCrash, Error);
672025262692a6710de29a48e2b3905672cd12d13d2Chris Lattner}
673