1138c41983fffe8935fa7cc69840e79605ac1306
[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 #if 0
15 class DebugCrashes : public ListReducer<const PassInfo*> {
16   BugDriver &BD;
17 public:
18   DebugCrashes(BugDriver &bd) : BD(bd) {}
19
20   // doTest - Return true iff running the "removed" passes succeeds, and running
21   // the "Kept" passes fail when run on the output of the "removed" passes.  If
22   // we return true, we update the current module of bugpoint.
23   //
24   virtual bool doTest(const std::vector<ElTy> &Removed,
25                       const std::vector<ElTy> &Kept) {
26     return BD.runPasses(Kept);
27   }
28 };
29 #endif
30
31 /// debugCrash - This method is called when some pass crashes on input.  It
32 /// attempts to prune down the testcase to something reasonable, and figure
33 /// out exactly which pass is crashing.
34 ///
35 bool BugDriver::debugCrash() {
36   std::cout << "\n*** Debugging optimizer crash!\n";
37
38 #if 0
39   // Reduce the list of passes which causes the optimizer to crash...
40   DebugCrashes(*this).reduceList(PassesToRun);
41 #endif
42
43   unsigned LastToPass = 0, LastToCrash = PassesToRun.size();
44   while (LastToPass != LastToCrash) {
45     unsigned Mid = (LastToCrash+LastToPass+1) / 2;
46     std::vector<const PassInfo*> P(PassesToRun.begin(),
47                                    PassesToRun.begin()+Mid);
48     std::cout << "Checking to see if the first " << Mid << " passes crash: ";
49
50     if (runPasses(P))
51       LastToCrash = Mid-1;
52     else
53       LastToPass = Mid;
54   }
55
56   // Make sure something crashed.  :)
57   if (LastToCrash >= PassesToRun.size()) {
58     std::cerr << "ERROR: No passes crashed!\n";
59     return true;
60   }
61
62   // Calculate which pass it is that crashes...
63   const PassInfo *CrashingPass = PassesToRun[LastToCrash];
64   
65   std::cout << "\n*** Found crashing pass '-" << CrashingPass->getPassArgument()
66             << "': " << CrashingPass->getPassName() << "\n";
67
68   // Compile the program with just the passes that don't crash.
69   if (LastToPass != 0) { // Don't bother doing this if the first pass crashes...
70     std::vector<const PassInfo*> P(PassesToRun.begin(), 
71                                    PassesToRun.begin()+LastToPass);
72     std::string Filename;
73     std::cout << "Running passes that don't crash to get input for pass: ";
74     if (runPasses(P, Filename)) {
75       std::cerr << "ERROR: Running the first " << LastToPass
76                 << " passes crashed this time!\n";
77       return true;
78     }
79
80     // Assuming everything was successful, we now have a valid bytecode file in
81     // OutputName.  Use it for "Program" Instead.
82     delete Program;
83     Program = ParseInputFile(Filename);
84
85     // Delete the file now.
86     removeFile(Filename);
87   }
88
89   PassesToRun.clear();
90   PassesToRun.push_back(CrashingPass);
91
92   return debugPassCrash(CrashingPass);
93 }
94
95 /// CountFunctions - return the number of non-external functions defined in the
96 /// module.
97 static unsigned CountFunctions(Module *M) {
98   unsigned N = 0;
99   for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
100     if (!I->isExternal())
101       ++N;
102   return N;
103 }
104
105 /// debugPassCrash - This method is called when the specified pass crashes on
106 /// Program as input.  It tries to reduce the testcase to something that still
107 /// crashes, but it smaller.
108 ///
109 bool BugDriver::debugPassCrash(const PassInfo *Pass) {
110   EmitProgressBytecode("passinput");
111   bool Reduced = false, AnyReduction = false;
112
113   if (CountFunctions(Program) > 1) {
114     // Attempt to reduce the input program down to a single function that still
115     // crashes.  Do this by removing everything except for that one function...
116     //
117     std::cout << "\n*** Attempting to reduce the testcase to one function\n";
118
119     for (Module::iterator I = Program->begin(), E = Program->end(); I != E; ++I)
120       if (!I->isExternal()) {
121         // Extract one function from the module...
122         Module *M = extractFunctionFromModule(I);
123
124         // Make the function the current program...
125         std::swap(Program, M);
126         
127         // Find out if the pass still crashes on this pass...
128         std::cout << "Checking function '" << I->getName() << "': ";
129         if (runPass(Pass)) {
130           // Yup, it does, we delete the old module, and continue trying to
131           // reduce the testcase...
132           delete M;
133
134           Reduced = AnyReduction = true;
135           break;
136         }
137         
138         // This pass didn't crash on this function, try the next one.
139         delete Program;
140         Program = M;
141       }
142
143     if (CountFunctions(Program) > 1) {
144       std::cout << "\n*** Couldn't reduce testcase to one function.\n"
145                 << "    Attempting to remove individual functions.\n";
146       std::cout << "XXX Individual function removal unimplemented!\n";
147     }
148   }
149
150   if (Reduced) {
151     EmitProgressBytecode("reduced-function");
152     Reduced = false;
153   }
154
155   // FIXME: This should attempt to delete entire basic blocks at a time to speed
156   // up convergence...
157
158   unsigned Simplification = 4;
159   do {
160     --Simplification;
161     std::cout << "\n*** Attempting to reduce testcase by deleting instruc"
162               << "tions: Simplification Level #" << Simplification << "\n";
163
164     // Now that we have deleted the functions that are unneccesary for the
165     // program, try to remove instructions that are not neccesary to cause the
166     // crash.  To do this, we loop through all of the instructions in the
167     // remaining functions, deleting them (replacing any values produced with
168     // nulls), and then running ADCE and SimplifyCFG.  If the transformed input
169     // still triggers failure, keep deleting until we cannot trigger failure
170     // anymore.
171     //
172   TryAgain:
173     
174     // Loop over all of the (non-terminator) instructions remaining in the
175     // function, attempting to delete them.
176     for (Module::iterator FI = Program->begin(), E = Program->end();
177          FI != E; ++FI)
178       if (!FI->isExternal()) {
179         for (Function::iterator BI = FI->begin(), E = FI->end(); BI != E; ++BI)
180           for (BasicBlock::iterator I = BI->begin(), E = --BI->end();
181                I != E; ++I) {
182             Module *M = deleteInstructionFromProgram(I, Simplification);
183             
184             // Make the function the current program...
185             std::swap(Program, M);
186             
187             // Find out if the pass still crashes on this pass...
188             std::cout << "Checking instruction '" << I->getName() << "': ";
189             if (runPass(Pass)) {
190               // Yup, it does, we delete the old module, and continue trying to
191               // reduce the testcase...
192               delete M;
193               Reduced = AnyReduction = true;
194               goto TryAgain;  // I wish I had a multi-level break here!
195             }
196             
197             // This pass didn't crash without this instruction, try the next
198             // one.
199             delete Program;
200             Program = M;
201           }
202       }
203   } while (Simplification);
204
205   // Try to clean up the testcase by running funcresolve and globaldce...
206   if (AnyReduction) {
207     std::cout << "\n*** Attempting to perform final cleanups: ";
208     Module *M = performFinalCleanups();
209     std::swap(Program, M);
210             
211     // Find out if the pass still crashes on the cleaned up program...
212     if (runPass(Pass)) {
213       // Yup, it does, keep the reduced version...
214       delete M;
215       Reduced = AnyReduction = true;
216     } else {
217       delete Program;   // Otherwise, restore the original module...
218       Program = M;
219     }
220   }
221
222   if (Reduced) {
223     EmitProgressBytecode("reduced-simplified");
224     Reduced = false;
225   }
226
227   return false;
228 }