FindBugs.cpp revision 198090
1193323Sed//===-- FindBugs.cpp - Run Many Different Optimizations -------------------===// 2193323Sed// 3193323Sed// The LLVM Compiler Infrastructure 4193323Sed// 5193323Sed// This file is distributed under the University of Illinois Open Source 6193323Sed// License. See LICENSE.TXT for details. 7193323Sed// 8193323Sed//===----------------------------------------------------------------------===// 9193323Sed// 10193323Sed// This file defines an interface that allows bugpoint to choose different 11193323Sed// combinations of optimizations to run on the selected input. Bugpoint will 12193323Sed// run these optimizations and record the success/failure of each. This way 13193323Sed// we can hopefully spot bugs in the optimizations. 14193323Sed// 15193323Sed//===----------------------------------------------------------------------===// 16193323Sed 17193323Sed#include "BugDriver.h" 18193323Sed#include "ToolRunner.h" 19193323Sed#include "llvm/Pass.h" 20198090Srdivacky#include "llvm/Support/raw_ostream.h" 21193323Sed#include <algorithm> 22193323Sed#include <ctime> 23193323Sedusing namespace llvm; 24193323Sed 25193323Sed/// runManyPasses - Take the specified pass list and create different 26193323Sed/// combinations of passes to compile the program with. Compile the program with 27193323Sed/// each set and mark test to see if it compiled correctly. If the passes 28193323Sed/// compiled correctly output nothing and rearrange the passes into a new order. 29193323Sed/// If the passes did not compile correctly, output the command required to 30193323Sed/// recreate the failure. This returns true if a compiler error is found. 31193323Sed/// 32212793Sdimbool BugDriver::runManyPasses(const std::vector<const PassInfo*> &AllPasses) { 33207618Srdivacky setPassesToRun(AllPasses); 34193323Sed outs() << "Starting bug finding procedure...\n\n"; 35198090Srdivacky 36193323Sed // Creating a reference output if necessary 37193323Sed if (initializeExecutionEnvironment()) return false; 38193323Sed 39193323Sed outs() << "\n"; 40198090Srdivacky if (ReferenceOutputFile.empty()) { 41193323Sed outs() << "Generating reference output from raw program: \n"; 42198090Srdivacky if (!createReferenceFile(Program)) 43193323Sed return false; 44193323Sed } 45193323Sed 46193323Sed srand(time(NULL)); 47193323Sed 48193323Sed unsigned num = 1; 49193323Sed while(1) { 50193323Sed // 51193323Sed // Step 1: Randomize the order of the optimizer passes. 52193323Sed // 53193323Sed std::random_shuffle(PassesToRun.begin(), PassesToRun.end()); 54193323Sed 55193323Sed // 56193323Sed // Step 2: Run optimizer passes on the program and check for success. 57193323Sed // 58193323Sed outs() << "Running selected passes on program to test for crash: "; 59198090Srdivacky for(int i = 0, e = PassesToRun.size(); i != e; i++) { 60193323Sed outs() << "-" << PassesToRun[i]->getPassArgument( )<< " "; 61212793Sdim } 62193323Sed 63193323Sed std::string Filename; 64193323Sed if(runPasses(PassesToRun, Filename, false)) { 65212793Sdim outs() << "\n"; 66198090Srdivacky outs() << "Optimizer passes caused failure!\n\n"; 67198090Srdivacky debugOptimizerCrash(); 68193323Sed return true; 69193323Sed } else { 70193323Sed outs() << "Combination " << num << " optimized successfully!\n"; 71198090Srdivacky } 72193323Sed 73193323Sed // 74193323Sed // Step 3: Compile the optimized code. 75193323Sed // 76193323Sed outs() << "Running the code generator to test for a crash: "; 77198090Srdivacky try { 78207618Srdivacky compileProgram(Program); 79207618Srdivacky outs() << '\n'; 80207618Srdivacky } catch (ToolExecutionError &TEE) { 81198090Srdivacky outs() << "\n*** compileProgram threw an exception: "; 82207618Srdivacky outs() << TEE.what(); 83207618Srdivacky return debugCodeGeneratorCrash(); 84193323Sed } 85207618Srdivacky 86193323Sed // 87193323Sed // Step 4: Run the program and compare its output to the reference 88193323Sed // output (created above). 89193323Sed // 90193323Sed outs() << "*** Checking if passes caused miscompliation:\n"; 91198090Srdivacky try { 92212793Sdim if (diffProgram(Filename, "", false)) { 93207618Srdivacky outs() << "\n*** diffProgram returned true!\n"; 94207618Srdivacky debugMiscompilation(); 95207618Srdivacky return true; 96207618Srdivacky } else { 97193323Sed outs() << "\n*** diff'd output matches!\n"; 98207618Srdivacky } 99207618Srdivacky } catch (ToolExecutionError &TEE) { 100207618Srdivacky errs() << TEE.what(); 101207618Srdivacky debugCodeGeneratorCrash(); 102193323Sed return true; 103193323Sed } 104207618Srdivacky 105193323Sed sys::Path(Filename).eraseFromDisk(); 106193323Sed 107193323Sed outs() << "\n\n"; 108198090Srdivacky num++; 109193323Sed } //end while 110193323Sed 111193323Sed // Unreachable. 112193323Sed} 113193323Sed