FindBugs.cpp revision 198090
1//===-- FindBugs.cpp - Run Many Different Optimizations -------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file defines an interface that allows bugpoint to choose different 11// combinations of optimizations to run on the selected input. Bugpoint will 12// run these optimizations and record the success/failure of each. This way 13// we can hopefully spot bugs in the optimizations. 14// 15//===----------------------------------------------------------------------===// 16 17#include "BugDriver.h" 18#include "ToolRunner.h" 19#include "llvm/Pass.h" 20#include "llvm/Support/raw_ostream.h" 21#include <algorithm> 22#include <ctime> 23using namespace llvm; 24 25/// runManyPasses - Take the specified pass list and create different 26/// combinations of passes to compile the program with. Compile the program with 27/// each set and mark test to see if it compiled correctly. If the passes 28/// compiled correctly output nothing and rearrange the passes into a new order. 29/// If the passes did not compile correctly, output the command required to 30/// recreate the failure. This returns true if a compiler error is found. 31/// 32bool BugDriver::runManyPasses(const std::vector<const PassInfo*> &AllPasses) { 33 setPassesToRun(AllPasses); 34 outs() << "Starting bug finding procedure...\n\n"; 35 36 // Creating a reference output if necessary 37 if (initializeExecutionEnvironment()) return false; 38 39 outs() << "\n"; 40 if (ReferenceOutputFile.empty()) { 41 outs() << "Generating reference output from raw program: \n"; 42 if (!createReferenceFile(Program)) 43 return false; 44 } 45 46 srand(time(NULL)); 47 48 unsigned num = 1; 49 while(1) { 50 // 51 // Step 1: Randomize the order of the optimizer passes. 52 // 53 std::random_shuffle(PassesToRun.begin(), PassesToRun.end()); 54 55 // 56 // Step 2: Run optimizer passes on the program and check for success. 57 // 58 outs() << "Running selected passes on program to test for crash: "; 59 for(int i = 0, e = PassesToRun.size(); i != e; i++) { 60 outs() << "-" << PassesToRun[i]->getPassArgument( )<< " "; 61 } 62 63 std::string Filename; 64 if(runPasses(PassesToRun, Filename, false)) { 65 outs() << "\n"; 66 outs() << "Optimizer passes caused failure!\n\n"; 67 debugOptimizerCrash(); 68 return true; 69 } else { 70 outs() << "Combination " << num << " optimized successfully!\n"; 71 } 72 73 // 74 // Step 3: Compile the optimized code. 75 // 76 outs() << "Running the code generator to test for a crash: "; 77 try { 78 compileProgram(Program); 79 outs() << '\n'; 80 } catch (ToolExecutionError &TEE) { 81 outs() << "\n*** compileProgram threw an exception: "; 82 outs() << TEE.what(); 83 return debugCodeGeneratorCrash(); 84 } 85 86 // 87 // Step 4: Run the program and compare its output to the reference 88 // output (created above). 89 // 90 outs() << "*** Checking if passes caused miscompliation:\n"; 91 try { 92 if (diffProgram(Filename, "", false)) { 93 outs() << "\n*** diffProgram returned true!\n"; 94 debugMiscompilation(); 95 return true; 96 } else { 97 outs() << "\n*** diff'd output matches!\n"; 98 } 99 } catch (ToolExecutionError &TEE) { 100 errs() << TEE.what(); 101 debugCodeGeneratorCrash(); 102 return true; 103 } 104 105 sys::Path(Filename).eraseFromDisk(); 106 107 outs() << "\n\n"; 108 num++; 109 } //end while 110 111 // Unreachable. 112} 113