1 //===-- FindBugs.cpp - Run Many Different Optimizations -------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // 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 "llvm/Support/FileSystem.h" 21 #include "llvm/Support/raw_ostream.h" 22 #include <algorithm> 23 #include <ctime> 24 using namespace llvm; 25 26 Error 27 BugDriver::runManyPasses(const std::vector<std::string> &AllPasses) { 28 setPassesToRun(AllPasses); 29 outs() << "Starting bug finding procedure...\n\n"; 30 31 // Creating a reference output if necessary 32 if (Error E = initializeExecutionEnvironment()) 33 return E; 34 35 outs() << "\n"; 36 if (ReferenceOutputFile.empty()) { 37 outs() << "Generating reference output from raw program: \n"; 38 if (Error E = createReferenceFile(Program)) 39 return E; 40 } 41 42 srand(time(nullptr)); 43 44 unsigned num = 1; 45 while (1) { 46 // 47 // Step 1: Randomize the order of the optimizer passes. 48 // 49 std::random_shuffle(PassesToRun.begin(), PassesToRun.end()); 50 51 // 52 // Step 2: Run optimizer passes on the program and check for success. 53 // 54 outs() << "Running selected passes on program to test for crash: "; 55 for (int i = 0, e = PassesToRun.size(); i != e; i++) { 56 outs() << "-" << PassesToRun[i] << " "; 57 } 58 59 std::string Filename; 60 if (runPasses(Program, PassesToRun, Filename, false)) { 61 outs() << "\n"; 62 outs() << "Optimizer passes caused failure!\n\n"; 63 return debugOptimizerCrash(); 64 } else { 65 outs() << "Combination " << num << " optimized successfully!\n"; 66 } 67 68 // 69 // Step 3: Compile the optimized code. 70 // 71 outs() << "Running the code generator to test for a crash: "; 72 if (Error E = compileProgram(Program)) { 73 outs() << "\n*** compileProgram threw an exception: "; 74 outs() << toString(std::move(E)); 75 return debugCodeGeneratorCrash(); 76 } 77 outs() << '\n'; 78 79 // 80 // Step 4: Run the program and compare its output to the reference 81 // output (created above). 82 // 83 outs() << "*** Checking if passes caused miscompliation:\n"; 84 Expected<bool> Diff = diffProgram(Program, Filename, "", false); 85 if (Error E = Diff.takeError()) { 86 errs() << toString(std::move(E)); 87 return debugCodeGeneratorCrash(); 88 } 89 if (*Diff) { 90 outs() << "\n*** diffProgram returned true!\n"; 91 Error E = debugMiscompilation(); 92 if (!E) 93 return Error::success(); 94 } 95 outs() << "\n*** diff'd output matches!\n"; 96 97 sys::fs::remove(Filename); 98 99 outs() << "\n\n"; 100 num++; 101 } // end while 102 103 // Unreachable. 104 } 105