FindBugs.cpp revision 032091d7f62774443c282915964189ea3d8930de
1//===-- FindBugs.cpp - Run Many Different Optimizations -------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file was developed by Patrick Jenkins and is distributed under 6// the University of Illinois Open Source 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#include "BugDriver.h" 17#include "ToolRunner.h" 18 19#include "llvm/Bytecode/WriteBytecodePass.h" 20 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{ 34 std::string Filename; 35 std::vector<const PassInfo*> TempPass(AllPasses); 36 std::cout << "Starting bug finding procedure...\n\n"; 37 38 // Creating a reference output if necessary 39 if (initializeExecutionEnvironment()) return false; 40 std::cout << "\n"; 41 if (ReferenceOutputFile.empty()) { 42 std::cout << "Generating reference output from raw program: \n"; 43 if(!createReferenceFile(Program)){ 44 return false; 45 } 46 } 47 48 srand(time(NULL)); 49 std::vector<const PassInfo*>::iterator I = TempPass.begin(); 50 std::vector<const PassInfo*>::iterator E = TempPass.end(); 51 52 int num=1; 53 while(1){ 54 // 55 // Step 1: Randomize the order of the optimizer passes. 56 // 57 std::random_shuffle(TempPass.begin(), TempPass.end()); 58 59 // 60 // Step 2: Run optimizer passes on the program and check for success. 61 // 62 std::cout << "Running selected passes on program to test for crash: "; 63 for(int i=0, e=TempPass.size(); i!=e; i++) { 64 std::cout << "-" << TempPass[i]->getPassArgument( )<< " "; 65 } 66 std::string Filename; 67 if(runPasses(TempPass, Filename, false)) { 68 std::cout << "\n"; 69 std::cout << "Optimizer passes caused failure!\n\n"; 70 debugOptimizerCrash(); 71 return true; 72 } 73 else{ 74 std::cout << "Combination "<<num<<" optimized successfully!\n"; 75 } 76 77 // 78 // Step 3: Compile the optimized code. 79 // 80 std::cout << "Running the code generator to test for a crash: "; 81 try { 82 compileProgram(Program); 83 std::cout << '\n'; 84 } catch (ToolExecutionError &TEE) { 85 std::cout << "\n*** compileProgram threw an exception: "; 86 std::cout << TEE.what(); 87 return debugCodeGeneratorCrash(); 88 } 89 90 // 91 // Step 4: Run the program and compare its output to the reference 92 // output (created above). 93 // 94 std::cout << "*** Checking if passes caused miscompliation:\n"; 95 try { 96 if (diffProgram(Filename, "", false)) { 97 std::cout << "\n*** diffProgram returned true!\n"; 98 debugMiscompilation(); 99 return true; 100 } 101 else{ 102 std::cout << "\n*** diff'd output matches!\n"; 103 } 104 } catch (ToolExecutionError &TEE) { 105 std::cerr << TEE.what(); 106 debugCodeGeneratorCrash(); 107 return true; 108 } 109 110 sys::Path(Filename).eraseFromDisk(); 111 112 std::cout << "\n\n"; 113 num++; 114 } //end while 115 116 // This will never be reached 117 std::cout << "Did not find any bugs :-( \n"; 118 return false; 119} 120