BugDriver.h revision a0f5b15e1eb8642d92b3141a6b88a5729ea979dc
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 3047ae4a1cee5eec5767a11403c0fac7c91ec45461Chris Lattnerextern bool DisableSimplifyCFG; 3147ae4a1cee5eec5767a11403c0fac7c91ec45461Chris Lattner 32afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattnerclass BugDriver { 33afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner const std::string ToolName; // Name of bugpoint 34a259c9be2acc9528ec7feb3cfd51dcde36d87bb3Misha Brukman std::string ReferenceOutputFile; // Name of `good' output file 35afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner Module *Program; // The raw program, linked together 36afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner std::vector<const PassInfo*> PassesToRun; 37218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner AbstractInterpreter *Interpreter; // How to run the program 38a259c9be2acc9528ec7feb3cfd51dcde36d87bb3Misha Brukman CBE *cbe; 39a259c9be2acc9528ec7feb3cfd51dcde36d87bb3Misha Brukman GCC *gcc; 40640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner 41aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner // FIXME: sort out public/private distinctions... 42aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner friend class DebugCrashes; 43640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner friend class ReduceMiscompilingPasses; 44640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner friend class ReduceMiscompilingFunctions; 455073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman friend class ReduceMisCodegenFunctions; 46aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner friend class ReduceCrashingFunctions; 47286921e8d21d4f0655905ed278d0e140829c7d1fChris Lattner friend class ReduceCrashingBlocks; 485073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 49afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattnerpublic: 505073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman BugDriver(const char *toolname); 51218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner 52218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner const std::string &getToolName() const { return ToolName; } 53afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 54afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner // Set up methods... these methods are used to copy information about the 55afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner // command line arguments into instance variables of BugDriver. 56afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner // 57afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner bool addSources(const std::vector<std::string> &FileNames); 58afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner template<class It> 59afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner void addPasses(It I, It E) { PassesToRun.insert(PassesToRun.end(), I, E); } 60afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 61afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner /// run - The top level method that is invoked after all of the instance 62afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner /// variables are set up from command line arguments. 63afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner /// 64afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner bool run(); 65afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 66afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner /// debugCrash - This method is called when some pass crashes on input. It 67afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner /// attempts to prune down the testcase to something reasonable, and figure 68afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner /// out exactly which pass is crashing. 69afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner /// 70afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner bool debugCrash(); 71afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 72afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner /// debugMiscompilation - This method is used when the passes selected are not 73afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner /// crashing, but the generated output is semantically different from the 74afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner /// input. 75afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner bool debugMiscompilation(); 76afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 77218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner /// debugPassMiscompilation - This method is called when the specified pass 78218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner /// miscompiles Program as input. It tries to reduce the testcase to 79218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner /// something that smaller that still miscompiles the program. 80218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner /// ReferenceOutput contains the filename of the file containing the output we 81218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner /// are to match. 82218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner /// 83218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner bool debugPassMiscompilation(const PassInfo *ThePass, 84218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner const std::string &ReferenceOutput); 85218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner 865073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman /// compileSharedObject - This method creates a SharedObject from a given 875073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman /// BytecodeFile for debugging a code generator. 88a0f5b15e1eb8642d92b3141a6b88a5729ea979dcChris Lattner /// 89a0f5b15e1eb8642d92b3141a6b88a5729ea979dcChris Lattner std::string compileSharedObject(const std::string &BytecodeFile); 905073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 915073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman /// debugCodeGenerator - This method narrows down a module to a function or 925073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman /// set of functions, using the CBE as a ``safe'' code generator for other 935073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman /// functions that are not under consideration. 945073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman bool debugCodeGenerator(); 955073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 96fe04db890b87d9ac4c4a607e6bd0035e8cc2ad6cMisha Brukman /// isExecutingJIT - Returns true if bugpoint is currently testing the JIT 97fe04db890b87d9ac4c4a607e6bd0035e8cc2ad6cMisha Brukman /// 9891eabc13d3a456cc4b387d3d7fdb041d976732c7Misha Brukman bool isExecutingJIT(); 9991eabc13d3a456cc4b387d3d7fdb041d976732c7Misha Brukman 100afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattnerprivate: 101afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner /// ParseInputFile - Given a bytecode or assembly input filename, parse and 102afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner /// return it, or return null if not possible. 103afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner /// 104afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner Module *ParseInputFile(const std::string &InputFilename) const; 105afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 106afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner /// writeProgramToFile - This writes the current "Program" to the named 107afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner /// bytecode file. If an error occurs, true is returned. 108afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner /// 109218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner bool writeProgramToFile(const std::string &Filename, Module *M = 0) const; 110afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 111afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 112afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner /// EmitProgressBytecode - This function is used to output the current Program 113afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner /// to a file named "bugpoing-ID.bc". 114afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner /// 115640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner void EmitProgressBytecode(const std::string &ID, bool NoFlyer = false); 116afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 117afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner /// runPasses - Run the specified passes on Program, outputting a bytecode 118afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner /// file and writting the filename into OutputFile if successful. If the 119afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner /// optimizations fail for some reason (optimizer crashes), return true, 120afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner /// otherwise return false. If DeleteOutput is set to true, the bytecode is 121afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner /// deleted on success, and the filename string is undefined. This prints to 122afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner /// cout a single line message indicating whether compilation was successful 123218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner /// or failed, unless Quiet is set. 124afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner /// 125afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner bool runPasses(const std::vector<const PassInfo*> &PassesToRun, 126218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner std::string &OutputFilename, bool DeleteOutput = false, 127218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner bool Quiet = false) const; 128afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 129afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner /// runPasses - Just like the method above, but this just returns true or 130afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner /// false indicating whether or not the optimizer crashed on the specified 131afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner /// input (true = crashed). 132afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner /// 133afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner bool runPasses(const std::vector<const PassInfo*> &PassesToRun, 134afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner bool DeleteOutput = true) const { 135afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner std::string Filename; 136afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner return runPasses(PassesToRun, Filename, DeleteOutput); 137afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner } 138afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 1395073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman /// PrintFunctionList - prints out list of problematic functions 140a259c9be2acc9528ec7feb3cfd51dcde36d87bb3Misha Brukman /// 1415073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman static void PrintFunctionList(const std::vector<Function*> &Funcs); 1425073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 1436520785dcd22012535934098942d57c07c7631c2Chris Lattner /// deleteInstructionFromProgram - This method clones the current Program and 1446520785dcd22012535934098942d57c07c7631c2Chris Lattner /// deletes the specified instruction from the cloned module. It then runs a 1456520785dcd22012535934098942d57c07c7631c2Chris Lattner /// series of cleanup passes (ADCE and SimplifyCFG) to eliminate any code 1466520785dcd22012535934098942d57c07c7631c2Chris Lattner /// which depends on the value. The modified module is then returned. 1476520785dcd22012535934098942d57c07c7631c2Chris Lattner /// 1486520785dcd22012535934098942d57c07c7631c2Chris Lattner Module *deleteInstructionFromProgram(Instruction *I, unsigned Simp) const; 1496520785dcd22012535934098942d57c07c7631c2Chris Lattner 150ba386d943f4a83095d9c625cb0d46c1afe45ed1fChris Lattner /// performFinalCleanups - This method clones the current Program and performs 151ba386d943f4a83095d9c625cb0d46c1afe45ed1fChris Lattner /// a series of cleanups intended to get rid of extra cruft on the module 152587a6ce4b99346b5e785d0a5c360c6c6687b036aChris Lattner /// before handing it to the user... if the module parameter is specified, it 153587a6ce4b99346b5e785d0a5c360c6c6687b036aChris Lattner /// operates directly on the specified Module, modifying it in place. 154ba386d943f4a83095d9c625cb0d46c1afe45ed1fChris Lattner /// 155587a6ce4b99346b5e785d0a5c360c6c6687b036aChris Lattner Module *performFinalCleanups(Module *M = 0) const; 156ba386d943f4a83095d9c625cb0d46c1afe45ed1fChris Lattner 157218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner /// initializeExecutionEnvironment - This method is used to set up the 158218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner /// environment for executing LLVM programs. 159218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner /// 160218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner bool initializeExecutionEnvironment(); 161218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner 162218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner /// executeProgram - This method runs "Program", capturing the output of the 163218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner /// program to a file, returning the filename of the file. A recommended 164218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner /// filename may be optionally specified. 165218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner /// 166218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner std::string executeProgram(std::string RequestedOutputFilename = "", 1675073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman std::string Bytecode = "", 1685073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman std::string SharedObject = "", 1695073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman AbstractInterpreter *AI = 0); 1705073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman 1715073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman /// executeProgramWithCBE - Used to create reference output with the C 1725073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman /// backend, if reference output is not provided. 1735073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman std::string executeProgramWithCBE(std::string RequestedOutputFilename = "", 1745073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman std::string Bytecode = "", 1755073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman std::string SharedObject = ""); 176218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner 177218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner /// diffProgram - This method executes the specified module and diffs the 178218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner /// output against the file specified by ReferenceOutputFile. If the output 179218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner /// is different, true is returned. 180218e26ef3583cc3270f5f2a2b9cb1025e5b05ebeChris Lattner /// 1815073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman bool diffProgram(const std::string &BytecodeFile = "", 1825073336cd4da5df4ae13a167582d1dc90f32e4e0Misha Brukman const std::string &SharedObject = "", 183640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner bool RemoveBytecode = false); 184afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner}; 185afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner 186640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner/// getPassesString - Turn a list of passes into a string which indicates the 187640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner/// command line options that must be passed to add the passes. 188640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner/// 189640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattnerstd::string getPassesString(const std::vector<const PassInfo*> &Passes); 190640f22e66d90439857a97a83896ee68c4f7128c9Chris Lattner 191aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner// DeleteFunctionBody - "Remove" the function by deleting all of it's basic 192aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner// blocks, making it external. 193aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner// 194aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattnervoid DeleteFunctionBody(Function *F); 195aae33f9137e4a64394d8f9fe66611ae53a0ef4e8Chris Lattner 196afade9294af43c6b947b9aeaa1555883d5f853e3Chris Lattner#endif 197