FindBugs.cpp revision 193323
1155131Srwatson//===-- FindBugs.cpp - Run Many Different Optimizations -------------------===// 2155131Srwatson// 3155131Srwatson// The LLVM Compiler Infrastructure 4155131Srwatson// 5155131Srwatson// This file is distributed under the University of Illinois Open Source 6155131Srwatson// License. See LICENSE.TXT for details. 7155131Srwatson// 8155131Srwatson//===----------------------------------------------------------------------===// 9155131Srwatson// 10155131Srwatson// This file defines an interface that allows bugpoint to choose different 11155131Srwatson// combinations of optimizations to run on the selected input. Bugpoint will 12155131Srwatson// run these optimizations and record the success/failure of each. This way 13168777Srwatson// we can hopefully spot bugs in the optimizations. 14155131Srwatson// 15155131Srwatson//===----------------------------------------------------------------------===// 16155131Srwatson 17155131Srwatson#include "BugDriver.h" 18155131Srwatson#include "ToolRunner.h" 19155131Srwatson#include "llvm/Pass.h" 20155131Srwatson#include <algorithm> 21155131Srwatson#include <ctime> 22155131Srwatson#include <iostream> 23155131Srwatsonusing namespace llvm; 24155131Srwatson 25155131Srwatson/// runManyPasses - Take the specified pass list and create different 26155131Srwatson/// combinations of passes to compile the program with. Compile the program with 27155131Srwatson/// each set and mark test to see if it compiled correctly. If the passes 28155131Srwatson/// compiled correctly output nothing and rearrange the passes into a new order. 29155131Srwatson/// If the passes did not compile correctly, output the command required to 30155131Srwatson/// recreate the failure. This returns true if a compiler error is found. 31155131Srwatson/// 32155131Srwatsonbool BugDriver::runManyPasses(const std::vector<const PassInfo*> &AllPasses) { 33168777Srwatson setPassesToRun(AllPasses); 34155131Srwatson std::cout << "Starting bug finding procedure...\n\n"; 35155131Srwatson 36155131Srwatson // Creating a reference output if necessary 37168777Srwatson if (initializeExecutionEnvironment()) return false; 38155131Srwatson 39155131Srwatson std::cout << "\n"; 40155131Srwatson if (ReferenceOutputFile.empty()) { 41155131Srwatson std::cout << "Generating reference output from raw program: \n"; 42155131Srwatson if (!createReferenceFile(Program)) 43155131Srwatson return false; 44155131Srwatson } 45155131Srwatson 46155131Srwatson srand(time(NULL)); 47155131Srwatson 48155131Srwatson unsigned num = 1; 49155131Srwatson while(1) { 50168777Srwatson // 51155131Srwatson // Step 1: Randomize the order of the optimizer passes. 52168777Srwatson // 53155131Srwatson std::random_shuffle(PassesToRun.begin(), PassesToRun.end()); 54168777Srwatson 55155131Srwatson // 56168777Srwatson // Step 2: Run optimizer passes on the program and check for success. 57155131Srwatson // 58168777Srwatson std::cout << "Running selected passes on program to test for crash: "; 59155131Srwatson for(int i = 0, e = PassesToRun.size(); i != e; i++) { 60155131Srwatson std::cout << "-" << PassesToRun[i]->getPassArgument( )<< " "; 61155131Srwatson } 62155131Srwatson 63155131Srwatson std::string Filename; 64155131Srwatson if(runPasses(PassesToRun, Filename, false)) { 65155131Srwatson std::cout << "\n"; 66168777Srwatson std::cout << "Optimizer passes caused failure!\n\n"; 67155131Srwatson debugOptimizerCrash(); 68155131Srwatson return true; 69155131Srwatson } else { 70155131Srwatson std::cout << "Combination " << num << " optimized successfully!\n"; 71155131Srwatson } 72155131Srwatson 73155131Srwatson // 74155131Srwatson // Step 3: Compile the optimized code. 75155131Srwatson // 76168777Srwatson std::cout << "Running the code generator to test for a crash: "; 77155131Srwatson try { 78168777Srwatson compileProgram(Program); 79155131Srwatson std::cout << '\n'; 80155131Srwatson } catch (ToolExecutionError &TEE) { 81168777Srwatson std::cout << "\n*** compileProgram threw an exception: "; 82155131Srwatson std::cout << TEE.what(); 83168777Srwatson return debugCodeGeneratorCrash(); 84155131Srwatson } 85168777Srwatson 86155131Srwatson // 87168777Srwatson // Step 4: Run the program and compare its output to the reference 88155131Srwatson // output (created above). 89168777Srwatson // 90155131Srwatson std::cout << "*** Checking if passes caused miscompliation:\n"; 91168777Srwatson try { 92168777Srwatson if (diffProgram(Filename, "", false)) { 93168777Srwatson std::cout << "\n*** diffProgram returned true!\n"; 94168777Srwatson debugMiscompilation(); 95155131Srwatson return true; 96155131Srwatson } else { 97168777Srwatson std::cout << "\n*** diff'd output matches!\n"; 98155131Srwatson } 99155131Srwatson } catch (ToolExecutionError &TEE) { 100155131Srwatson std::cerr << TEE.what(); 101168777Srwatson debugCodeGeneratorCrash(); 102168777Srwatson return true; 103168777Srwatson } 104168777Srwatson 105168777Srwatson sys::Path(Filename).eraseFromDisk(); 106168777Srwatson 107168777Srwatson std::cout << "\n\n"; 108155131Srwatson num++; 109168777Srwatson } //end while 110155131Srwatson 111168777Srwatson // Unreachable. 112168777Srwatson} 113155131Srwatson