BugDriver.cpp revision 314564
11539Srgrimes//===- BugDriver.cpp - Top-Level BugPoint class implementation ------------===// 21539Srgrimes// 31539Srgrimes// The LLVM Compiler Infrastructure 41539Srgrimes// 51539Srgrimes// This file is distributed under the University of Illinois Open Source 61539Srgrimes// License. See LICENSE.TXT for details. 71539Srgrimes// 81539Srgrimes//===----------------------------------------------------------------------===// 91539Srgrimes// 101539Srgrimes// This class contains all of the shared state and information that is used by 111539Srgrimes// the BugPoint tool to track down errors in optimizations. This class is the 121539Srgrimes// main driver class that invokes all sub-functionality. 131539Srgrimes// 141539Srgrimes//===----------------------------------------------------------------------===// 151539Srgrimes 161539Srgrimes#include "BugDriver.h" 171539Srgrimes#include "ToolRunner.h" 181539Srgrimes#include "llvm/IR/Module.h" 191539Srgrimes#include "llvm/IR/Verifier.h" 201539Srgrimes#include "llvm/IRReader/IRReader.h" 211539Srgrimes#include "llvm/Linker/Linker.h" 221539Srgrimes#include "llvm/Pass.h" 231539Srgrimes#include "llvm/Support/CommandLine.h" 241539Srgrimes#include "llvm/Support/FileUtilities.h" 251539Srgrimes#include "llvm/Support/Host.h" 261539Srgrimes#include "llvm/Support/SourceMgr.h" 271539Srgrimes#include "llvm/Support/raw_ostream.h" 281539Srgrimes#include <memory> 291539Srgrimesusing namespace llvm; 301539Srgrimes 311539Srgrimesnamespace llvm { 321539SrgrimesTriple TargetTriple; 3323657Speter} 3455031Sbde 351539Srgrimes// Anonymous namespace to define command line options for debugging. 361539Srgrimes// 371539Srgrimesnamespace { 387865Sbde// Output - The user can specify a file containing the expected output of the 391539Srgrimes// program. If this filename is set, it is used as the reference diff source, 4033861Sbde// otherwise the raw input run through an interpreter is used as the reference 41123257Smarcel// source. 42102227Smike// 4333861Sbdecl::opt<std::string> OutputFile("output", 44103728Swollman cl::desc("Specify a reference program output " 45102227Smike "(for miscompilation detection)")); 46102227Smike} 47102227Smike 4815483Sbde/// setNewProgram - If we reduce or update the program somehow, call this method 4915483Sbde/// to update bugdriver with it. This deletes the old module and sets the 5015483Sbde/// specified one as the current program. 51102227Smikevoid BugDriver::setNewProgram(Module *M) { 52102227Smike delete Program; 53102227Smike Program = M; 541539Srgrimes} 551539Srgrimes 5699640Sobrien/// getPassesString - Turn a list of passes into a string which indicates the 57102227Smike/// command line options that must be passed to add the passes. 58102227Smike/// 59102227Smikestd::string llvm::getPassesString(const std::vector<std::string> &Passes) { 601539Srgrimes std::string Result; 6199640Sobrien for (unsigned i = 0, e = Passes.size(); i != e; ++i) { 621539Srgrimes if (i) 631539Srgrimes Result += " "; 64103766Sbde Result += "-"; 65103766Sbde Result += Passes[i]; 661539Srgrimes } 671539Srgrimes return Result; 681539Srgrimes} 69103766Sbde 70103766SbdeBugDriver::BugDriver(const char *toolname, bool find_bugs, unsigned timeout, 711539Srgrimes unsigned memlimit, bool use_valgrind, LLVMContext &ctxt) 721539Srgrimes : Context(ctxt), ToolName(toolname), ReferenceOutputFile(OutputFile), 731539Srgrimes Program(nullptr), Interpreter(nullptr), SafeInterpreter(nullptr), 741539Srgrimes cc(nullptr), run_find_bugs(find_bugs), Timeout(timeout), 751539Srgrimes MemoryLimit(memlimit), UseValgrind(use_valgrind) {} 761539Srgrimes 771539SrgrimesBugDriver::~BugDriver() { 781539Srgrimes delete Program; 791539Srgrimes if (Interpreter != SafeInterpreter) 801539Srgrimes delete Interpreter; 811539Srgrimes delete SafeInterpreter; 8293032Simp delete cc; 8393032Simp} 8493032Simp 8593032Simpstd::unique_ptr<Module> llvm::parseInputFile(StringRef Filename, 8693032Simp LLVMContext &Ctxt) { 8793032Simp SMDiagnostic Err; 8893032Simp std::unique_ptr<Module> Result = parseIRFile(Filename, Err, Ctxt); 8993032Simp if (!Result) { 90187961Sdas Err.print("bugpoint", errs()); 9193032Simp return Result; 9293032Simp } 9393032Simp 9493032Simp if (verifyModule(*Result, &errs())) { 9593032Simp errs() << "bugpoint: " << Filename << ": error: input module is broken!\n"; 9693032Simp return std::unique_ptr<Module>(); 97187961Sdas } 98103728Swollman 99103766Sbde // If we don't have an override triple, use the first one to configure 100103728Swollman // bugpoint, or use the host triple if none provided. 10193032Simp if (TargetTriple.getTriple().empty()) { 10293032Simp Triple TheTriple(Result->getTargetTriple()); 10393032Simp 10493032Simp if (TheTriple.getTriple().empty()) 10593032Simp TheTriple.setTriple(sys::getDefaultTargetTriple()); 106103766Sbde 107112163Sdas TargetTriple.setTriple(TheTriple.getTriple()); 108103766Sbde } 109112163Sdas 110112163Sdas Result->setTargetTriple(TargetTriple.getTriple()); // override the triple 1111539Srgrimes return Result; 112103012Stjr} 11393032Simp 11493032Simp// This method takes the specified list of LLVM input files, attempts to load 115103012Stjr// them, either as assembly or bitcode, then link them together. It returns 1161539Srgrimes// true on failure (if, for example, an input bitcode file could not be 117103728Swollman// parsed), and false on success. 118103728Swollman// 119103728Swollmanbool BugDriver::addSources(const std::vector<std::string> &Filenames) { 120103728Swollman assert(!Program && "Cannot call addSources multiple times!"); 121103728Swollman assert(!Filenames.empty() && "Must specify at least on input filename!"); 122103728Swollman 123103728Swollman // Load the first input file. 124103728Swollman Program = parseInputFile(Filenames[0], Context).release(); 125103728Swollman if (!Program) 126103728Swollman return true; 127103728Swollman 128103728Swollman outs() << "Read input file : '" << Filenames[0] << "'\n"; 129103728Swollman 130103728Swollman for (unsigned i = 1, e = Filenames.size(); i != e; ++i) { 131103728Swollman std::unique_ptr<Module> M = parseInputFile(Filenames[i], Context); 132103728Swollman if (!M.get()) 133103728Swollman return true; 13469201Sphk 135103728Swollman outs() << "Linking in input file: '" << Filenames[i] << "'\n"; 136103728Swollman if (Linker::linkModules(*Program, std::move(M))) 137103728Swollman return true; 138103728Swollman } 139103728Swollman 140103728Swollman outs() << "*** All input ok\n"; 141103728Swollman 142103728Swollman // All input files read successfully! 143103728Swollman return false; 144103766Sbde} 145103766Sbde 146103728Swollman/// run - The top level method that is invoked after all of the instance 147103728Swollman/// variables are set up from command line arguments. 148103766Sbde/// 149103728SwollmanError BugDriver::run() { 150103728Swollman if (run_find_bugs) { 151103766Sbde // Rearrange the passes and apply them to the program. Repeat this process 152103728Swollman // until the user kills the program or we find a bug. 153103728Swollman return runManyPasses(PassesToRun); 154103728Swollman } 155103728Swollman 156103728Swollman // If we're not running as a child, the first thing that we must do is 157103728Swollman // determine what the problem is. Does the optimization series crash the 158103728Swollman // compiler, or does it produce illegal code? We make the top-level 159103728Swollman // decision by trying to run all of the passes on the input program, 160154250Sjasone // which should generate a bitcode file. If it does generate a bitcode 161103728Swollman // file, then we know the compiler didn't crash, so try to diagnose a 16293032Simp // miscompilation. 163171195Sscf if (!PassesToRun.empty()) { 164103728Swollman outs() << "Running selected passes on program to test for crash: "; 1651539Srgrimes if (runPasses(Program, PassesToRun)) 166189349Sdas return debugOptimizerCrash(); 167189349Sdas } 168189349Sdas 169189349Sdas // Set up the execution environment, selecting a method to run LLVM bitcode. 170189349Sdas if (Error E = initializeExecutionEnvironment()) 171189349Sdas return E; 172189349Sdas 173189349Sdas // Test to see if we have a code generator crash. 174189349Sdas outs() << "Running the code generator to test for a crash: "; 175189349Sdas if (Error E = compileProgram(Program)) { 176189349Sdas outs() << toString(std::move(E)); 177189349Sdas return debugCodeGeneratorCrash(); 178103728Swollman } 179103728Swollman outs() << '\n'; 180103728Swollman 181103728Swollman // Run the raw input to see where we are coming from. If a reference output 182103728Swollman // was specified, make sure that the raw output matches it. If not, it's a 183103728Swollman // problem in the front-end or the code generator. 184103728Swollman // 185103728Swollman bool CreatedOutput = false; 186153707Strhodes if (ReferenceOutputFile.empty()) { 18793032Simp outs() << "Generating reference output from raw program: "; 188103766Sbde if (Error E = createReferenceFile(Program)) { 18993032Simp errs() << toString(std::move(E)); 190103766Sbde return debugCodeGeneratorCrash(); 191103766Sbde } 192108574Sjmallett CreatedOutput = true; 193103728Swollman } 19493032Simp 195153707Strhodes // Make sure the reference output file gets deleted on exit from this 19693032Simp // function, if appropriate. 19793032Simp std::string ROF(ReferenceOutputFile); 198189782Sdas FileRemover RemoverInstance(ROF, CreatedOutput && !SaveTemps); 199103728Swollman 200103766Sbde // Diff the output of the raw program against the reference output. If it 201103728Swollman // matches, then we assume there is a miscompilation bug and try to 20293032Simp // diagnose it. 20393032Simp outs() << "*** Checking the code generator...\n"; 204108574Sjmallett Expected<bool> Diff = diffProgram(Program, "", "", false); 205108574Sjmallett if (Error E = Diff.takeError()) { 206171195Sscf errs() << toString(std::move(E)); 207103728Swollman return debugCodeGeneratorCrash(); 208103728Swollman } 2097865Sbde if (!*Diff) { 21093032Simp outs() << "\n*** Output matches: Debugging miscompilation!\n"; 211103728Swollman if (Error E = debugMiscompilation()) { 212103728Swollman errs() << toString(std::move(E)); 213103728Swollman return debugCodeGeneratorCrash(); 214103728Swollman } 215103728Swollman return Error::success(); 21693032Simp } 217103728Swollman 218108574Sjmallett outs() << "\n*** Input program does not match reference diff!\n"; 219103728Swollman outs() << "Debugging code generator problem!\n"; 2204749Sats if (Error E = debugCodeGenerator()) { 221103728Swollman errs() << toString(std::move(E)); 222103728Swollman return debugCodeGeneratorCrash(); 223103766Sbde } 224103766Sbde return Error::success(); 225103728Swollman} 226116397Sdes 227116397Sdesvoid llvm::PrintFunctionList(const std::vector<Function *> &Funcs) { 228116397Sdes unsigned NumPrint = Funcs.size(); 229116397Sdes if (NumPrint > 10) 230116397Sdes NumPrint = 10; 231116397Sdes for (unsigned i = 0; i != NumPrint; ++i) 232116397Sdes outs() << " " << Funcs[i]->getName(); 233116397Sdes if (NumPrint < Funcs.size()) 234116397Sdes outs() << "... <" << Funcs.size() << " total>"; 235116831Sobrien outs().flush(); 236116831Sobrien} 237116397Sdes 238116831Sobrienvoid llvm::PrintGlobalVariableList(const std::vector<GlobalVariable *> &GVs) { 239116831Sobrien unsigned NumPrint = GVs.size(); 240116397Sdes if (NumPrint > 10) 241116397Sdes NumPrint = 10; 242189820Sdas for (unsigned i = 0; i != NumPrint; ++i) 24341927Sdt outs() << " " << GVs[i]->getName(); 24493032Simp if (NumPrint < GVs.size()) 245180658Sache outs() << "... <" << GVs.size() << " total>"; 246180658Sache outs().flush(); 24793032Simp} 248180689Sache