Home | History | Annotate | Download | only in bugpoint
      1 //===-- tools/bugpoint/ToolRunner.h -----------------------------*- 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 file exposes an abstraction around a platform C compiler, used to
     11 // compile C and assembly code.  It also exposes an "AbstractIntepreter"
     12 // interface, which is used to execute code using one of the LLVM execution
     13 // engines.
     14 //
     15 //===----------------------------------------------------------------------===//
     16 
     17 #ifndef BUGPOINT_TOOLRUNNER_H
     18 #define BUGPOINT_TOOLRUNNER_H
     19 
     20 #include "llvm/ADT/Triple.h"
     21 #include "llvm/Support/CommandLine.h"
     22 #include "llvm/Support/ErrorHandling.h"
     23 #include "llvm/Support/Path.h"
     24 #include "llvm/Support/SystemUtils.h"
     25 #include <exception>
     26 #include <vector>
     27 
     28 namespace llvm {
     29 
     30 extern cl::opt<bool> SaveTemps;
     31 extern Triple TargetTriple;
     32 
     33 class LLC;
     34 
     35 //===---------------------------------------------------------------------===//
     36 // GCC abstraction
     37 //
     38 class GCC {
     39   std::string GCCPath;                // The path to the gcc executable.
     40   std::string RemoteClientPath;       // The path to the rsh / ssh executable.
     41   std::vector<std::string> gccArgs; // GCC-specific arguments.
     42   GCC(StringRef gccPath, StringRef RemotePath,
     43       const std::vector<std::string> *GCCArgs)
     44     : GCCPath(gccPath), RemoteClientPath(RemotePath) {
     45     if (GCCArgs) gccArgs = *GCCArgs;
     46   }
     47 public:
     48   enum FileType { AsmFile, ObjectFile, CFile };
     49 
     50   static GCC *create(std::string &Message,
     51                      const std::string &GCCBinary,
     52                      const std::vector<std::string> *Args);
     53 
     54   /// ExecuteProgram - Execute the program specified by "ProgramFile" (which is
     55   /// either a .s file, or a .c file, specified by FileType), with the specified
     56   /// arguments.  Standard input is specified with InputFile, and standard
     57   /// Output is captured to the specified OutputFile location.  The SharedLibs
     58   /// option specifies optional native shared objects that can be loaded into
     59   /// the program for execution.
     60   ///
     61   int ExecuteProgram(const std::string &ProgramFile,
     62                      const std::vector<std::string> &Args,
     63                      FileType fileType,
     64                      const std::string &InputFile,
     65                      const std::string &OutputFile,
     66                      std::string *Error = nullptr,
     67                      const std::vector<std::string> &GCCArgs =
     68                          std::vector<std::string>(),
     69                      unsigned Timeout = 0,
     70                      unsigned MemoryLimit = 0);
     71 
     72   /// MakeSharedObject - This compiles the specified file (which is either a .c
     73   /// file or a .s file) into a shared object.
     74   ///
     75   int MakeSharedObject(const std::string &InputFile, FileType fileType,
     76                        std::string &OutputFile,
     77                        const std::vector<std::string> &ArgsForGCC,
     78                        std::string &Error);
     79 };
     80 
     81 
     82 //===---------------------------------------------------------------------===//
     83 /// AbstractInterpreter Class - Subclasses of this class are used to execute
     84 /// LLVM bitcode in a variety of ways.  This abstract interface hides this
     85 /// complexity behind a simple interface.
     86 ///
     87 class AbstractInterpreter {
     88   virtual void anchor();
     89 public:
     90   static LLC *createLLC(const char *Argv0, std::string &Message,
     91                         const std::string              &GCCBinary,
     92                         const std::vector<std::string> *Args = nullptr,
     93                         const std::vector<std::string> *GCCArgs = nullptr,
     94                         bool UseIntegratedAssembler = false);
     95 
     96   static AbstractInterpreter*
     97   createLLI(const char *Argv0, std::string &Message,
     98             const std::vector<std::string> *Args = nullptr);
     99 
    100   static AbstractInterpreter*
    101   createJIT(const char *Argv0, std::string &Message,
    102             const std::vector<std::string> *Args = nullptr);
    103 
    104   static AbstractInterpreter*
    105   createCustomCompiler(std::string &Message,
    106                        const std::string &CompileCommandLine);
    107 
    108   static AbstractInterpreter*
    109   createCustomExecutor(std::string &Message,
    110                        const std::string &ExecCommandLine);
    111 
    112 
    113   virtual ~AbstractInterpreter() {}
    114 
    115   /// compileProgram - Compile the specified program from bitcode to executable
    116   /// code.  This does not produce any output, it is only used when debugging
    117   /// the code generator.  It returns false if the code generator fails.
    118   virtual void compileProgram(const std::string &Bitcode, std::string *Error,
    119                               unsigned Timeout = 0, unsigned MemoryLimit = 0) {}
    120 
    121   /// OutputCode - Compile the specified program from bitcode to code
    122   /// understood by the GCC driver (either C or asm).  If the code generator
    123   /// fails, it sets Error, otherwise, this function returns the type of code
    124   /// emitted.
    125   virtual GCC::FileType OutputCode(const std::string &Bitcode,
    126                                    std::string &OutFile, std::string &Error,
    127                                    unsigned Timeout = 0,
    128                                    unsigned MemoryLimit = 0) {
    129     Error = "OutputCode not supported by this AbstractInterpreter!";
    130     return GCC::AsmFile;
    131   }
    132 
    133   /// ExecuteProgram - Run the specified bitcode file, emitting output to the
    134   /// specified filename.  This sets RetVal to the exit code of the program or
    135   /// returns false if a problem was encountered that prevented execution of
    136   /// the program.
    137   ///
    138   virtual int ExecuteProgram(const std::string &Bitcode,
    139                              const std::vector<std::string> &Args,
    140                              const std::string &InputFile,
    141                              const std::string &OutputFile,
    142                              std::string *Error,
    143                              const std::vector<std::string> &GCCArgs =
    144                                std::vector<std::string>(),
    145                              const std::vector<std::string> &SharedLibs =
    146                                std::vector<std::string>(),
    147                              unsigned Timeout = 0,
    148                              unsigned MemoryLimit = 0) = 0;
    149 };
    150 
    151 //===---------------------------------------------------------------------===//
    152 // LLC Implementation of AbstractIntepreter interface
    153 //
    154 class LLC : public AbstractInterpreter {
    155   std::string LLCPath;               // The path to the LLC executable.
    156   std::vector<std::string> ToolArgs; // Extra args to pass to LLC.
    157   GCC *gcc;
    158   bool UseIntegratedAssembler;
    159 public:
    160   LLC(const std::string &llcPath, GCC *Gcc,
    161       const std::vector<std::string> *Args,
    162       bool useIntegratedAssembler)
    163     : LLCPath(llcPath), gcc(Gcc),
    164       UseIntegratedAssembler(useIntegratedAssembler) {
    165     ToolArgs.clear();
    166     if (Args) ToolArgs = *Args;
    167   }
    168   ~LLC() { delete gcc; }
    169 
    170   /// compileProgram - Compile the specified program from bitcode to executable
    171   /// code.  This does not produce any output, it is only used when debugging
    172   /// the code generator.  Returns false if the code generator fails.
    173   void compileProgram(const std::string &Bitcode, std::string *Error,
    174                       unsigned Timeout = 0, unsigned MemoryLimit = 0) override;
    175 
    176   int ExecuteProgram(const std::string &Bitcode,
    177                      const std::vector<std::string> &Args,
    178                      const std::string &InputFile,
    179                      const std::string &OutputFile,
    180                      std::string *Error,
    181                      const std::vector<std::string> &GCCArgs =
    182                        std::vector<std::string>(),
    183                      const std::vector<std::string> &SharedLibs =
    184                         std::vector<std::string>(),
    185                      unsigned Timeout = 0,
    186                      unsigned MemoryLimit = 0) override;
    187 
    188   /// OutputCode - Compile the specified program from bitcode to code
    189   /// understood by the GCC driver (either C or asm).  If the code generator
    190   /// fails, it sets Error, otherwise, this function returns the type of code
    191   /// emitted.
    192   GCC::FileType OutputCode(const std::string &Bitcode,
    193                            std::string &OutFile, std::string &Error,
    194                            unsigned Timeout = 0,
    195                            unsigned MemoryLimit = 0) override;
    196 };
    197 
    198 } // End llvm namespace
    199 
    200 #endif
    201