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