BugDriver.h revision 91eabc13d3a456cc4b387d3d7fdb041d976732c7
1afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner//===- BugDriver.h - Top-Level BugPoint class -------------------*- C++ -*-===// 2afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner// 3afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner// This class contains all of the shared state and information that is used by 4afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner// the BugPoint tool to track down errors in optimizations. This class is the 5afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner// main driver class that invokes all sub-functionality. 6afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner// 7afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner//===----------------------------------------------------------------------===// 8afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 9afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner#ifndef BUGDRIVER_H 10afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner#define BUGDRIVER_H 11afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 12afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner#include <vector> 13afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner#include <string> 145073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 15afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattnerclass PassInfo; 16afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattnerclass Module; 17afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattnerclass Function; 18218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattnerclass AbstractInterpreter; 196520785dcd22012535934098942d57c07c7631c2Chris Lattnerclass Instruction; 20afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 21aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattnerclass DebugCrashes; 22640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattnerclass ReduceMiscompilingPasses; 23640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattnerclass ReduceMiscompilingFunctions; 24aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattnerclass ReduceCrashingFunctions; 25286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattnerclass ReduceCrashingBlocks; 26640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner 27a259c9be2acc9528ec7feb3cfd51dcde36d87bb3Misha Brukmanclass CBE; 28a259c9be2acc9528ec7feb3cfd51dcde36d87bb3Misha Brukmanclass GCC; 29a259c9be2acc9528ec7feb3cfd51dcde36d87bb3Misha Brukman 30afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattnerclass BugDriver { 31afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner const std::string ToolName; // Name of bugpoint 32a259c9be2acc9528ec7feb3cfd51dcde36d87bb3Misha Brukman std::string ReferenceOutputFile; // Name of `good' output file 33afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner Module *Program; // The raw program, linked together 34afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner std::vector<const PassInfo*> PassesToRun; 35218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner AbstractInterpreter *Interpreter; // How to run the program 36a259c9be2acc9528ec7feb3cfd51dcde36d87bb3Misha Brukman CBE *cbe; 37a259c9be2acc9528ec7feb3cfd51dcde36d87bb3Misha Brukman GCC *gcc; 38640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner 39aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner // FIXME: sort out public/private distinctions... 40aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner friend class DebugCrashes; 41640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner friend class ReduceMiscompilingPasses; 42640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner friend class ReduceMiscompilingFunctions; 435073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman friend class ReduceMisCodegenFunctions; 44aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner friend class ReduceCrashingFunctions; 45286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner friend class ReduceCrashingBlocks; 465073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 47afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattnerpublic: 485073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman BugDriver(const char *toolname); 49218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner 50218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner const std::string &getToolName() const { return ToolName; } 51afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 52afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner // Set up methods... these methods are used to copy information about the 53afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner // command line arguments into instance variables of BugDriver. 54afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner // 55afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner bool addSources(const std::vector<std::string> &FileNames); 56afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner template<class It> 57afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner void addPasses(It I, It E) { PassesToRun.insert(PassesToRun.end(), I, E); } 58afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 59afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner /// run - The top level method that is invoked after all of the instance 60afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner /// variables are set up from command line arguments. 61afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner /// 62afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner bool run(); 63afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 64afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner /// debugCrash - This method is called when some pass crashes on input. It 65afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner /// attempts to prune down the testcase to something reasonable, and figure 66afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner /// out exactly which pass is crashing. 67afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner /// 68afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner bool debugCrash(); 69afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 70afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner /// debugMiscompilation - This method is used when the passes selected are not 71afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner /// crashing, but the generated output is semantically different from the 72afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner /// input. 73afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner bool debugMiscompilation(); 74afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 75218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner /// debugPassMiscompilation - This method is called when the specified pass 76218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner /// miscompiles Program as input. It tries to reduce the testcase to 77218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner /// something that smaller that still miscompiles the program. 78218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner /// ReferenceOutput contains the filename of the file containing the output we 79218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner /// are to match. 80218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner /// 81218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner bool debugPassMiscompilation(const PassInfo *ThePass, 82218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner const std::string &ReferenceOutput); 83218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner 845073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman /// compileSharedObject - This method creates a SharedObject from a given 855073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman /// BytecodeFile for debugging a code generator. 865073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman int compileSharedObject(const std::string &BytecodeFile, 875073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman std::string &SharedObject); 885073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 895073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman /// debugCodeGenerator - This method narrows down a module to a function or 905073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman /// set of functions, using the CBE as a ``safe'' code generator for other 915073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman /// functions that are not under consideration. 925073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman bool debugCodeGenerator(); 935073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 9491eabc13d3a456cc4b387d3d7fdb041d976732c7Misha Brukman bool isExecutingJIT(); 9591eabc13d3a456cc4b387d3d7fdb041d976732c7Misha Brukman 96afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattnerprivate: 97afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner /// ParseInputFile - Given a bytecode or assembly input filename, parse and 98afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner /// return it, or return null if not possible. 99afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner /// 100afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner Module *ParseInputFile(const std::string &InputFilename) const; 101afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 102afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner /// writeProgramToFile - This writes the current "Program" to the named 103afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner /// bytecode file. If an error occurs, true is returned. 104afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner /// 105218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner bool writeProgramToFile(const std::string &Filename, Module *M = 0) const; 106afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 107afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 108afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner /// EmitProgressBytecode - This function is used to output the current Program 109afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner /// to a file named "bugpoing-ID.bc". 110afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner /// 111640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner void EmitProgressBytecode(const std::string &ID, bool NoFlyer = false); 112afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 113afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner /// runPasses - Run the specified passes on Program, outputting a bytecode 114afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner /// file and writting the filename into OutputFile if successful. If the 115afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner /// optimizations fail for some reason (optimizer crashes), return true, 116afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner /// otherwise return false. If DeleteOutput is set to true, the bytecode is 117afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner /// deleted on success, and the filename string is undefined. This prints to 118afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner /// cout a single line message indicating whether compilation was successful 119218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner /// or failed, unless Quiet is set. 120afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner /// 121afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner bool runPasses(const std::vector<const PassInfo*> &PassesToRun, 122218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner std::string &OutputFilename, bool DeleteOutput = false, 123218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner bool Quiet = false) const; 124afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 125afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner /// runPasses - Just like the method above, but this just returns true or 126afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner /// false indicating whether or not the optimizer crashed on the specified 127afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner /// input (true = crashed). 128afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner /// 129afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner bool runPasses(const std::vector<const PassInfo*> &PassesToRun, 130afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner bool DeleteOutput = true) const { 131afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner std::string Filename; 132afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner return runPasses(PassesToRun, Filename, DeleteOutput); 133afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner } 134afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 1355073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman /// PrintFunctionList - prints out list of problematic functions 136a259c9be2acc9528ec7feb3cfd51dcde36d87bb3Misha Brukman /// 1375073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman static void PrintFunctionList(const std::vector<Function*> &Funcs); 1385073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 1396520785dcd22012535934098942d57c07c7631c2Chris Lattner /// deleteInstructionFromProgram - This method clones the current Program and 1406520785dcd22012535934098942d57c07c7631c2Chris Lattner /// deletes the specified instruction from the cloned module. It then runs a 1416520785dcd22012535934098942d57c07c7631c2Chris Lattner /// series of cleanup passes (ADCE and SimplifyCFG) to eliminate any code 1426520785dcd22012535934098942d57c07c7631c2Chris Lattner /// which depends on the value. The modified module is then returned. 1436520785dcd22012535934098942d57c07c7631c2Chris Lattner /// 1446520785dcd22012535934098942d57c07c7631c2Chris Lattner Module *deleteInstructionFromProgram(Instruction *I, unsigned Simp) const; 1456520785dcd22012535934098942d57c07c7631c2Chris Lattner 146ba386d943f4a83095d9c625cb0d46c1afe45ed1fChris Lattner /// performFinalCleanups - This method clones the current Program and performs 147ba386d943f4a83095d9c625cb0d46c1afe45ed1fChris Lattner /// a series of cleanups intended to get rid of extra cruft on the module 148ba386d943f4a83095d9c625cb0d46c1afe45ed1fChris Lattner /// before handing it to the user... 149ba386d943f4a83095d9c625cb0d46c1afe45ed1fChris Lattner /// 150ba386d943f4a83095d9c625cb0d46c1afe45ed1fChris Lattner Module *performFinalCleanups() const; 151ba386d943f4a83095d9c625cb0d46c1afe45ed1fChris Lattner 152218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner /// initializeExecutionEnvironment - This method is used to set up the 153218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner /// environment for executing LLVM programs. 154218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner /// 155218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner bool initializeExecutionEnvironment(); 156218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner 157218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner /// executeProgram - This method runs "Program", capturing the output of the 158218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner /// program to a file, returning the filename of the file. A recommended 159218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner /// filename may be optionally specified. 160218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner /// 161218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner std::string executeProgram(std::string RequestedOutputFilename = "", 1625073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman std::string Bytecode = "", 1635073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman std::string SharedObject = "", 1645073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman AbstractInterpreter *AI = 0); 1655073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 1665073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman /// executeProgramWithCBE - Used to create reference output with the C 1675073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman /// backend, if reference output is not provided. 1685073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman std::string executeProgramWithCBE(std::string RequestedOutputFilename = "", 1695073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman std::string Bytecode = "", 1705073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman std::string SharedObject = ""); 171218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner 172218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner /// diffProgram - This method executes the specified module and diffs the 173218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner /// output against the file specified by ReferenceOutputFile. If the output 174218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner /// is different, true is returned. 175218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner /// 1765073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman bool diffProgram(const std::string &BytecodeFile = "", 1775073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman const std::string &SharedObject = "", 178640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner bool RemoveBytecode = false); 179afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner}; 180afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 181640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner/// getPassesString - Turn a list of passes into a string which indicates the 182640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner/// command line options that must be passed to add the passes. 183640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner/// 184640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattnerstd::string getPassesString(const std::vector<const PassInfo*> &Passes); 185640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner 186aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner// DeleteFunctionBody - "Remove" the function by deleting all of it's basic 187aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner// blocks, making it external. 188aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner// 189aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattnervoid DeleteFunctionBody(Function *F); 190aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner 191afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner#endif 192