Path: blob/main/contrib/llvm-project/llvm/tools/bugpoint/BugDriver.h
35230 views
//===- BugDriver.h - Top-Level BugPoint class -------------------*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This class contains all of the shared state and information that is used by9// the BugPoint tool to track down errors in optimizations. This class is the10// main driver class that invokes all sub-functionality.11//12//===----------------------------------------------------------------------===//1314#ifndef LLVM_TOOLS_BUGPOINT_BUGDRIVER_H15#define LLVM_TOOLS_BUGPOINT_BUGDRIVER_H1617#include "llvm/IR/ValueMap.h"18#include "llvm/Support/Error.h"19#include "llvm/Support/FileSystem.h"20#include "llvm/Transforms/Utils/ValueMapper.h"21#include <memory>22#include <string>23#include <vector>2425namespace llvm {2627class Module;28class GlobalVariable;29class Function;30class BasicBlock;31class AbstractInterpreter;32class Instruction;33class LLVMContext;3435class CC;3637extern bool DisableSimplifyCFG;3839/// BugpointIsInterrupted - Set to true when the user presses ctrl-c.40///41extern bool BugpointIsInterrupted;4243class BugDriver {44LLVMContext &Context;45const char *ToolName; // argv[0] of bugpoint46std::string ReferenceOutputFile; // Name of `good' output file47std::unique_ptr<Module> Program; // The raw program, linked together48std::vector<std::string> PassesToRun;49AbstractInterpreter *Interpreter; // How to run the program50AbstractInterpreter *SafeInterpreter; // To generate reference output, etc.51CC *cc;52bool run_find_bugs;53unsigned Timeout;54unsigned MemoryLimit;55bool UseValgrind;5657// FIXME: sort out public/private distinctions...58friend class ReducePassList;59friend class ReduceMisCodegenFunctions;6061public:62BugDriver(const char *toolname, bool find_bugs, unsigned timeout,63unsigned memlimit, bool use_valgrind, LLVMContext &ctxt);64~BugDriver();6566const char *getToolName() const { return ToolName; }6768LLVMContext &getContext() const { return Context; }6970// Set up methods... these methods are used to copy information about the71// command line arguments into instance variables of BugDriver.72//73bool addSources(const std::vector<std::string> &FileNames);74void addPass(std::string p) { PassesToRun.push_back(std::move(p)); }75void setPassesToRun(const std::vector<std::string> &PTR) {76PassesToRun = PTR;77}78const std::vector<std::string> &getPassesToRun() const { return PassesToRun; }7980/// run - The top level method that is invoked after all of the instance81/// variables are set up from command line arguments. The \p as_child argument82/// indicates whether the driver is to run in parent mode or child mode.83///84Error run();8586/// debugOptimizerCrash - This method is called when some optimizer pass87/// crashes on input. It attempts to prune down the testcase to something88/// reasonable, and figure out exactly which pass is crashing.89///90Error debugOptimizerCrash(const std::string &ID = "passes");9192/// debugCodeGeneratorCrash - This method is called when the code generator93/// crashes on an input. It attempts to reduce the input as much as possible94/// while still causing the code generator to crash.95Error debugCodeGeneratorCrash();9697/// debugMiscompilation - This method is used when the passes selected are not98/// crashing, but the generated output is semantically different from the99/// input.100Error debugMiscompilation();101102/// compileSharedObject - This method creates a SharedObject from a given103/// BitcodeFile for debugging a code generator.104///105Expected<std::string> compileSharedObject(const std::string &BitcodeFile);106107/// debugCodeGenerator - This method narrows down a module to a function or108/// set of functions, using the CBE as a ``safe'' code generator for other109/// functions that are not under consideration.110Error debugCodeGenerator();111112/// isExecutingJIT - Returns true if bugpoint is currently testing the JIT113///114bool isExecutingJIT();115116Module &getProgram() const { return *Program; }117118/// Set the current module to the specified module, returning the old one.119std::unique_ptr<Module> swapProgramIn(std::unique_ptr<Module> M);120121AbstractInterpreter *switchToSafeInterpreter() {122AbstractInterpreter *Old = Interpreter;123Interpreter = (AbstractInterpreter *)SafeInterpreter;124return Old;125}126127void switchToInterpreter(AbstractInterpreter *AI) { Interpreter = AI; }128129/// If we reduce or update the program somehow, call this method to update130/// bugdriver with it. This deletes the old module and sets the specified one131/// as the current program.132void setNewProgram(std::unique_ptr<Module> M);133134/// Try to compile the specified module. This is used for code generation135/// crash testing.136Error compileProgram(Module &M) const;137138/// This method runs "Program", capturing the output of the program to a file.139/// A recommended filename may be optionally specified.140Expected<std::string> executeProgram(const Module &Program,141std::string OutputFilename,142std::string Bitcode,143const std::string &SharedObjects,144AbstractInterpreter *AI) const;145146/// Used to create reference output with the "safe" backend, if reference147/// output is not provided. If there is a problem with the code generator148/// (e.g., llc crashes), this will return false and set Error.149Expected<std::string>150executeProgramSafely(const Module &Program,151const std::string &OutputFile) const;152153/// Calls compileProgram and then records the output into ReferenceOutputFile.154/// Returns true if reference file created, false otherwise. Note:155/// initializeExecutionEnvironment should be called BEFORE this function.156Error createReferenceFile(Module &M, const std::string &Filename =157"bugpoint.reference.out-%%%%%%%");158159/// This method executes the specified module and diffs the output against the160/// file specified by ReferenceOutputFile. If the output is different, 1 is161/// returned. If there is a problem with the code generator (e.g., llc162/// crashes), this will return -1 and set Error.163Expected<bool> diffProgram(const Module &Program,164const std::string &BitcodeFile = "",165const std::string &SharedObj = "",166bool RemoveBitcode = false) const;167168/// This function is used to output M to a file named "bugpoint-ID.bc".169void EmitProgressBitcode(const Module &M, const std::string &ID,170bool NoFlyer = false) const;171172/// This method clones the current Program and deletes the specified173/// instruction from the cloned module. It then runs a series of cleanup174/// passes (ADCE and SimplifyCFG) to eliminate any code which depends on the175/// value. The modified module is then returned.176///177std::unique_ptr<Module> deleteInstructionFromProgram(const Instruction *I,178unsigned Simp);179180/// This method clones the current Program and performs a series of cleanups181/// intended to get rid of extra cruft on the module. If the182/// MayModifySemantics argument is true, then the cleanups is allowed to183/// modify how the code behaves.184///185std::unique_ptr<Module> performFinalCleanups(std::unique_ptr<Module> M,186bool MayModifySemantics = false);187188/// Given a module, extract up to one loop from it into a new function. This189/// returns null if there are no extractable loops in the program or if the190/// loop extractor crashes.191std::unique_ptr<Module> extractLoop(Module *M);192193/// Extract all but the specified basic blocks into their own functions. The194/// only detail is that M is actually a module cloned from the one the BBs are195/// in, so some mapping needs to be performed. If this operation fails for196/// some reason (ie the implementation is buggy), this function should return197/// null, otherwise it returns a new Module.198std::unique_ptr<Module>199extractMappedBlocksFromModule(const std::vector<BasicBlock *> &BBs,200Module *M);201202/// Carefully run the specified set of pass on the specified/ module,203/// returning the transformed module on success, or a null pointer on failure.204std::unique_ptr<Module> runPassesOn(Module *M,205const std::vector<std::string> &Passes,206ArrayRef<std::string> ExtraArgs = {});207208/// runPasses - Run the specified passes on Program, outputting a bitcode209/// file and writting the filename into OutputFile if successful. If the210/// optimizations fail for some reason (optimizer crashes), return true,211/// otherwise return false. If DeleteOutput is set to true, the bitcode is212/// deleted on success, and the filename string is undefined. This prints to213/// outs() a single line message indicating whether compilation was successful214/// or failed, unless Quiet is set. ExtraArgs specifies additional arguments215/// to pass to the child bugpoint instance.216///217bool runPasses(Module &Program, const std::vector<std::string> &PassesToRun,218std::string &OutputFilename, bool DeleteOutput = false,219bool Quiet = false,220ArrayRef<std::string> ExtraArgs = {}) const;221222/// runPasses - Just like the method above, but this just returns true or223/// false indicating whether or not the optimizer crashed on the specified224/// input (true = crashed). Does not produce any output.225///226bool runPasses(Module &M, const std::vector<std::string> &PassesToRun) const {227std::string Filename;228return runPasses(M, PassesToRun, Filename, true);229}230231/// Take the specified pass list and create different combinations of passes232/// to compile the program with. Compile the program with each set and mark233/// test to see if it compiled correctly. If the passes compiled correctly234/// output nothing and rearrange the passes into a new order. If the passes235/// did not compile correctly, output the command required to recreate the236/// failure.237Error runManyPasses(const std::vector<std::string> &AllPasses);238239/// This writes the current "Program" to the named bitcode file. If an error240/// occurs, true is returned.241bool writeProgramToFile(const std::string &Filename, const Module &M) const;242bool writeProgramToFile(const std::string &Filename, int FD,243const Module &M) const;244bool writeProgramToFile(int FD, const Module &M) const;245246private:247/// initializeExecutionEnvironment - This method is used to set up the248/// environment for executing LLVM programs.249///250Error initializeExecutionEnvironment();251};252253struct DiscardTemp {254sys::fs::TempFile &File;255~DiscardTemp();256};257258/// Given a bitcode or assembly input filename, parse and return it, or return259/// null if not possible.260///261std::unique_ptr<Module> parseInputFile(StringRef InputFilename,262LLVMContext &ctxt);263264/// getPassesString - Turn a list of passes into a string which indicates the265/// command line options that must be passed to add the passes.266///267std::string getPassesString(const std::vector<std::string> &Passes);268269/// PrintFunctionList - prints out list of problematic functions270///271void PrintFunctionList(const std::vector<Function *> &Funcs);272273/// PrintGlobalVariableList - prints out list of problematic global variables274///275void PrintGlobalVariableList(const std::vector<GlobalVariable *> &GVs);276277// DeleteGlobalInitializer - "Remove" the global variable by deleting its278// initializer, making it external.279//280void DeleteGlobalInitializer(GlobalVariable *GV);281282// DeleteFunctionBody - "Remove" the function by deleting all of it's basic283// blocks, making it external.284//285void DeleteFunctionBody(Function *F);286287/// Given a module and a list of functions in the module, split the functions288/// OUT of the specified module, and place them in the new module.289std::unique_ptr<Module>290SplitFunctionsOutOfModule(Module *M, const std::vector<Function *> &F,291ValueToValueMapTy &VMap);292293} // End llvm namespace294295#endif296297298