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