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