1 //===- BugDriver.h - Top-Level BugPoint class -------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This class contains all of the shared state and information that is used by 11 // the BugPoint tool to track down errors in optimizations. This class is the 12 // main driver class that invokes all sub-functionality. 13 // 14 //===----------------------------------------------------------------------===// 15 16 #ifndef LLVM_TOOLS_BUGPOINT_BUGDRIVER_H 17 #define LLVM_TOOLS_BUGPOINT_BUGDRIVER_H 18 19 #include "llvm/IR/ValueMap.h" 20 #include "llvm/Support/Error.h" 21 #include "llvm/Support/FileSystem.h" 22 #include "llvm/Transforms/Utils/ValueMapper.h" 23 #include <memory> 24 #include <string> 25 #include <vector> 26 27 namespace llvm { 28 29 class Value; 30 class PassInfo; 31 class Module; 32 class GlobalVariable; 33 class Function; 34 class BasicBlock; 35 class AbstractInterpreter; 36 class Instruction; 37 class LLVMContext; 38 39 class DebugCrashes; 40 41 class CC; 42 43 extern bool DisableSimplifyCFG; 44 45 /// BugpointIsInterrupted - Set to true when the user presses ctrl-c. 46 /// 47 extern bool BugpointIsInterrupted; 48 49 class BugDriver { 50 LLVMContext &Context; 51 const char *ToolName; // argv[0] of bugpoint 52 std::string ReferenceOutputFile; // Name of `good' output file 53 std::unique_ptr<Module> Program; // The raw program, linked together 54 std::vector<std::string> PassesToRun; 55 AbstractInterpreter *Interpreter; // How to run the program 56 AbstractInterpreter *SafeInterpreter; // To generate reference output, etc. 57 CC *cc; 58 bool run_find_bugs; 59 unsigned Timeout; 60 unsigned MemoryLimit; 61 bool UseValgrind; 62 63 // FIXME: sort out public/private distinctions... 64 friend class ReducePassList; 65 friend class ReduceMisCodegenFunctions; 66 67 public: 68 BugDriver(const char *toolname, bool find_bugs, unsigned timeout, 69 unsigned memlimit, bool use_valgrind, LLVMContext &ctxt); 70 ~BugDriver(); 71 getToolName()72 const char *getToolName() const { return ToolName; } 73 getContext()74 LLVMContext &getContext() const { return Context; } 75 76 // Set up methods... these methods are used to copy information about the 77 // command line arguments into instance variables of BugDriver. 78 // 79 bool addSources(const std::vector<std::string> &FileNames); addPass(std::string p)80 void addPass(std::string p) { PassesToRun.push_back(std::move(p)); } setPassesToRun(const std::vector<std::string> & PTR)81 void setPassesToRun(const std::vector<std::string> &PTR) { 82 PassesToRun = PTR; 83 } getPassesToRun()84 const std::vector<std::string> &getPassesToRun() const { return PassesToRun; } 85 86 /// run - The top level method that is invoked after all of the instance 87 /// variables are set up from command line arguments. The \p as_child argument 88 /// indicates whether the driver is to run in parent mode or child mode. 89 /// 90 Error run(); 91 92 /// debugOptimizerCrash - This method is called when some optimizer pass 93 /// crashes on input. It attempts to prune down the testcase to something 94 /// reasonable, and figure out exactly which pass is crashing. 95 /// 96 Error debugOptimizerCrash(const std::string &ID = "passes"); 97 98 /// debugCodeGeneratorCrash - This method is called when the code generator 99 /// crashes on an input. It attempts to reduce the input as much as possible 100 /// while still causing the code generator to crash. 101 Error debugCodeGeneratorCrash(); 102 103 /// debugMiscompilation - This method is used when the passes selected are not 104 /// crashing, but the generated output is semantically different from the 105 /// input. 106 Error debugMiscompilation(); 107 108 /// debugPassMiscompilation - This method is called when the specified pass 109 /// miscompiles Program as input. It tries to reduce the testcase to 110 /// something that smaller that still miscompiles the program. 111 /// ReferenceOutput contains the filename of the file containing the output we 112 /// are to match. 113 /// 114 bool debugPassMiscompilation(const PassInfo *ThePass, 115 const std::string &ReferenceOutput); 116 117 /// compileSharedObject - This method creates a SharedObject from a given 118 /// BitcodeFile for debugging a code generator. 119 /// 120 Expected<std::string> compileSharedObject(const std::string &BitcodeFile); 121 122 /// debugCodeGenerator - This method narrows down a module to a function or 123 /// set of functions, using the CBE as a ``safe'' code generator for other 124 /// functions that are not under consideration. 125 Error debugCodeGenerator(); 126 127 /// isExecutingJIT - Returns true if bugpoint is currently testing the JIT 128 /// 129 bool isExecutingJIT(); 130 getProgram()131 Module &getProgram() const { return *Program; } 132 133 /// Set the current module to the specified module, returning the old one. 134 std::unique_ptr<Module> swapProgramIn(std::unique_ptr<Module> M); 135 switchToSafeInterpreter()136 AbstractInterpreter *switchToSafeInterpreter() { 137 AbstractInterpreter *Old = Interpreter; 138 Interpreter = (AbstractInterpreter *)SafeInterpreter; 139 return Old; 140 } 141 switchToInterpreter(AbstractInterpreter * AI)142 void switchToInterpreter(AbstractInterpreter *AI) { Interpreter = AI; } 143 144 /// If we reduce or update the program somehow, call this method to update 145 /// bugdriver with it. This deletes the old module and sets the specified one 146 /// as the current program. 147 void setNewProgram(std::unique_ptr<Module> M); 148 149 /// Try to compile the specified module. This is used for code generation 150 /// crash testing. 151 Error compileProgram(Module &M) const; 152 153 /// This method runs "Program", capturing the output of the program to a file. 154 /// A recommended filename may be optionally specified. 155 Expected<std::string> executeProgram(const Module &Program, 156 std::string OutputFilename, 157 std::string Bitcode, 158 const std::string &SharedObjects, 159 AbstractInterpreter *AI) const; 160 161 /// Used to create reference output with the "safe" backend, if reference 162 /// output is not provided. If there is a problem with the code generator 163 /// (e.g., llc crashes), this will return false and set Error. 164 Expected<std::string> 165 executeProgramSafely(const Module &Program, 166 const std::string &OutputFile) const; 167 168 /// Calls compileProgram and then records the output into ReferenceOutputFile. 169 /// Returns true if reference file created, false otherwise. Note: 170 /// initializeExecutionEnvironment should be called BEFORE this function. 171 Error createReferenceFile(Module &M, const std::string &Filename = 172 "bugpoint.reference.out-%%%%%%%"); 173 174 /// This method executes the specified module and diffs the output against the 175 /// file specified by ReferenceOutputFile. If the output is different, 1 is 176 /// returned. If there is a problem with the code generator (e.g., llc 177 /// crashes), this will return -1 and set Error. 178 Expected<bool> diffProgram(const Module &Program, 179 const std::string &BitcodeFile = "", 180 const std::string &SharedObj = "", 181 bool RemoveBitcode = false) const; 182 183 /// This function is used to output M to a file named "bugpoint-ID.bc". 184 void EmitProgressBitcode(const Module &M, const std::string &ID, 185 bool NoFlyer = false) const; 186 187 /// This method clones the current Program and deletes the specified 188 /// instruction from the cloned module. It then runs a series of cleanup 189 /// passes (ADCE and SimplifyCFG) to eliminate any code which depends on the 190 /// value. The modified module is then returned. 191 /// 192 std::unique_ptr<Module> deleteInstructionFromProgram(const Instruction *I, 193 unsigned Simp); 194 195 /// This method clones the current Program and performs a series of cleanups 196 /// intended to get rid of extra cruft on the module. If the 197 /// MayModifySemantics argument is true, then the cleanups is allowed to 198 /// modify how the code behaves. 199 /// 200 std::unique_ptr<Module> performFinalCleanups(std::unique_ptr<Module> M, 201 bool MayModifySemantics = false); 202 203 /// Given a module, extract up to one loop from it into a new function. This 204 /// returns null if there are no extractable loops in the program or if the 205 /// loop extractor crashes. 206 std::unique_ptr<Module> extractLoop(Module *M); 207 208 /// Extract all but the specified basic blocks into their own functions. The 209 /// only detail is that M is actually a module cloned from the one the BBs are 210 /// in, so some mapping needs to be performed. If this operation fails for 211 /// some reason (ie the implementation is buggy), this function should return 212 /// null, otherwise it returns a new Module. 213 std::unique_ptr<Module> 214 extractMappedBlocksFromModule(const std::vector<BasicBlock *> &BBs, 215 Module *M); 216 217 /// Carefully run the specified set of pass on the specified/ module, 218 /// returning the transformed module on success, or a null pointer on failure. 219 std::unique_ptr<Module> runPassesOn(Module *M, 220 const std::vector<std::string> &Passes, 221 unsigned NumExtraArgs = 0, 222 const char *const *ExtraArgs = nullptr); 223 224 /// runPasses - Run the specified passes on Program, outputting a bitcode 225 /// file and writting the filename into OutputFile if successful. If the 226 /// optimizations fail for some reason (optimizer crashes), return true, 227 /// otherwise return false. If DeleteOutput is set to true, the bitcode is 228 /// deleted on success, and the filename string is undefined. This prints to 229 /// outs() a single line message indicating whether compilation was successful 230 /// or failed, unless Quiet is set. ExtraArgs specifies additional arguments 231 /// to pass to the child bugpoint instance. 232 /// 233 bool runPasses(Module &Program, const std::vector<std::string> &PassesToRun, 234 std::string &OutputFilename, bool DeleteOutput = false, 235 bool Quiet = false, unsigned NumExtraArgs = 0, 236 const char *const *ExtraArgs = nullptr) const; 237 238 /// runPasses - Just like the method above, but this just returns true or 239 /// false indicating whether or not the optimizer crashed on the specified 240 /// input (true = crashed). Does not produce any output. 241 /// runPasses(Module & M,const std::vector<std::string> & PassesToRun)242 bool runPasses(Module &M, const std::vector<std::string> &PassesToRun) const { 243 std::string Filename; 244 return runPasses(M, PassesToRun, Filename, true); 245 } 246 247 /// Take the specified pass list and create different combinations of passes 248 /// to compile the program with. Compile the program with each set and mark 249 /// test to see if it compiled correctly. If the passes compiled correctly 250 /// output nothing and rearrange the passes into a new order. If the passes 251 /// did not compile correctly, output the command required to recreate the 252 /// failure. 253 Error runManyPasses(const std::vector<std::string> &AllPasses); 254 255 /// This writes the current "Program" to the named bitcode file. If an error 256 /// occurs, true is returned. 257 bool writeProgramToFile(const std::string &Filename, const Module &M) const; 258 bool writeProgramToFile(const std::string &Filename, int FD, 259 const Module &M) const; 260 bool writeProgramToFile(int FD, const Module &M) const; 261 262 private: 263 /// initializeExecutionEnvironment - This method is used to set up the 264 /// environment for executing LLVM programs. 265 /// 266 Error initializeExecutionEnvironment(); 267 }; 268 269 struct DiscardTemp { 270 sys::fs::TempFile &File; 271 ~DiscardTemp(); 272 }; 273 274 /// Given a bitcode or assembly input filename, parse and return it, or return 275 /// null if not possible. 276 /// 277 std::unique_ptr<Module> parseInputFile(StringRef InputFilename, 278 LLVMContext &ctxt); 279 280 /// getPassesString - Turn a list of passes into a string which indicates the 281 /// command line options that must be passed to add the passes. 282 /// 283 std::string getPassesString(const std::vector<std::string> &Passes); 284 285 /// PrintFunctionList - prints out list of problematic functions 286 /// 287 void PrintFunctionList(const std::vector<Function *> &Funcs); 288 289 /// PrintGlobalVariableList - prints out list of problematic global variables 290 /// 291 void PrintGlobalVariableList(const std::vector<GlobalVariable *> &GVs); 292 293 // DeleteGlobalInitializer - "Remove" the global variable by deleting its 294 // initializer, making it external. 295 // 296 void DeleteGlobalInitializer(GlobalVariable *GV); 297 298 // DeleteFunctionBody - "Remove" the function by deleting all of it's basic 299 // blocks, making it external. 300 // 301 void DeleteFunctionBody(Function *F); 302 303 /// Given a module and a list of functions in the module, split the functions 304 /// OUT of the specified module, and place them in the new module. 305 std::unique_ptr<Module> 306 SplitFunctionsOutOfModule(Module *M, const std::vector<Function *> &F, 307 ValueToValueMapTy &VMap); 308 309 } // End llvm namespace 310 311 #endif 312