BugDriver.cpp revision 239462
1193323Sed//===- BugDriver.cpp - Top-Level BugPoint class implementation ------------===// 2193323Sed// 3193323Sed// The LLVM Compiler Infrastructure 4193323Sed// 5193323Sed// This file is distributed under the University of Illinois Open Source 6193323Sed// License. See LICENSE.TXT for details. 7193323Sed// 8193323Sed//===----------------------------------------------------------------------===// 9193323Sed// 10193323Sed// This class contains all of the shared state and information that is used by 11193323Sed// the BugPoint tool to track down errors in optimizations. This class is the 12193323Sed// main driver class that invokes all sub-functionality. 13193323Sed// 14193323Sed//===----------------------------------------------------------------------===// 15193323Sed 16193323Sed#include "BugDriver.h" 17193323Sed#include "ToolRunner.h" 18193323Sed#include "llvm/Linker.h" 19193323Sed#include "llvm/Module.h" 20193323Sed#include "llvm/Pass.h" 21198090Srdivacky#include "llvm/Support/IRReader.h" 22193323Sed#include "llvm/Support/CommandLine.h" 23193323Sed#include "llvm/Support/FileUtilities.h" 24195340Sed#include "llvm/Support/SourceMgr.h" 25193323Sed#include "llvm/Support/raw_ostream.h" 26218885Sdim#include "llvm/Support/Host.h" 27193323Sed#include <memory> 28193323Sedusing namespace llvm; 29193323Sed 30198090Srdivackynamespace llvm { 31198090Srdivacky Triple TargetTriple; 32198090Srdivacky} 33198090Srdivacky 34193323Sed// Anonymous namespace to define command line options for debugging. 35193323Sed// 36193323Sednamespace { 37193323Sed // Output - The user can specify a file containing the expected output of the 38193323Sed // program. If this filename is set, it is used as the reference diff source, 39193323Sed // otherwise the raw input run through an interpreter is used as the reference 40193323Sed // source. 41193323Sed // 42193323Sed cl::opt<std::string> 43193323Sed OutputFile("output", cl::desc("Specify a reference program output " 44193323Sed "(for miscompilation detection)")); 45193323Sed} 46193323Sed 47193323Sed/// setNewProgram - If we reduce or update the program somehow, call this method 48193323Sed/// to update bugdriver with it. This deletes the old module and sets the 49193323Sed/// specified one as the current program. 50193323Sedvoid BugDriver::setNewProgram(Module *M) { 51193323Sed delete Program; 52193323Sed Program = M; 53193323Sed} 54193323Sed 55193323Sed 56193323Sed/// getPassesString - Turn a list of passes into a string which indicates the 57193323Sed/// command line options that must be passed to add the passes. 58193323Sed/// 59212793Sdimstd::string llvm::getPassesString(const std::vector<std::string> &Passes) { 60193323Sed std::string Result; 61193323Sed for (unsigned i = 0, e = Passes.size(); i != e; ++i) { 62193323Sed if (i) Result += " "; 63193323Sed Result += "-"; 64212793Sdim Result += Passes[i]; 65193323Sed } 66193323Sed return Result; 67193323Sed} 68193323Sed 69212793SdimBugDriver::BugDriver(const char *toolname, bool find_bugs, 70205407Srdivacky unsigned timeout, unsigned memlimit, bool use_valgrind, 71195340Sed LLVMContext& ctxt) 72195340Sed : Context(ctxt), ToolName(toolname), ReferenceOutputFile(OutputFile), 73193323Sed Program(0), Interpreter(0), SafeInterpreter(0), gcc(0), 74221337Sdim run_find_bugs(find_bugs), Timeout(timeout), 75205407Srdivacky MemoryLimit(memlimit), UseValgrind(use_valgrind) {} 76193323Sed 77206083SrdivackyBugDriver::~BugDriver() { 78206083Srdivacky delete Program; 79206083Srdivacky} 80193323Sed 81206083Srdivacky 82193323Sed/// ParseInputFile - Given a bitcode or assembly input filename, parse and 83193323Sed/// return it, or return null if not possible. 84193323Sed/// 85195340SedModule *llvm::ParseInputFile(const std::string &Filename, 86195340Sed LLVMContext& Ctxt) { 87195340Sed SMDiagnostic Err; 88198090Srdivacky Module *Result = ParseIRFile(Filename, Err, Ctxt); 89198090Srdivacky if (!Result) 90234353Sdim Err.print("bugpoint", errs()); 91198090Srdivacky 92198090Srdivacky // If we don't have an override triple, use the first one to configure 93198090Srdivacky // bugpoint, or use the host triple if none provided. 94198090Srdivacky if (Result) { 95198090Srdivacky if (TargetTriple.getTriple().empty()) { 96198090Srdivacky Triple TheTriple(Result->getTargetTriple()); 97198090Srdivacky 98198090Srdivacky if (TheTriple.getTriple().empty()) 99234353Sdim TheTriple.setTriple(sys::getDefaultTargetTriple()); 100221337Sdim 101198090Srdivacky TargetTriple.setTriple(TheTriple.getTriple()); 102198090Srdivacky } 103198090Srdivacky 104198090Srdivacky Result->setTargetTriple(TargetTriple.getTriple()); // override the triple 105193323Sed } 106193323Sed return Result; 107193323Sed} 108193323Sed 109193323Sed// This method takes the specified list of LLVM input files, attempts to load 110193323Sed// them, either as assembly or bitcode, then link them together. It returns 111193323Sed// true on failure (if, for example, an input bitcode file could not be 112193323Sed// parsed), and false on success. 113193323Sed// 114193323Sedbool BugDriver::addSources(const std::vector<std::string> &Filenames) { 115193323Sed assert(Program == 0 && "Cannot call addSources multiple times!"); 116193323Sed assert(!Filenames.empty() && "Must specify at least on input filename!"); 117193323Sed 118207618Srdivacky // Load the first input file. 119207618Srdivacky Program = ParseInputFile(Filenames[0], Context); 120207618Srdivacky if (Program == 0) return true; 121221337Sdim 122212793Sdim outs() << "Read input file : '" << Filenames[0] << "'\n"; 123193323Sed 124207618Srdivacky for (unsigned i = 1, e = Filenames.size(); i != e; ++i) { 125207618Srdivacky std::auto_ptr<Module> M(ParseInputFile(Filenames[i], Context)); 126207618Srdivacky if (M.get() == 0) return true; 127193323Sed 128212793Sdim outs() << "Linking in input file: '" << Filenames[i] << "'\n"; 129207618Srdivacky std::string ErrorMessage; 130226584Sdim if (Linker::LinkModules(Program, M.get(), Linker::DestroySource, 131226584Sdim &ErrorMessage)) { 132207618Srdivacky errs() << ToolName << ": error linking in '" << Filenames[i] << "': " 133207618Srdivacky << ErrorMessage << '\n'; 134207618Srdivacky return true; 135193323Sed } 136193323Sed } 137193323Sed 138212793Sdim outs() << "*** All input ok\n"; 139193323Sed 140193323Sed // All input files read successfully! 141193323Sed return false; 142193323Sed} 143193323Sed 144193323Sed 145193323Sed 146193323Sed/// run - The top level method that is invoked after all of the instance 147193323Sed/// variables are set up from command line arguments. 148193323Sed/// 149207618Srdivackybool BugDriver::run(std::string &ErrMsg) { 150193323Sed if (run_find_bugs) { 151193323Sed // Rearrange the passes and apply them to the program. Repeat this process 152193323Sed // until the user kills the program or we find a bug. 153207618Srdivacky return runManyPasses(PassesToRun, ErrMsg); 154193323Sed } 155193323Sed 156221337Sdim // If we're not running as a child, the first thing that we must do is 157221337Sdim // determine what the problem is. Does the optimization series crash the 158221337Sdim // compiler, or does it produce illegal code? We make the top-level 159239462Sdim // decision by trying to run all of the passes on the input program, 160221337Sdim // which should generate a bitcode file. If it does generate a bitcode 161221337Sdim // file, then we know the compiler didn't crash, so try to diagnose a 162193323Sed // miscompilation. 163193323Sed if (!PassesToRun.empty()) { 164198090Srdivacky outs() << "Running selected passes on program to test for crash: "; 165212793Sdim if (runPasses(Program, PassesToRun)) 166193323Sed return debugOptimizerCrash(); 167193323Sed } 168193323Sed 169193323Sed // Set up the execution environment, selecting a method to run LLVM bitcode. 170193323Sed if (initializeExecutionEnvironment()) return true; 171193323Sed 172193323Sed // Test to see if we have a code generator crash. 173198090Srdivacky outs() << "Running the code generator to test for a crash: "; 174207618Srdivacky std::string Error; 175207618Srdivacky compileProgram(Program, &Error); 176207618Srdivacky if (!Error.empty()) { 177207618Srdivacky outs() << Error; 178207618Srdivacky return debugCodeGeneratorCrash(ErrMsg); 179193323Sed } 180207618Srdivacky outs() << '\n'; 181193323Sed 182193323Sed // Run the raw input to see where we are coming from. If a reference output 183193323Sed // was specified, make sure that the raw output matches it. If not, it's a 184193323Sed // problem in the front-end or the code generator. 185193323Sed // 186193323Sed bool CreatedOutput = false; 187193323Sed if (ReferenceOutputFile.empty()) { 188198090Srdivacky outs() << "Generating reference output from raw program: "; 189207618Srdivacky if (!createReferenceFile(Program)) { 190207618Srdivacky return debugCodeGeneratorCrash(ErrMsg); 191193323Sed } 192193323Sed CreatedOutput = true; 193193323Sed } 194193323Sed 195193323Sed // Make sure the reference output file gets deleted on exit from this 196193323Sed // function, if appropriate. 197193323Sed sys::Path ROF(ReferenceOutputFile); 198221337Sdim FileRemover RemoverInstance(ROF.str(), CreatedOutput && !SaveTemps); 199193323Sed 200193323Sed // Diff the output of the raw program against the reference output. If it 201221337Sdim // matches, then we assume there is a miscompilation bug and try to 202193323Sed // diagnose it. 203198090Srdivacky outs() << "*** Checking the code generator...\n"; 204212793Sdim bool Diff = diffProgram(Program, "", "", false, &Error); 205207618Srdivacky if (!Error.empty()) { 206207618Srdivacky errs() << Error; 207207618Srdivacky return debugCodeGeneratorCrash(ErrMsg); 208207618Srdivacky } 209207618Srdivacky if (!Diff) { 210207618Srdivacky outs() << "\n*** Output matches: Debugging miscompilation!\n"; 211207618Srdivacky debugMiscompilation(&Error); 212207618Srdivacky if (!Error.empty()) { 213207618Srdivacky errs() << Error; 214207618Srdivacky return debugCodeGeneratorCrash(ErrMsg); 215193323Sed } 216207618Srdivacky return false; 217193323Sed } 218193323Sed 219198090Srdivacky outs() << "\n*** Input program does not match reference diff!\n"; 220198090Srdivacky outs() << "Debugging code generator problem!\n"; 221207618Srdivacky bool Failure = debugCodeGenerator(&Error); 222207618Srdivacky if (!Error.empty()) { 223207618Srdivacky errs() << Error; 224207618Srdivacky return debugCodeGeneratorCrash(ErrMsg); 225193323Sed } 226207618Srdivacky return Failure; 227193323Sed} 228193323Sed 229193323Sedvoid llvm::PrintFunctionList(const std::vector<Function*> &Funcs) { 230193323Sed unsigned NumPrint = Funcs.size(); 231193323Sed if (NumPrint > 10) NumPrint = 10; 232193323Sed for (unsigned i = 0; i != NumPrint; ++i) 233198090Srdivacky outs() << " " << Funcs[i]->getName(); 234193323Sed if (NumPrint < Funcs.size()) 235198090Srdivacky outs() << "... <" << Funcs.size() << " total>"; 236198090Srdivacky outs().flush(); 237193323Sed} 238193323Sed 239193323Sedvoid llvm::PrintGlobalVariableList(const std::vector<GlobalVariable*> &GVs) { 240193323Sed unsigned NumPrint = GVs.size(); 241193323Sed if (NumPrint > 10) NumPrint = 10; 242193323Sed for (unsigned i = 0; i != NumPrint; ++i) 243198090Srdivacky outs() << " " << GVs[i]->getName(); 244193323Sed if (NumPrint < GVs.size()) 245198090Srdivacky outs() << "... <" << GVs.size() << " total>"; 246198090Srdivacky outs().flush(); 247193323Sed} 248