FindBugs.cpp revision 7f27570ae0cb716927f946f4e73a55f60d99b3e2
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 17#include "BugDriver.h" 18#include "ToolRunner.h" 19#include "llvm/Pass.h" 20#include <algorithm> 21#include <ctime> 22#include <iostream> 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 std::string Filename; 34 std::vector<const PassInfo*> TempPass(AllPasses); 35 std::cout << "Starting bug finding procedure...\n\n"; 36 37 // Creating a reference output if necessary 38 if (initializeExecutionEnvironment()) return false; 39 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 srand(time(NULL)); 48 std::vector<const PassInfo*>::iterator I = TempPass.begin(); 49 std::vector<const PassInfo*>::iterator E = TempPass.end(); 50 51 unsigned num = 1; 52 while(1) { 53 // 54 // Step 1: Randomize the order of the optimizer passes. 55 // 56 std::random_shuffle(TempPass.begin(), TempPass.end()); 57 58 // 59 // Step 2: Run optimizer passes on the program and check for success. 60 // 61 std::cout << "Running selected passes on program to test for crash: "; 62 for(int i = 0, e = TempPass.size(); i != e; i++) { 63 std::cout << "-" << TempPass[i]->getPassArgument( )<< " "; 64 } 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 } else { 73 std::cout << "Combination " << num << " optimized successfully!\n"; 74 } 75 76 // 77 // Step 3: Compile the optimized code. 78 // 79 std::cout << "Running the code generator to test for a crash: "; 80 try { 81 compileProgram(Program); 82 std::cout << '\n'; 83 } catch (ToolExecutionError &TEE) { 84 std::cout << "\n*** compileProgram threw an exception: "; 85 std::cout << TEE.what(); 86 return debugCodeGeneratorCrash(); 87 } 88 89 // 90 // Step 4: Run the program and compare its output to the reference 91 // output (created above). 92 // 93 std::cout << "*** Checking if passes caused miscompliation:\n"; 94 try { 95 if (diffProgram(Filename, "", false)) { 96 std::cout << "\n*** diffProgram returned true!\n"; 97 debugMiscompilation(); 98 return true; 99 } else { 100 std::cout << "\n*** diff'd output matches!\n"; 101 } 102 } catch (ToolExecutionError &TEE) { 103 std::cerr << TEE.what(); 104 debugCodeGeneratorCrash(); 105 return true; 106 } 107 108 sys::Path(Filename).eraseFromDisk(); 109 110 std::cout << "\n\n"; 111 num++; 112 } //end while 113 114 // Unreachable. 115} 116