BugDriver.h revision 3b6441e1050a9a2a55c79f58513191b3195fdaf7
1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===- BugDriver.h - Top-Level BugPoint class -------------------*- C++ -*-===// 2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// 3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// The LLVM Compiler Infrastructure 4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// 5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// This file was developed by the LLVM research group and is distributed under 6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// the University of Illinois Open Source License. See LICENSE.TXT for details. 7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// 8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===// 9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// 10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// This class contains all of the shared state and information that is used by 11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// the BugPoint tool to track down errors in optimizations. This class is the 12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// main driver class that invokes all sub-functionality. 13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// 14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org//===----------------------------------------------------------------------===// 15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifndef BUGDRIVER_H 17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define BUGDRIVER_H 18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <vector> 20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <string> 21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnamespace llvm { 23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclass PassInfo; 25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclass Module; 26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclass Function; 27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclass AbstractInterpreter; 28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclass Instruction; 29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclass DebugCrashes; 31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclass CBE; 33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclass GCC; 34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgextern bool DisableSimplifyCFG; 36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgclass BugDriver { 38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const std::string ToolName; // Name of bugpoint 39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org std::string ReferenceOutputFile; // Name of `good' output file 40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org Module *Program; // The raw program, linked together 41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org std::vector<const PassInfo*> PassesToRun; 42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org AbstractInterpreter *Interpreter; // How to run the program 43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org CBE *cbe; 44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GCC *gcc; 45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // FIXME: sort out public/private distinctions... 47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org friend class ReducePassList; 48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org friend class ReduceMisCodegenFunctions; 49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpublic: 51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org BugDriver(const char *toolname); 52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const std::string &getToolName() const { return ToolName; } 54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // Set up methods... these methods are used to copy information about the 56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // command line arguments into instance variables of BugDriver. 57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org // 58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool addSources(const std::vector<std::string> &FileNames); 59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org template<class It> 60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void addPasses(It I, It E) { PassesToRun.insert(PassesToRun.end(), I, E); } 61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void setPassesToRun(const std::vector<const PassInfo*> &PTR) { 62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org PassesToRun = PTR; 63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const std::vector<const PassInfo*> &getPassesToRun() const { 65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return PassesToRun; 66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /// run - The top level method that is invoked after all of the instance 69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /// variables are set up from command line arguments. 70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /// 71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool run(); 72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /// debugOptimizerCrash - This method is called when some optimizer pass 74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /// crashes on input. It attempts to prune down the testcase to something 75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /// reasonable, and figure out exactly which pass is crashing. 76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /// 77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool debugOptimizerCrash(); 78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /// debugCodeGeneratorCrash - This method is called when the code generator 80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /// crashes on an input. It attempts to reduce the input as much as possible 81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /// while still causing the code generator to crash. 82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool debugCodeGeneratorCrash(); 83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /// debugMiscompilation - This method is used when the passes selected are not 85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /// crashing, but the generated output is semantically different from the 86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /// input. 87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool debugMiscompilation(); 88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /// debugPassMiscompilation - This method is called when the specified pass 90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /// miscompiles Program as input. It tries to reduce the testcase to 91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /// something that smaller that still miscompiles the program. 92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /// ReferenceOutput contains the filename of the file containing the output we 93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /// are to match. 94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /// 95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool debugPassMiscompilation(const PassInfo *ThePass, 96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const std::string &ReferenceOutput); 97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /// compileSharedObject - This method creates a SharedObject from a given 99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /// BytecodeFile for debugging a code generator. 100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /// 101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org std::string compileSharedObject(const std::string &BytecodeFile); 102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /// debugCodeGenerator - This method narrows down a module to a function or 104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /// set of functions, using the CBE as a ``safe'' code generator for other 105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /// functions that are not under consideration. 106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool debugCodeGenerator(); 107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /// isExecutingJIT - Returns true if bugpoint is currently testing the JIT 109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /// 110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool isExecutingJIT(); 111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /// runPasses - Run all of the passes in the "PassesToRun" list, discard the 113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /// output, and return true if any of the passes crashed. 114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool runPasses(Module *M = 0) { 115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (M == 0) M = Program; 116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org std::swap(M, Program); 117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org bool Result = runPasses(PassesToRun); 118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org std::swap(M, Program); 119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return Result; 120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org Module *getProgram() const { return Program; } 123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /// swapProgramIn - Set the current module to the specified module, returning 125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /// the old one. 126 Module *swapProgramIn(Module *M) { 127 Module *OldProgram = Program; 128 Program = M; 129 return OldProgram; 130 } 131 132 /// setNewProgram - If we reduce or update the program somehow, call this 133 /// method to update bugdriver with it. This deletes the old module and sets 134 /// the specified one as the current program. 135 void setNewProgram(Module *M); 136 137 /// compileProgram - Try to compile the specified module, throwing an 138 /// exception if an error occurs, or returning normally if not. This is used 139 /// for code generation crash testing. 140 /// 141 void compileProgram(Module *M); 142 143 /// executeProgram - This method runs "Program", capturing the output of the 144 /// program to a file, returning the filename of the file. A recommended 145 /// filename may be optionally specified. If there is a problem with the code 146 /// generator (e.g., llc crashes), this will throw an exception. 147 /// 148 std::string executeProgram(std::string RequestedOutputFilename = "", 149 std::string Bytecode = "", 150 const std::string &SharedObjects = "", 151 AbstractInterpreter *AI = 0, 152 bool *ProgramExitedNonzero = 0); 153 154 /// executeProgramWithCBE - Used to create reference output with the C 155 /// backend, if reference output is not provided. If there is a problem with 156 /// the code generator (e.g., llc crashes), this will throw an exception. 157 /// 158 std::string executeProgramWithCBE(std::string OutputFile = ""); 159 160 /// diffProgram - This method executes the specified module and diffs the 161 /// output against the file specified by ReferenceOutputFile. If the output 162 /// is different, true is returned. If there is a problem with the code 163 /// generator (e.g., llc crashes), this will throw an exception. 164 /// 165 bool diffProgram(const std::string &BytecodeFile = "", 166 const std::string &SharedObj = "", 167 bool RemoveBytecode = false); 168 /// EmitProgressBytecode - This function is used to output the current Program 169 /// to a file named "bugpoint-ID.bc". 170 /// 171 void EmitProgressBytecode(const std::string &ID, bool NoFlyer = false); 172 173 /// deleteInstructionFromProgram - This method clones the current Program and 174 /// deletes the specified instruction from the cloned module. It then runs a 175 /// series of cleanup passes (ADCE and SimplifyCFG) to eliminate any code 176 /// which depends on the value. The modified module is then returned. 177 /// 178 Module *deleteInstructionFromProgram(const Instruction *I, unsigned Simp) 179 const; 180 181 /// performFinalCleanups - This method clones the current Program and performs 182 /// a series of cleanups intended to get rid of extra cruft on the module. If 183 /// the MayModifySemantics argument is true, then the cleanups is allowed to 184 /// modify how the code behaves. 185 /// 186 Module *performFinalCleanups(Module *M, bool MayModifySemantics = false); 187 188 /// ExtractLoop - Given a module, extract up to one loop from it into a new 189 /// function. This returns null if there are no extractable loops in the 190 /// program or if the loop extractor crashes. 191 Module *ExtractLoop(Module *M); 192 193 /// runPassesOn - Carefully run the specified set of pass on the specified 194 /// module, returning the transformed module on success, or a null pointer on 195 /// failure. 196 Module *runPassesOn(Module *M, const std::vector<const PassInfo*> &Passes); 197 198 /// runPasses - Run the specified passes on Program, outputting a bytecode 199 /// file and writting the filename into OutputFile if successful. If the 200 /// optimizations fail for some reason (optimizer crashes), return true, 201 /// otherwise return false. If DeleteOutput is set to true, the bytecode is 202 /// deleted on success, and the filename string is undefined. This prints to 203 /// cout a single line message indicating whether compilation was successful 204 /// or failed, unless Quiet is set. 205 /// 206 bool runPasses(const std::vector<const PassInfo*> &PassesToRun, 207 std::string &OutputFilename, bool DeleteOutput = false, 208 bool Quiet = false) const; 209private: 210 /// writeProgramToFile - This writes the current "Program" to the named 211 /// bytecode file. If an error occurs, true is returned. 212 /// 213 bool writeProgramToFile(const std::string &Filename, Module *M = 0) const; 214 215 /// runPasses - Just like the method above, but this just returns true or 216 /// false indicating whether or not the optimizer crashed on the specified 217 /// input (true = crashed). 218 /// 219 bool runPasses(const std::vector<const PassInfo*> &PassesToRun, 220 bool DeleteOutput = true) const { 221 std::string Filename; 222 return runPasses(PassesToRun, Filename, DeleteOutput); 223 } 224 225 /// initializeExecutionEnvironment - This method is used to set up the 226 /// environment for executing LLVM programs. 227 /// 228 bool initializeExecutionEnvironment(); 229}; 230 231/// ParseInputFile - Given a bytecode or assembly input filename, parse and 232/// return it, or return null if not possible. 233/// 234Module *ParseInputFile(const std::string &InputFilename); 235 236 237/// getPassesString - Turn a list of passes into a string which indicates the 238/// command line options that must be passed to add the passes. 239/// 240std::string getPassesString(const std::vector<const PassInfo*> &Passes); 241 242/// PrintFunctionList - prints out list of problematic functions 243/// 244void PrintFunctionList(const std::vector<Function*> &Funcs); 245 246// DeleteFunctionBody - "Remove" the function by deleting all of it's basic 247// blocks, making it external. 248// 249void DeleteFunctionBody(Function *F); 250 251/// SplitFunctionsOutOfModule - Given a module and a list of functions in the 252/// module, split the functions OUT of the specified module, and place them in 253/// the new module. 254Module *SplitFunctionsOutOfModule(Module *M, const std::vector<Function*> &F); 255 256} // End llvm namespace 257 258#endif 259