BugDriver.cpp revision fa76183e8e28985dfd17b1d6291c939dab4cbe1d
1afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner//===- BugDriver.cpp - Top-Level BugPoint class implementation ------------===// 27c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell// 37c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell// The LLVM Compiler Infrastructure 47c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell// 57c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell// This file was developed by the LLVM research group and is distributed under 67c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell// the University of Illinois Open Source License. See LICENSE.TXT for details. 77c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell// 87c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell//===----------------------------------------------------------------------===// 9afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner// 10afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner// This class contains all of the shared state and information that is used by 11afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner// the BugPoint tool to track down errors in optimizations. This class is the 12afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner// main driver class that invokes all sub-functionality. 13afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner// 14afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner//===----------------------------------------------------------------------===// 15afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 16afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner#include "BugDriver.h" 17afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner#include "llvm/Module.h" 18e49603d79d220a795bd50684c8b1f503ee40f97fMisha Brukman#include "llvm/Pass.h" 19afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner#include "llvm/Assembly/Parser.h" 20e49603d79d220a795bd50684c8b1f503ee40f97fMisha Brukman#include "llvm/Bytecode/Reader.h" 21afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner#include "llvm/Transforms/Utils/Linker.h" 225073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman#include "Support/CommandLine.h" 233d9cafa003a114bf9974bc80d5b69b0ed1d29290Misha Brukman#include "Support/FileUtilities.h" 24afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner#include <memory> 25d0fde30ce850b78371fd1386338350591f9ff494Brian Gaekeusing namespace llvm; 26d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke 275073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman// Anonymous namespace to define command line options for debugging. 285073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman// 295073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukmannamespace { 305073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman // Output - The user can specify a file containing the expected output of the 315073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman // program. If this filename is set, it is used as the reference diff source, 325073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman // otherwise the raw input run through an interpreter is used as the reference 335073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman // source. 345073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman // 355073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman cl::opt<std::string> 365073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman OutputFile("output", cl::desc("Specify a reference program output " 375073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman "(for miscompilation detection)")); 385073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman} 395073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 40640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner/// getPassesString - Turn a list of passes into a string which indicates the 41640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner/// command line options that must be passed to add the passes. 42640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner/// 43fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattnerstd::string llvm::getPassesString(const std::vector<const PassInfo*> &Passes) { 44640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner std::string Result; 45640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner for (unsigned i = 0, e = Passes.size(); i != e; ++i) { 46640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner if (i) Result += " "; 47640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner Result += "-"; 48640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner Result += Passes[i]->getPassArgument(); 49640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner } 50640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner return Result; 51640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner} 52640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner 53c8b27318a33d1fe2fbae553159a918ccee8fae29Misha Brukman// DeleteFunctionBody - "Remove" the function by deleting all of its basic 54ff4aaf0010d11a4c42f58f839336669d5fd7ba03Chris Lattner// blocks, making it external. 55ff4aaf0010d11a4c42f58f839336669d5fd7ba03Chris Lattner// 56fa76183e8e28985dfd17b1d6291c939dab4cbe1dChris Lattnervoid llvm::DeleteFunctionBody(Function *F) { 5779f03d350e426f017696c63a29330d153e0a7932Chris Lattner // delete the body of the function... 5879f03d350e426f017696c63a29330d153e0a7932Chris Lattner F->deleteBody(); 59ff4aaf0010d11a4c42f58f839336669d5fd7ba03Chris Lattner assert(F->isExternal() && "This didn't make the function external!"); 60ff4aaf0010d11a4c42f58f839336669d5fd7ba03Chris Lattner} 61640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner 625073336cd4da5df4ae13a167582d1dc90f32e4e0Misha BrukmanBugDriver::BugDriver(const char *toolname) 635073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman : ToolName(toolname), ReferenceOutputFile(OutputFile), 64a259c9be2acc9528ec7feb3cfd51dcde36d87bb3Misha Brukman Program(0), Interpreter(0), cbe(0), gcc(0) {} 655073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 665073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 67afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner/// ParseInputFile - Given a bytecode or assembly input filename, parse and 68afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner/// return it, or return null if not possible. 69afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner/// 70afade9294af43c6b947b9aeaa1555883d5f853e3Chris LattnerModule *BugDriver::ParseInputFile(const std::string &InputFilename) const { 71afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner Module *Result = 0; 72afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner try { 73afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner Result = ParseBytecodeFile(InputFilename); 74afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner if (!Result && !(Result = ParseAssemblyFile(InputFilename))){ 75afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner std::cerr << ToolName << ": could not read input file '" 76afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner << InputFilename << "'!\n"; 77afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner } 78afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner } catch (const ParseException &E) { 79afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner std::cerr << ToolName << ": " << E.getMessage() << "\n"; 80afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner Result = 0; 81afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner } 82afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner return Result; 83afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner} 84afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 85afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner// This method takes the specified list of LLVM input files, attempts to load 86dae7f92366311de2bfaff91f6e66ef3da2f2fcbcBrian Gaeke// them, either as assembly or bytecode, then link them together. It returns 87dae7f92366311de2bfaff91f6e66ef3da2f2fcbcBrian Gaeke// true on failure (if, for example, an input bytecode file could not be 88dae7f92366311de2bfaff91f6e66ef3da2f2fcbcBrian Gaeke// parsed), and false on success. 89afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner// 90afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattnerbool BugDriver::addSources(const std::vector<std::string> &Filenames) { 91afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner assert(Program == 0 && "Cannot call addSources multiple times!"); 92afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner assert(!Filenames.empty() && "Must specify at least on input filename!"); 93afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 94afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner // Load the first input file... 95afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner Program = ParseInputFile(Filenames[0]); 96afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner if (Program == 0) return true; 97afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner std::cout << "Read input file : '" << Filenames[0] << "'\n"; 98afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 99afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner for (unsigned i = 1, e = Filenames.size(); i != e; ++i) { 100afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner std::auto_ptr<Module> M(ParseInputFile(Filenames[i])); 101afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner if (M.get() == 0) return true; 102afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 103afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner std::cout << "Linking in input file: '" << Filenames[i] << "'\n"; 104afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner std::string ErrorMessage; 105afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner if (LinkModules(Program, M.get(), &ErrorMessage)) { 106afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner std::cerr << ToolName << ": error linking in '" << Filenames[i] << "': " 107afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner << ErrorMessage << "\n"; 108afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner return true; 109afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner } 110afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner } 111afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 112afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner std::cout << "*** All input ok\n"; 113afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 114afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner // All input files read successfully! 115afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner return false; 116afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner} 117afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 118afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 119afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 120afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner/// run - The top level method that is invoked after all of the instance 121afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner/// variables are set up from command line arguments. 122afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner/// 123afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattnerbool BugDriver::run() { 124afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner // The first thing that we must do is determine what the problem is. Does the 125afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner // optimization series crash the compiler, or does it produce illegal code? We 126afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner // make the top-level decision by trying to run all of the passes on the the 127afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner // input program, which should generate a bytecode file. If it does generate 128afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner // a bytecode file, then we know the compiler didn't crash, so try to diagnose 129afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner // a miscompilation. 130afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner // 13199b85334d70bc5eb110ee5f1af4ff2f63c55f6cbChris Lattner if (!PassesToRun.empty()) { 13299b85334d70bc5eb110ee5f1af4ff2f63c55f6cbChris Lattner std::cout << "Running selected passes on program to test for crash: "; 13399b85334d70bc5eb110ee5f1af4ff2f63c55f6cbChris Lattner if (runPasses(PassesToRun)) 13499b85334d70bc5eb110ee5f1af4ff2f63c55f6cbChris Lattner return debugCrash(); 13599b85334d70bc5eb110ee5f1af4ff2f63c55f6cbChris Lattner } 1365073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 1375073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman // Set up the execution environment, selecting a method to run LLVM bytecode. 1385073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman if (initializeExecutionEnvironment()) return true; 1395073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 1405073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman // Run the raw input to see where we are coming from. If a reference output 1415073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman // was specified, make sure that the raw output matches it. If not, it's a 1425073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman // problem in the front-end or the code generator. 1435073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman // 144c28c1d3cd19bbfcc8eec44f25c5890f8e3ed8bdcChris Lattner bool CreatedOutput = false; 1455073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman if (ReferenceOutputFile.empty()) { 1465073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman std::cout << "Generating reference output from raw program..."; 147a5a96a9ed9d90014769ffc86ca48c486cf753ad5Chris Lattner ReferenceOutputFile = executeProgramWithCBE("bugpoint.reference.out"); 1485073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman CreatedOutput = true; 1495073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman std::cout << "Reference output is: " << ReferenceOutputFile << "\n"; 150a5a96a9ed9d90014769ffc86ca48c486cf753ad5Chris Lattner } 1515073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 152a5a96a9ed9d90014769ffc86ca48c486cf753ad5Chris Lattner // Make sure the reference output file gets deleted on exit from this 153a5a96a9ed9d90014769ffc86ca48c486cf753ad5Chris Lattner // function, if appropriate. 154a5a96a9ed9d90014769ffc86ca48c486cf753ad5Chris Lattner struct Remover { 155a5a96a9ed9d90014769ffc86ca48c486cf753ad5Chris Lattner bool DeleteIt; const std::string &Filename; 156a5a96a9ed9d90014769ffc86ca48c486cf753ad5Chris Lattner Remover(bool deleteIt, const std::string &filename) 157a5a96a9ed9d90014769ffc86ca48c486cf753ad5Chris Lattner : DeleteIt(deleteIt), Filename(filename) {} 158a5a96a9ed9d90014769ffc86ca48c486cf753ad5Chris Lattner ~Remover() { 159a5a96a9ed9d90014769ffc86ca48c486cf753ad5Chris Lattner if (DeleteIt) removeFile(Filename); 160a5a96a9ed9d90014769ffc86ca48c486cf753ad5Chris Lattner } 161a5a96a9ed9d90014769ffc86ca48c486cf753ad5Chris Lattner } RemoverInstance(CreatedOutput, ReferenceOutputFile); 162a5a96a9ed9d90014769ffc86ca48c486cf753ad5Chris Lattner 163a5a96a9ed9d90014769ffc86ca48c486cf753ad5Chris Lattner // Diff the output of the raw program against the reference output. If it 164a5a96a9ed9d90014769ffc86ca48c486cf753ad5Chris Lattner // matches, then we have a miscompilation bug. 165a5a96a9ed9d90014769ffc86ca48c486cf753ad5Chris Lattner std::cout << "*** Checking the code generator...\n"; 166a5a96a9ed9d90014769ffc86ca48c486cf753ad5Chris Lattner if (!diffProgram()) { 1675073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman std::cout << "\n*** Debugging miscompilation!\n"; 168a5a96a9ed9d90014769ffc86ca48c486cf753ad5Chris Lattner return debugMiscompilation(); 1695073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman } 1705073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 171a5a96a9ed9d90014769ffc86ca48c486cf753ad5Chris Lattner std::cout << "\n*** Input program does not match reference diff!\n"; 172a5a96a9ed9d90014769ffc86ca48c486cf753ad5Chris Lattner std::cout << "Debugging code generator problem!\n"; 173a5a96a9ed9d90014769ffc86ca48c486cf753ad5Chris Lattner return debugCodeGenerator(); 1745073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman} 1755073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 176a5a96a9ed9d90014769ffc86ca48c486cf753ad5Chris Lattnervoid BugDriver::PrintFunctionList(const std::vector<Function*> &Funcs) { 1775073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman for (unsigned i = 0, e = Funcs.size(); i != e; ++i) { 1785073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman if (i) std::cout << ", "; 1795073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman std::cout << Funcs[i]->getName(); 1805073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman } 181b6c3a88dc4c749e88fdd68368d74ccfb37d506a3Brian Gaeke std::cout << std::flush; 182afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner} 183d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke 184