xref: /freebsd-src/contrib/llvm-project/llvm/tools/bugpoint/ToolRunner.h (revision 06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e)
10b57cec5SDimitry Andric //===-- tools/bugpoint/ToolRunner.h -----------------------------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file exposes an abstraction around a platform C compiler, used to
100b57cec5SDimitry Andric // compile C and assembly code.  It also exposes an "AbstractIntepreter"
110b57cec5SDimitry Andric // interface, which is used to execute code using one of the LLVM execution
120b57cec5SDimitry Andric // engines.
130b57cec5SDimitry Andric //
140b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
150b57cec5SDimitry Andric 
160b57cec5SDimitry Andric #ifndef LLVM_TOOLS_BUGPOINT_TOOLRUNNER_H
170b57cec5SDimitry Andric #define LLVM_TOOLS_BUGPOINT_TOOLRUNNER_H
180b57cec5SDimitry Andric 
190b57cec5SDimitry Andric #include "llvm/Support/CommandLine.h"
200b57cec5SDimitry Andric #include "llvm/Support/Error.h"
210b57cec5SDimitry Andric #include "llvm/Support/Path.h"
220b57cec5SDimitry Andric #include "llvm/Support/SystemUtils.h"
23*06c3fb27SDimitry Andric #include "llvm/TargetParser/Triple.h"
240b57cec5SDimitry Andric #include <exception>
250b57cec5SDimitry Andric #include <vector>
260b57cec5SDimitry Andric 
270b57cec5SDimitry Andric namespace llvm {
280b57cec5SDimitry Andric 
290b57cec5SDimitry Andric extern cl::opt<bool> SaveTemps;
300b57cec5SDimitry Andric extern Triple TargetTriple;
310b57cec5SDimitry Andric 
320b57cec5SDimitry Andric class LLC;
330b57cec5SDimitry Andric 
340b57cec5SDimitry Andric //===---------------------------------------------------------------------===//
350b57cec5SDimitry Andric // CC abstraction
360b57cec5SDimitry Andric //
370b57cec5SDimitry Andric class CC {
380b57cec5SDimitry Andric   std::string CCPath;              // The path to the cc executable.
390b57cec5SDimitry Andric   std::string RemoteClientPath;    // The path to the rsh / ssh executable.
400b57cec5SDimitry Andric   std::vector<std::string> ccArgs; // CC-specific arguments.
CC(StringRef ccPath,StringRef RemotePath,const std::vector<std::string> * CCArgs)410b57cec5SDimitry Andric   CC(StringRef ccPath, StringRef RemotePath,
420b57cec5SDimitry Andric      const std::vector<std::string> *CCArgs)
435ffd83dbSDimitry Andric       : CCPath(std::string(ccPath)), RemoteClientPath(std::string(RemotePath)) {
440b57cec5SDimitry Andric     if (CCArgs)
450b57cec5SDimitry Andric       ccArgs = *CCArgs;
460b57cec5SDimitry Andric   }
470b57cec5SDimitry Andric 
480b57cec5SDimitry Andric public:
490b57cec5SDimitry Andric   enum FileType { AsmFile, ObjectFile, CFile };
500b57cec5SDimitry Andric 
510b57cec5SDimitry Andric   static CC *create(const char *Argv0, std::string &Message,
520b57cec5SDimitry Andric                     const std::string &CCBinary,
530b57cec5SDimitry Andric                     const std::vector<std::string> *Args);
540b57cec5SDimitry Andric 
550b57cec5SDimitry Andric   /// ExecuteProgram - Execute the program specified by "ProgramFile" (which is
560b57cec5SDimitry Andric   /// either a .s file, or a .c file, specified by FileType), with the specified
570b57cec5SDimitry Andric   /// arguments.  Standard input is specified with InputFile, and standard
580b57cec5SDimitry Andric   /// Output is captured to the specified OutputFile location.  The SharedLibs
590b57cec5SDimitry Andric   /// option specifies optional native shared objects that can be loaded into
600b57cec5SDimitry Andric   /// the program for execution.
610b57cec5SDimitry Andric   ///
620b57cec5SDimitry Andric   Expected<int> ExecuteProgram(
630b57cec5SDimitry Andric       const std::string &ProgramFile, const std::vector<std::string> &Args,
640b57cec5SDimitry Andric       FileType fileType, const std::string &InputFile,
650b57cec5SDimitry Andric       const std::string &OutputFile,
660b57cec5SDimitry Andric       const std::vector<std::string> &CCArgs = std::vector<std::string>(),
670b57cec5SDimitry Andric       unsigned Timeout = 0, unsigned MemoryLimit = 0);
680b57cec5SDimitry Andric 
690b57cec5SDimitry Andric   /// MakeSharedObject - This compiles the specified file (which is either a .c
700b57cec5SDimitry Andric   /// file or a .s file) into a shared object.
710b57cec5SDimitry Andric   ///
720b57cec5SDimitry Andric   Error MakeSharedObject(const std::string &InputFile, FileType fileType,
730b57cec5SDimitry Andric                          std::string &OutputFile,
740b57cec5SDimitry Andric                          const std::vector<std::string> &ArgsForCC);
750b57cec5SDimitry Andric };
760b57cec5SDimitry Andric 
770b57cec5SDimitry Andric //===---------------------------------------------------------------------===//
780b57cec5SDimitry Andric /// AbstractInterpreter Class - Subclasses of this class are used to execute
790b57cec5SDimitry Andric /// LLVM bitcode in a variety of ways.  This abstract interface hides this
800b57cec5SDimitry Andric /// complexity behind a simple interface.
810b57cec5SDimitry Andric ///
820b57cec5SDimitry Andric class AbstractInterpreter {
830b57cec5SDimitry Andric   virtual void anchor();
840b57cec5SDimitry Andric 
850b57cec5SDimitry Andric public:
860b57cec5SDimitry Andric   static LLC *createLLC(const char *Argv0, std::string &Message,
870b57cec5SDimitry Andric                         const std::string &CCBinary,
880b57cec5SDimitry Andric                         const std::vector<std::string> *Args = nullptr,
890b57cec5SDimitry Andric                         const std::vector<std::string> *CCArgs = nullptr,
900b57cec5SDimitry Andric                         bool UseIntegratedAssembler = false);
910b57cec5SDimitry Andric 
920b57cec5SDimitry Andric   static AbstractInterpreter *
930b57cec5SDimitry Andric   createLLI(const char *Argv0, std::string &Message,
940b57cec5SDimitry Andric             const std::vector<std::string> *Args = nullptr);
950b57cec5SDimitry Andric 
960b57cec5SDimitry Andric   static AbstractInterpreter *
970b57cec5SDimitry Andric   createJIT(const char *Argv0, std::string &Message,
980b57cec5SDimitry Andric             const std::vector<std::string> *Args = nullptr);
990b57cec5SDimitry Andric 
1000b57cec5SDimitry Andric   static AbstractInterpreter *
1010b57cec5SDimitry Andric   createCustomCompiler(const char *Argv0, std::string &Message,
1020b57cec5SDimitry Andric                        const std::string &CompileCommandLine);
1030b57cec5SDimitry Andric 
1040b57cec5SDimitry Andric   static AbstractInterpreter *
1050b57cec5SDimitry Andric   createCustomExecutor(const char *Argv0, std::string &Message,
1060b57cec5SDimitry Andric                        const std::string &ExecCommandLine);
1070b57cec5SDimitry Andric 
~AbstractInterpreter()1080b57cec5SDimitry Andric   virtual ~AbstractInterpreter() {}
1090b57cec5SDimitry Andric 
1100b57cec5SDimitry Andric   /// compileProgram - Compile the specified program from bitcode to executable
1110b57cec5SDimitry Andric   /// code.  This does not produce any output, it is only used when debugging
1120b57cec5SDimitry Andric   /// the code generator.  It returns false if the code generator fails.
1130b57cec5SDimitry Andric   virtual Error compileProgram(const std::string &Bitcode, unsigned Timeout = 0,
1140b57cec5SDimitry Andric                                unsigned MemoryLimit = 0) {
1150b57cec5SDimitry Andric     return Error::success();
1160b57cec5SDimitry Andric   }
1170b57cec5SDimitry Andric 
1180b57cec5SDimitry Andric   /// Compile the specified program from bitcode to code understood by the CC
1190b57cec5SDimitry Andric   /// driver (either C or asm).  Returns an error if the code generator fails,,
1200b57cec5SDimitry Andric   /// otherwise, the type of code emitted.
1210b57cec5SDimitry Andric   virtual Expected<CC::FileType> OutputCode(const std::string &Bitcode,
1220b57cec5SDimitry Andric                                             std::string &OutFile,
1230b57cec5SDimitry Andric                                             unsigned Timeout = 0,
1240b57cec5SDimitry Andric                                             unsigned MemoryLimit = 0) {
1250b57cec5SDimitry Andric     return make_error<StringError>(
1260b57cec5SDimitry Andric         "OutputCode not supported by this AbstractInterpreter!",
1270b57cec5SDimitry Andric         inconvertibleErrorCode());
1280b57cec5SDimitry Andric   }
1290b57cec5SDimitry Andric 
1300b57cec5SDimitry Andric   /// ExecuteProgram - Run the specified bitcode file, emitting output to the
1310b57cec5SDimitry Andric   /// specified filename.  This sets RetVal to the exit code of the program or
1320b57cec5SDimitry Andric   /// returns an Error if a problem was encountered that prevented execution of
1330b57cec5SDimitry Andric   /// the program.
1340b57cec5SDimitry Andric   ///
1350b57cec5SDimitry Andric   virtual Expected<int> ExecuteProgram(
1360b57cec5SDimitry Andric       const std::string &Bitcode, const std::vector<std::string> &Args,
1370b57cec5SDimitry Andric       const std::string &InputFile, const std::string &OutputFile,
1380b57cec5SDimitry Andric       const std::vector<std::string> &CCArgs = std::vector<std::string>(),
1390b57cec5SDimitry Andric       const std::vector<std::string> &SharedLibs = std::vector<std::string>(),
1400b57cec5SDimitry Andric       unsigned Timeout = 0, unsigned MemoryLimit = 0) = 0;
1410b57cec5SDimitry Andric };
1420b57cec5SDimitry Andric 
1430b57cec5SDimitry Andric //===---------------------------------------------------------------------===//
1440b57cec5SDimitry Andric // LLC Implementation of AbstractIntepreter interface
1450b57cec5SDimitry Andric //
1460b57cec5SDimitry Andric class LLC : public AbstractInterpreter {
1470b57cec5SDimitry Andric   std::string LLCPath;               // The path to the LLC executable.
1480b57cec5SDimitry Andric   std::vector<std::string> ToolArgs; // Extra args to pass to LLC.
1490b57cec5SDimitry Andric   CC *cc;
1500b57cec5SDimitry Andric   bool UseIntegratedAssembler;
1510b57cec5SDimitry Andric 
1520b57cec5SDimitry Andric public:
LLC(const std::string & llcPath,CC * cc,const std::vector<std::string> * Args,bool useIntegratedAssembler)1530b57cec5SDimitry Andric   LLC(const std::string &llcPath, CC *cc, const std::vector<std::string> *Args,
1540b57cec5SDimitry Andric       bool useIntegratedAssembler)
1550b57cec5SDimitry Andric       : LLCPath(llcPath), cc(cc),
1560b57cec5SDimitry Andric         UseIntegratedAssembler(useIntegratedAssembler) {
1570b57cec5SDimitry Andric     ToolArgs.clear();
1580b57cec5SDimitry Andric     if (Args)
1590b57cec5SDimitry Andric       ToolArgs = *Args;
1600b57cec5SDimitry Andric   }
~LLC()1610b57cec5SDimitry Andric   ~LLC() override { delete cc; }
1620b57cec5SDimitry Andric 
1630b57cec5SDimitry Andric   /// compileProgram - Compile the specified program from bitcode to executable
1640b57cec5SDimitry Andric   /// code.  This does not produce any output, it is only used when debugging
1650b57cec5SDimitry Andric   /// the code generator.  Returns false if the code generator fails.
1660b57cec5SDimitry Andric   Error compileProgram(const std::string &Bitcode, unsigned Timeout = 0,
1670b57cec5SDimitry Andric                        unsigned MemoryLimit = 0) override;
1680b57cec5SDimitry Andric 
1690b57cec5SDimitry Andric   Expected<int> ExecuteProgram(
1700b57cec5SDimitry Andric       const std::string &Bitcode, const std::vector<std::string> &Args,
1710b57cec5SDimitry Andric       const std::string &InputFile, const std::string &OutputFile,
1720b57cec5SDimitry Andric       const std::vector<std::string> &CCArgs = std::vector<std::string>(),
1730b57cec5SDimitry Andric       const std::vector<std::string> &SharedLibs = std::vector<std::string>(),
1740b57cec5SDimitry Andric       unsigned Timeout = 0, unsigned MemoryLimit = 0) override;
1750b57cec5SDimitry Andric 
1760b57cec5SDimitry Andric   Expected<CC::FileType> OutputCode(const std::string &Bitcode,
1770b57cec5SDimitry Andric                                     std::string &OutFile, unsigned Timeout = 0,
1780b57cec5SDimitry Andric                                     unsigned MemoryLimit = 0) override;
1790b57cec5SDimitry Andric };
1800b57cec5SDimitry Andric 
1810b57cec5SDimitry Andric /// Find the first executable file \ExeName, either in the user's PATH or,
1820b57cec5SDimitry Andric /// failing that, in the same directory as argv[0]. This allows us to find
1830b57cec5SDimitry Andric /// another LLVM tool if it is built in the same directory. If no executable is
1840b57cec5SDimitry Andric /// found, an error is returned.
1850b57cec5SDimitry Andric ErrorOr<std::string> FindProgramByName(const std::string &ExeName,
1860b57cec5SDimitry Andric                                        const char *Argv0, void *MainAddr);
1870b57cec5SDimitry Andric 
1880b57cec5SDimitry Andric } // End llvm namespace
1890b57cec5SDimitry Andric 
1900b57cec5SDimitry Andric #endif
191