c69ca453621d71a618b5381ce5b96de0f8d7ce6b
[oota-llvm.git] / tools / bugpoint / CrashDebugger.cpp
1 //===- CrashDebugger.cpp - Debug compilation crashes ----------------------===//
2 //
3 // This file defines the bugpoint internals that narrow down compilation crashes
4 //
5 //===----------------------------------------------------------------------===//
6
7 #include "BugDriver.h"
8 #include "SystemUtils.h"
9 #include "llvm/Module.h"
10 #include "llvm/Bytecode/Writer.h"
11 #include "llvm/Pass.h"
12 #include <fstream>
13
14 /// debugCrash - This method is called when some pass crashes on input.  It
15 /// attempts to prune down the testcase to something reasonable, and figure
16 /// out exactly which pass is crashing.
17 ///
18 bool BugDriver::debugCrash() {
19   std::cout << "\n*** Debugging optimizer crash!\n";
20
21   // Determine which pass causes the optimizer to crash... using binary search
22   unsigned LastToPass = 0, LastToCrash = PassesToRun.size();
23   while (LastToPass != LastToCrash) {
24     unsigned Mid = (LastToCrash+LastToPass+1) / 2;
25     std::vector<const PassInfo*> P(PassesToRun.begin(),
26                                    PassesToRun.begin()+Mid);
27     std::cout << "Checking to see if the first " << Mid << " passes crash: ";
28
29     if (runPasses(P))
30       LastToCrash = Mid-1;
31     else
32       LastToPass = Mid;
33   }
34
35   // Make sure something crashed.  :)
36   if (LastToCrash >= PassesToRun.size()) {
37     std::cerr << "ERROR: No passes crashed!\n";
38     return true;
39   }
40
41   // Calculate which pass it is that crashes...
42   const PassInfo *CrashingPass = PassesToRun[LastToCrash];
43   
44   std::cout << "\n*** Found crashing pass '-" << CrashingPass->getPassArgument()
45             << "': " << CrashingPass->getPassName() << "\n";
46
47   // Compile the program with just the passes that don't crash.
48   if (LastToPass != 0) { // Don't bother doing this if the first pass crashes...
49     std::vector<const PassInfo*> P(PassesToRun.begin(), 
50                                    PassesToRun.begin()+LastToPass);
51     std::string Filename;
52     std::cout << "Running passes that don't crash to get input for pass: ";
53     if (runPasses(P, Filename)) {
54       std::cerr << "ERROR: Running the first " << LastToPass
55                 << " passes crashed this time!\n";
56       return true;
57     }
58
59     // Assuming everything was successful, we now have a valid bytecode file in
60     // OutputName.  Use it for "Program" Instead.
61     delete Program;
62     Program = ParseInputFile(Filename);
63
64     // Delete the file now.
65     removeFile(Filename);
66   }
67
68   return debugPassCrash(CrashingPass);
69 }
70
71 /// CountFunctions - return the number of non-external functions defined in the
72 /// module.
73 static unsigned CountFunctions(Module *M) {
74   unsigned N = 0;
75   for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
76     if (!I->isExternal())
77       ++N;
78   return N;
79 }
80
81 /// debugPassCrash - This method is called when the specified pass crashes on
82 /// Program as input.  It tries to reduce the testcase to something that still
83 /// crashes, but it smaller.
84 ///
85 bool BugDriver::debugPassCrash(const PassInfo *Pass) {
86   EmitProgressBytecode(Pass, "passinput");
87
88   if (CountFunctions(Program) > 1) {
89     // Attempt to reduce the input program down to a single function that still
90     // crashes.  Do this by removing everything except for that one function...
91     //
92     std::cout << "\n*** Attempting to reduce the testcase to one function\n";
93
94     for (Module::iterator I = Program->begin(), E = Program->end(); I != E; ++I)
95       if (!I->isExternal()) {
96         // Extract one function from the module...
97         Module *M = extractFunctionFromModule(I);
98
99         // Make the function the current program...
100         std::swap(Program, M);
101         
102         // Find out if the pass still crashes on this pass...
103         std::cout << "Checking function '" << I->getName() << "': ";
104         if (runPass(Pass)) {
105           // Yup, it does, we delete the old module, and continue trying to
106           // reduce the testcase...
107           delete M;
108
109           EmitProgressBytecode(Pass, "reduced-"+I->getName());
110           break;
111         }
112         
113         // This pass didn't crash on this function, try the next one.
114         delete Program;
115         Program = M;
116       }
117   }
118
119   if (CountFunctions(Program) > 1) {
120     std::cout << "\n*** Couldn't reduce testcase to one function.\n"
121               << "    Attempting to remove individual functions.\n";
122     std::cout << "XXX Individual function removal unimplemented!\n";
123   }
124
125   // Now that we have deleted the functions that are unneccesary for the
126   // program, try to remove instructions and basic blocks that are not neccesary
127   // to cause the crash.
128   //
129   
130   return false;
131 }