llvm/llvm/tools/bugpoint/ToolRunner.cpp

//===-- ToolRunner.cpp ----------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file implements the interfaces described in the ToolRunner.h file.
//
//===----------------------------------------------------------------------===//

#include "ToolRunner.h"
#include "llvm/Config/config.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/FileUtilities.h"
#include "llvm/Support/Program.h"
#include "llvm/Support/raw_ostream.h"
#include <fstream>
#include <sstream>
#include <utility>
usingnamespacellvm;

#define DEBUG_TYPE

namespace llvm {
cl::opt<bool> SaveTemps("save-temps", cl::init(false),
                        cl::desc("Save temporary files"));
}

namespace {
cl::opt<std::string>
    RemoteClient("remote-client",
                 cl::desc("Remote execution client (rsh/ssh)"));

cl::opt<std::string> RemoteHost("remote-host",
                                cl::desc("Remote execution (rsh/ssh) host"));

cl::opt<std::string> RemotePort("remote-port",
                                cl::desc("Remote execution (rsh/ssh) port"));

cl::opt<std::string> RemoteUser("remote-user",
                                cl::desc("Remote execution (rsh/ssh) user id"));

cl::opt<std::string>
    RemoteExtra("remote-extra-options",
                cl::desc("Remote execution (rsh/ssh) extra options"));
}

/// RunProgramWithTimeout - This function provides an alternate interface
/// to the sys::Program::ExecuteAndWait interface.
/// @see sys::Program::ExecuteAndWait
static int RunProgramWithTimeout(StringRef ProgramPath,
                                 ArrayRef<StringRef> Args, StringRef StdInFile,
                                 StringRef StdOutFile, StringRef StdErrFile,
                                 unsigned NumSeconds = 0,
                                 unsigned MemoryLimit = 0,
                                 std::string *ErrMsg = nullptr) {}

/// RunProgramRemotelyWithTimeout - This function runs the given program
/// remotely using the given remote client and the sys::Program::ExecuteAndWait.
/// Returns the remote program exit code or reports a remote client error if it
/// fails. Remote client is required to return 255 if it failed or program exit
/// code otherwise.
/// @see sys::Program::ExecuteAndWait
static int RunProgramRemotelyWithTimeout(
    StringRef RemoteClientPath, ArrayRef<StringRef> Args, StringRef StdInFile,
    StringRef StdOutFile, StringRef StdErrFile, unsigned NumSeconds = 0,
    unsigned MemoryLimit = 0) {}

static Error ProcessFailure(StringRef ProgPath, ArrayRef<StringRef> Args,
                            unsigned Timeout = 0, unsigned MemoryLimit = 0) {}

//===---------------------------------------------------------------------===//
// LLI Implementation of AbstractIntepreter interface
//
namespace {
class LLI : public AbstractInterpreter {};
}

Expected<int> LLI::ExecuteProgram(const std::string &Bitcode,
                                  const std::vector<std::string> &Args,
                                  const std::string &InputFile,
                                  const std::string &OutputFile,
                                  const std::vector<std::string> &CCArgs,
                                  const std::vector<std::string> &SharedLibs,
                                  unsigned Timeout, unsigned MemoryLimit) {}

void AbstractInterpreter::anchor() {}

ErrorOr<std::string> llvm::FindProgramByName(const std::string &ExeName,
                                             const char *Argv0,
                                             void *MainAddr) {}

// LLI create method - Try to find the LLI executable
AbstractInterpreter *
AbstractInterpreter::createLLI(const char *Argv0, std::string &Message,
                               const std::vector<std::string> *ToolArgs) {}

//===---------------------------------------------------------------------===//
// Custom compiler command implementation of AbstractIntepreter interface
//
// Allows using a custom command for compiling the bitcode, thus allows, for
// example, to compile a bitcode fragment without linking or executing, then
// using a custom wrapper script to check for compiler errors.
namespace {
class CustomCompiler : public AbstractInterpreter {};
}

Error CustomCompiler::compileProgram(const std::string &Bitcode,
                                     unsigned Timeout, unsigned MemoryLimit) {}

//===---------------------------------------------------------------------===//
// Custom execution command implementation of AbstractIntepreter interface
//
// Allows using a custom command for executing the bitcode, thus allows,
// for example, to invoke a cross compiler for code generation followed by
// a simulator that executes the generated binary.
namespace {
class CustomExecutor : public AbstractInterpreter {};
}

Expected<int> CustomExecutor::ExecuteProgram(
    const std::string &Bitcode, const std::vector<std::string> &Args,
    const std::string &InputFile, const std::string &OutputFile,
    const std::vector<std::string> &CCArgs,
    const std::vector<std::string> &SharedLibs, unsigned Timeout,
    unsigned MemoryLimit) {}

// Tokenize the CommandLine to the command and the args to allow
// defining a full command line as the command instead of just the
// executed program. We cannot just pass the whole string after the command
// as a single argument because then the program sees only a single
// command line argument (with spaces in it: "foo bar" instead
// of "foo" and "bar").
//
// Spaces are used as a delimiter; however repeated, leading, and trailing
// whitespace are ignored. Simple escaping is allowed via the '\'
// character, as seen below:
//
// Two consecutive '\' evaluate to a single '\'.
// A space after a '\' evaluates to a space that is not interpreted as a
// delimiter.
// Any other instances of the '\' character are removed.
//
// Example:
// '\\' -> '\'
// '\ ' -> ' '
// 'exa\mple' -> 'example'
//
static void lexCommand(const char *Argv0, std::string &Message,
                       const std::string &CommandLine, std::string &CmdPath,
                       std::vector<std::string> &Args) {}

// Custom execution environment create method, takes the execution command
// as arguments
AbstractInterpreter *AbstractInterpreter::createCustomCompiler(
    const char *Argv0, std::string &Message,
    const std::string &CompileCommandLine) {}

// Custom execution environment create method, takes the execution command
// as arguments
AbstractInterpreter *
AbstractInterpreter::createCustomExecutor(const char *Argv0,
                                          std::string &Message,
                                          const std::string &ExecCommandLine) {}

//===----------------------------------------------------------------------===//
// LLC Implementation of AbstractIntepreter interface
//
Expected<CC::FileType> LLC::OutputCode(const std::string &Bitcode,
                                       std::string &OutputAsmFile,
                                       unsigned Timeout, unsigned MemoryLimit) {}

Error LLC::compileProgram(const std::string &Bitcode, unsigned Timeout,
                          unsigned MemoryLimit) {}

Expected<int> LLC::ExecuteProgram(const std::string &Bitcode,
                                  const std::vector<std::string> &Args,
                                  const std::string &InputFile,
                                  const std::string &OutputFile,
                                  const std::vector<std::string> &ArgsForCC,
                                  const std::vector<std::string> &SharedLibs,
                                  unsigned Timeout, unsigned MemoryLimit) {}

/// createLLC - Try to find the LLC executable
///
LLC *AbstractInterpreter::createLLC(const char *Argv0, std::string &Message,
                                    const std::string &CCBinary,
                                    const std::vector<std::string> *Args,
                                    const std::vector<std::string> *CCArgs,
                                    bool UseIntegratedAssembler) {}

//===---------------------------------------------------------------------===//
// JIT Implementation of AbstractIntepreter interface
//
namespace {
class JIT : public AbstractInterpreter {};
}

Expected<int> JIT::ExecuteProgram(const std::string &Bitcode,
                                  const std::vector<std::string> &Args,
                                  const std::string &InputFile,
                                  const std::string &OutputFile,
                                  const std::vector<std::string> &CCArgs,
                                  const std::vector<std::string> &SharedLibs,
                                  unsigned Timeout, unsigned MemoryLimit) {}

/// createJIT - Try to find the LLI executable
///
AbstractInterpreter *
AbstractInterpreter::createJIT(const char *Argv0, std::string &Message,
                               const std::vector<std::string> *Args) {}

//===---------------------------------------------------------------------===//
// CC abstraction
//

static bool IsARMArchitecture(std::vector<StringRef> Args) {}

Expected<int> CC::ExecuteProgram(const std::string &ProgramFile,
                                 const std::vector<std::string> &Args,
                                 FileType fileType,
                                 const std::string &InputFile,
                                 const std::string &OutputFile,
                                 const std::vector<std::string> &ArgsForCC,
                                 unsigned Timeout, unsigned MemoryLimit) {}

Error CC::MakeSharedObject(const std::string &InputFile, FileType fileType,
                           std::string &OutputFile,
                           const std::vector<std::string> &ArgsForCC) {}

/// create - Try to find the CC executable
///
CC *CC::create(const char *Argv0, std::string &Message,
               const std::string &CCBinary,
               const std::vector<std::string> *Args) {}