FindBugs.cpp revision 193323
1183371Simp//===-- FindBugs.cpp - Run Many Different Optimizations -------------------===// 2183371Simp// 3183371Simp// The LLVM Compiler Infrastructure 4183371Simp// 5183371Simp// This file is distributed under the University of Illinois Open Source 6183371Simp// License. See LICENSE.TXT for details. 7183371Simp// 8183371Simp//===----------------------------------------------------------------------===// 9183371Simp// 10183371Simp// This file defines an interface that allows bugpoint to choose different 11183371Simp// combinations of optimizations to run on the selected input. Bugpoint will 12183371Simp// run these optimizations and record the success/failure of each. This way 13183371Simp// we can hopefully spot bugs in the optimizations. 14183371Simp// 15183371Simp//===----------------------------------------------------------------------===// 16183371Simp 17183371Simp#include "BugDriver.h" 18183371Simp#include "ToolRunner.h" 19183371Simp#include "llvm/Pass.h" 20183371Simp#include <algorithm> 21183371Simp#include <ctime> 22183371Simp#include <iostream> 23183371Simpusing namespace llvm; 24183371Simp 25183371Simp/// runManyPasses - Take the specified pass list and create different 26183371Simp/// combinations of passes to compile the program with. Compile the program with 27183371Simp/// each set and mark test to see if it compiled correctly. If the passes 28183371Simp/// compiled correctly output nothing and rearrange the passes into a new order. 29183371Simp/// If the passes did not compile correctly, output the command required to 30183371Simp/// recreate the failure. This returns true if a compiler error is found. 31183371Simp/// 32183371Simpbool BugDriver::runManyPasses(const std::vector<const PassInfo*> &AllPasses) { 33183371Simp setPassesToRun(AllPasses); 34183371Simp std::cout << "Starting bug finding procedure...\n\n"; 35183371Simp 36183371Simp // Creating a reference output if necessary 37183371Simp if (initializeExecutionEnvironment()) return false; 38183371Simp 39183371Simp std::cout << "\n"; 40183371Simp if (ReferenceOutputFile.empty()) { 41183371Simp std::cout << "Generating reference output from raw program: \n"; 42183371Simp if (!createReferenceFile(Program)) 43183371Simp return false; 44183371Simp } 45183371Simp 46183371Simp srand(time(NULL)); 47183371Simp 48183371Simp unsigned num = 1; 49183371Simp while(1) { 50183371Simp // 51183371Simp // Step 1: Randomize the order of the optimizer passes. 52183371Simp // 53183371Simp std::random_shuffle(PassesToRun.begin(), PassesToRun.end()); 54183371Simp 55183371Simp // 56183371Simp // Step 2: Run optimizer passes on the program and check for success. 57183371Simp // 58183371Simp std::cout << "Running selected passes on program to test for crash: "; 59183371Simp for(int i = 0, e = PassesToRun.size(); i != e; i++) { 60183371Simp std::cout << "-" << PassesToRun[i]->getPassArgument( )<< " "; 61183371Simp } 62183371Simp 63183371Simp std::string Filename; 64183371Simp if(runPasses(PassesToRun, Filename, false)) { 65183371Simp std::cout << "\n"; 66183371Simp std::cout << "Optimizer passes caused failure!\n\n"; 67183371Simp debugOptimizerCrash(); 68183371Simp return true; 69183371Simp } else { 70183371Simp std::cout << "Combination " << num << " optimized successfully!\n"; 71183371Simp } 72183371Simp 73183371Simp // 74 // Step 3: Compile the optimized code. 75 // 76 std::cout << "Running the code generator to test for a crash: "; 77 try { 78 compileProgram(Program); 79 std::cout << '\n'; 80 } catch (ToolExecutionError &TEE) { 81 std::cout << "\n*** compileProgram threw an exception: "; 82 std::cout << 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 std::cout << "*** Checking if passes caused miscompliation:\n"; 91 try { 92 if (diffProgram(Filename, "", false)) { 93 std::cout << "\n*** diffProgram returned true!\n"; 94 debugMiscompilation(); 95 return true; 96 } else { 97 std::cout << "\n*** diff'd output matches!\n"; 98 } 99 } catch (ToolExecutionError &TEE) { 100 std::cerr << TEE.what(); 101 debugCodeGeneratorCrash(); 102 return true; 103 } 104 105 sys::Path(Filename).eraseFromDisk(); 106 107 std::cout << "\n\n"; 108 num++; 109 } //end while 110 111 // Unreachable. 112} 113