FindBugs.cpp revision dce4a407a24b04eebc6a376f8e62b41aaa7b071f
1032091d7f62774443c282915964189ea3d8930dePatrick Jenkins//===-- FindBugs.cpp - Run Many Different Optimizations -------------------===// 2032091d7f62774443c282915964189ea3d8930dePatrick Jenkins// 3032091d7f62774443c282915964189ea3d8930dePatrick Jenkins// The LLVM Compiler Infrastructure 4032091d7f62774443c282915964189ea3d8930dePatrick Jenkins// 521c62da287237d39d0d95004881ea4baae3be6daChris Lattner// This file is distributed under the University of Illinois Open Source 621c62da287237d39d0d95004881ea4baae3be6daChris Lattner// License. See LICENSE.TXT for details. 7032091d7f62774443c282915964189ea3d8930dePatrick Jenkins// 8032091d7f62774443c282915964189ea3d8930dePatrick Jenkins//===----------------------------------------------------------------------===// 9032091d7f62774443c282915964189ea3d8930dePatrick Jenkins// 10032091d7f62774443c282915964189ea3d8930dePatrick Jenkins// This file defines an interface that allows bugpoint to choose different 11032091d7f62774443c282915964189ea3d8930dePatrick Jenkins// combinations of optimizations to run on the selected input. Bugpoint will 12032091d7f62774443c282915964189ea3d8930dePatrick Jenkins// run these optimizations and record the success/failure of each. This way 13032091d7f62774443c282915964189ea3d8930dePatrick Jenkins// we can hopefully spot bugs in the optimizations. 14032091d7f62774443c282915964189ea3d8930dePatrick Jenkins// 15032091d7f62774443c282915964189ea3d8930dePatrick Jenkins//===----------------------------------------------------------------------===// 167f27570ae0cb716927f946f4e73a55f60d99b3e2Chris Lattner 17032091d7f62774443c282915964189ea3d8930dePatrick Jenkins#include "BugDriver.h" 18032091d7f62774443c282915964189ea3d8930dePatrick Jenkins#include "ToolRunner.h" 197f27570ae0cb716927f946f4e73a55f60d99b3e2Chris Lattner#include "llvm/Pass.h" 20cacfeed162722d13430cef6aa8acf15ec6da90dbRafael Espindola#include "llvm/Support/FileSystem.h" 2174382b7c699120fbec5cb5603c9cf4212eb37f06Chris Lattner#include "llvm/Support/raw_ostream.h" 22032091d7f62774443c282915964189ea3d8930dePatrick Jenkins#include <algorithm> 23032091d7f62774443c282915964189ea3d8930dePatrick Jenkins#include <ctime> 24032091d7f62774443c282915964189ea3d8930dePatrick Jenkinsusing namespace llvm; 25032091d7f62774443c282915964189ea3d8930dePatrick Jenkins 26032091d7f62774443c282915964189ea3d8930dePatrick Jenkins/// runManyPasses - Take the specified pass list and create different 27032091d7f62774443c282915964189ea3d8930dePatrick Jenkins/// combinations of passes to compile the program with. Compile the program with 28032091d7f62774443c282915964189ea3d8930dePatrick Jenkins/// each set and mark test to see if it compiled correctly. If the passes 29032091d7f62774443c282915964189ea3d8930dePatrick Jenkins/// compiled correctly output nothing and rearrange the passes into a new order. 30032091d7f62774443c282915964189ea3d8930dePatrick Jenkins/// If the passes did not compile correctly, output the command required to 31032091d7f62774443c282915964189ea3d8930dePatrick Jenkins/// recreate the failure. This returns true if a compiler error is found. 32032091d7f62774443c282915964189ea3d8930dePatrick Jenkins/// 338261dfed05e32302469ef707cc881fed2c31f85fRafael Espindolabool BugDriver::runManyPasses(const std::vector<std::string> &AllPasses, 3422ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky std::string &ErrMsg) { 351d1ef14248a24cb7239e0bc9298d84004a8044e6Nick Lewycky setPassesToRun(AllPasses); 36ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman outs() << "Starting bug finding procedure...\n\n"; 37032091d7f62774443c282915964189ea3d8930dePatrick Jenkins 38032091d7f62774443c282915964189ea3d8930dePatrick Jenkins // Creating a reference output if necessary 39032091d7f62774443c282915964189ea3d8930dePatrick Jenkins if (initializeExecutionEnvironment()) return false; 407f27570ae0cb716927f946f4e73a55f60d99b3e2Chris Lattner 41ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman outs() << "\n"; 42032091d7f62774443c282915964189ea3d8930dePatrick Jenkins if (ReferenceOutputFile.empty()) { 43ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman outs() << "Generating reference output from raw program: \n"; 447f27570ae0cb716927f946f4e73a55f60d99b3e2Chris Lattner if (!createReferenceFile(Program)) 457f27570ae0cb716927f946f4e73a55f60d99b3e2Chris Lattner return false; 46032091d7f62774443c282915964189ea3d8930dePatrick Jenkins } 47032091d7f62774443c282915964189ea3d8930dePatrick Jenkins 48dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines srand(time(nullptr)); 491d1ef14248a24cb7239e0bc9298d84004a8044e6Nick Lewycky 507f27570ae0cb716927f946f4e73a55f60d99b3e2Chris Lattner unsigned num = 1; 517f27570ae0cb716927f946f4e73a55f60d99b3e2Chris Lattner while(1) { 52032091d7f62774443c282915964189ea3d8930dePatrick Jenkins // 53032091d7f62774443c282915964189ea3d8930dePatrick Jenkins // Step 1: Randomize the order of the optimizer passes. 54032091d7f62774443c282915964189ea3d8930dePatrick Jenkins // 551d1ef14248a24cb7239e0bc9298d84004a8044e6Nick Lewycky std::random_shuffle(PassesToRun.begin(), PassesToRun.end()); 56032091d7f62774443c282915964189ea3d8930dePatrick Jenkins 57032091d7f62774443c282915964189ea3d8930dePatrick Jenkins // 58032091d7f62774443c282915964189ea3d8930dePatrick Jenkins // Step 2: Run optimizer passes on the program and check for success. 59032091d7f62774443c282915964189ea3d8930dePatrick Jenkins // 60ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman outs() << "Running selected passes on program to test for crash: "; 611d1ef14248a24cb7239e0bc9298d84004a8044e6Nick Lewycky for(int i = 0, e = PassesToRun.size(); i != e; i++) { 628261dfed05e32302469ef707cc881fed2c31f85fRafael Espindola outs() << "-" << PassesToRun[i] << " "; 63032091d7f62774443c282915964189ea3d8930dePatrick Jenkins } 647f27570ae0cb716927f946f4e73a55f60d99b3e2Chris Lattner 65032091d7f62774443c282915964189ea3d8930dePatrick Jenkins std::string Filename; 66ca356afe09454b3378165ded4eda294bd6341428Rafael Espindola if(runPasses(Program, PassesToRun, Filename, false)) { 67ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman outs() << "\n"; 68ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman outs() << "Optimizer passes caused failure!\n\n"; 69032091d7f62774443c282915964189ea3d8930dePatrick Jenkins debugOptimizerCrash(); 70032091d7f62774443c282915964189ea3d8930dePatrick Jenkins return true; 717f27570ae0cb716927f946f4e73a55f60d99b3e2Chris Lattner } else { 72ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman outs() << "Combination " << num << " optimized successfully!\n"; 73032091d7f62774443c282915964189ea3d8930dePatrick Jenkins } 741d1ef14248a24cb7239e0bc9298d84004a8044e6Nick Lewycky 75032091d7f62774443c282915964189ea3d8930dePatrick Jenkins // 76032091d7f62774443c282915964189ea3d8930dePatrick Jenkins // Step 3: Compile the optimized code. 77032091d7f62774443c282915964189ea3d8930dePatrick Jenkins // 78ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman outs() << "Running the code generator to test for a crash: "; 7922ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky std::string Error; 8022ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky compileProgram(Program, &Error); 8122ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky if (!Error.empty()) { 82ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman outs() << "\n*** compileProgram threw an exception: "; 8322ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky outs() << Error; 8422ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky return debugCodeGeneratorCrash(ErrMsg); 85032091d7f62774443c282915964189ea3d8930dePatrick Jenkins } 8622ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky outs() << '\n'; 871d1ef14248a24cb7239e0bc9298d84004a8044e6Nick Lewycky 88032091d7f62774443c282915964189ea3d8930dePatrick Jenkins // 89032091d7f62774443c282915964189ea3d8930dePatrick Jenkins // Step 4: Run the program and compare its output to the reference 90032091d7f62774443c282915964189ea3d8930dePatrick Jenkins // output (created above). 91032091d7f62774443c282915964189ea3d8930dePatrick Jenkins // 92ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman outs() << "*** Checking if passes caused miscompliation:\n"; 9310757dd8e1a66128b205bd04797c8aed0cb7a1bdRafael Espindola bool Diff = diffProgram(Program, Filename, "", false, &Error); 9422ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky if (Error.empty() && Diff) { 9522ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky outs() << "\n*** diffProgram returned true!\n"; 9622ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky debugMiscompilation(&Error); 9722ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky if (Error.empty()) 98032091d7f62774443c282915964189ea3d8930dePatrick Jenkins return true; 9922ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky } 10022ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky if (!Error.empty()) { 10122ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky errs() << Error; 10222ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky debugCodeGeneratorCrash(ErrMsg); 103032091d7f62774443c282915964189ea3d8930dePatrick Jenkins return true; 104032091d7f62774443c282915964189ea3d8930dePatrick Jenkins } 10522ff748712b348300e51248339b6e8cf9b59e2c6Nick Lewycky outs() << "\n*** diff'd output matches!\n"; 106032091d7f62774443c282915964189ea3d8930dePatrick Jenkins 107cacfeed162722d13430cef6aa8acf15ec6da90dbRafael Espindola sys::fs::remove(Filename); 108032091d7f62774443c282915964189ea3d8930dePatrick Jenkins 109ac95cc79ac0b899d566cc29c0f646f39c2fa35c0Dan Gohman outs() << "\n\n"; 110032091d7f62774443c282915964189ea3d8930dePatrick Jenkins num++; 111032091d7f62774443c282915964189ea3d8930dePatrick Jenkins } //end while 112032091d7f62774443c282915964189ea3d8930dePatrick Jenkins 1137f27570ae0cb716927f946f4e73a55f60d99b3e2Chris Lattner // Unreachable. 114032091d7f62774443c282915964189ea3d8930dePatrick Jenkins} 115