2006-06-07 06:30:59 +08:00
|
|
|
//===-- ToolRunner.cpp ----------------------------------------------------===//
|
|
|
|
//
|
2019-01-19 16:50:56 +08:00
|
|
|
// 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
|
2006-06-07 06:30:59 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// This file implements the interfaces described in the ToolRunner.h file.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "ToolRunner.h"
|
2016-10-01 04:11:21 +08:00
|
|
|
#include "llvm/Config/config.h"
|
2007-05-04 02:36:15 +08:00
|
|
|
#include "llvm/Support/CommandLine.h"
|
2006-06-07 06:30:59 +08:00
|
|
|
#include "llvm/Support/Debug.h"
|
2013-06-19 01:20:08 +08:00
|
|
|
#include "llvm/Support/FileSystem.h"
|
2006-06-07 06:30:59 +08:00
|
|
|
#include "llvm/Support/FileUtilities.h"
|
2012-12-04 18:44:52 +08:00
|
|
|
#include "llvm/Support/Program.h"
|
2009-08-24 06:45:37 +08:00
|
|
|
#include "llvm/Support/raw_ostream.h"
|
2006-06-07 06:30:59 +08:00
|
|
|
#include <fstream>
|
|
|
|
#include <sstream>
|
2016-05-27 22:27:24 +08:00
|
|
|
#include <utility>
|
2006-06-07 06:30:59 +08:00
|
|
|
using namespace llvm;
|
|
|
|
|
2014-04-22 11:10:36 +08:00
|
|
|
#define DEBUG_TYPE "toolrunner"
|
|
|
|
|
2009-08-05 17:32:10 +08:00
|
|
|
namespace llvm {
|
2016-09-02 09:21:37 +08:00
|
|
|
cl::opt<bool> SaveTemps("save-temps", cl::init(false),
|
|
|
|
cl::desc("Save temporary files"));
|
2009-08-05 17:32:10 +08:00
|
|
|
}
|
|
|
|
|
2007-05-04 02:36:15 +08:00
|
|
|
namespace {
|
2016-09-02 09:21:37 +08:00
|
|
|
cl::opt<std::string>
|
|
|
|
RemoteClient("remote-client",
|
|
|
|
cl::desc("Remote execution client (rsh/ssh)"));
|
2007-05-04 02:36:15 +08:00
|
|
|
|
2016-09-02 09:21:37 +08:00
|
|
|
cl::opt<std::string> RemoteHost("remote-host",
|
|
|
|
cl::desc("Remote execution (rsh/ssh) host"));
|
2008-09-09 14:11:26 +08:00
|
|
|
|
2016-09-02 09:21:37 +08:00
|
|
|
cl::opt<std::string> RemotePort("remote-port",
|
|
|
|
cl::desc("Remote execution (rsh/ssh) port"));
|
2009-07-11 05:39:28 +08:00
|
|
|
|
2016-09-02 09:21:37 +08:00
|
|
|
cl::opt<std::string> RemoteUser("remote-user",
|
|
|
|
cl::desc("Remote execution (rsh/ssh) user id"));
|
2008-09-09 14:11:26 +08:00
|
|
|
|
2016-09-02 09:21:37 +08:00
|
|
|
cl::opt<std::string>
|
|
|
|
RemoteExtra("remote-extra-options",
|
|
|
|
cl::desc("Remote execution (rsh/ssh) extra options"));
|
2007-05-04 02:36:15 +08:00
|
|
|
}
|
|
|
|
|
2009-07-19 02:39:24 +08:00
|
|
|
/// RunProgramWithTimeout - This function provides an alternate interface
|
|
|
|
/// to the sys::Program::ExecuteAndWait interface.
|
2010-04-12 13:08:25 +08:00
|
|
|
/// @see sys::Program::ExecuteAndWait
|
2018-06-13 01:43:52 +08:00
|
|
|
static int RunProgramWithTimeout(StringRef ProgramPath,
|
|
|
|
ArrayRef<StringRef> Args, StringRef StdInFile,
|
|
|
|
StringRef StdOutFile, StringRef StdErrFile,
|
|
|
|
unsigned NumSeconds = 0,
|
2010-11-09 09:13:31 +08:00
|
|
|
unsigned MemoryLimit = 0,
|
2014-04-25 12:24:47 +08:00
|
|
|
std::string *ErrMsg = nullptr) {
|
2017-09-14 01:03:37 +08:00
|
|
|
Optional<StringRef> Redirects[3] = {StdInFile, StdOutFile, StdErrFile};
|
2018-06-13 01:43:52 +08:00
|
|
|
return sys::ExecuteAndWait(ProgramPath, Args, None, Redirects, NumSeconds,
|
2016-09-02 09:21:37 +08:00
|
|
|
MemoryLimit, ErrMsg);
|
2006-06-07 06:30:59 +08:00
|
|
|
}
|
|
|
|
|
2009-07-19 02:39:24 +08:00
|
|
|
/// 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.
|
2010-04-12 13:08:25 +08:00
|
|
|
/// @see sys::Program::ExecuteAndWait
|
2018-06-13 01:43:52 +08:00
|
|
|
static int RunProgramRemotelyWithTimeout(
|
|
|
|
StringRef RemoteClientPath, ArrayRef<StringRef> Args, StringRef StdInFile,
|
|
|
|
StringRef StdOutFile, StringRef StdErrFile, unsigned NumSeconds = 0,
|
|
|
|
unsigned MemoryLimit = 0) {
|
2017-09-14 01:03:37 +08:00
|
|
|
Optional<StringRef> Redirects[3] = {StdInFile, StdOutFile, StdErrFile};
|
2009-07-19 02:39:24 +08:00
|
|
|
|
|
|
|
// Run the program remotely with the remote client
|
2018-06-13 01:43:52 +08:00
|
|
|
int ReturnCode = sys::ExecuteAndWait(RemoteClientPath, Args, None, Redirects,
|
|
|
|
NumSeconds, MemoryLimit);
|
2009-07-19 02:39:24 +08:00
|
|
|
|
|
|
|
// Has the remote client fail?
|
|
|
|
if (255 == ReturnCode) {
|
|
|
|
std::ostringstream OS;
|
|
|
|
OS << "\nError running remote client:\n ";
|
2018-06-13 01:43:52 +08:00
|
|
|
for (StringRef Arg : Args)
|
|
|
|
OS << " " << Arg.str();
|
2009-07-19 02:39:24 +08:00
|
|
|
OS << "\n";
|
|
|
|
|
|
|
|
// The error message is in the output file, let's print it out from there.
|
2013-06-13 23:52:54 +08:00
|
|
|
std::string StdOutFileName = StdOutFile.str();
|
|
|
|
std::ifstream ErrorFile(StdOutFileName.c_str());
|
2009-07-19 02:39:24 +08:00
|
|
|
if (ErrorFile) {
|
|
|
|
std::copy(std::istreambuf_iterator<char>(ErrorFile),
|
|
|
|
std::istreambuf_iterator<char>(),
|
|
|
|
std::ostreambuf_iterator<char>(OS));
|
|
|
|
ErrorFile.close();
|
|
|
|
}
|
2006-06-07 06:30:59 +08:00
|
|
|
|
2012-05-02 13:39:10 +08:00
|
|
|
errs() << OS.str();
|
2009-07-19 02:39:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return ReturnCode;
|
|
|
|
}
|
2006-06-07 06:30:59 +08:00
|
|
|
|
2018-06-13 01:43:52 +08:00
|
|
|
static Error ProcessFailure(StringRef ProgPath, ArrayRef<StringRef> Args,
|
2016-09-07 01:18:22 +08:00
|
|
|
unsigned Timeout = 0, unsigned MemoryLimit = 0) {
|
2006-06-07 06:30:59 +08:00
|
|
|
std::ostringstream OS;
|
|
|
|
OS << "\nError running tool:\n ";
|
2018-06-13 01:43:52 +08:00
|
|
|
for (StringRef Arg : Args)
|
|
|
|
OS << " " << Arg.str();
|
2006-06-07 06:30:59 +08:00
|
|
|
OS << "\n";
|
2010-11-04 00:14:07 +08:00
|
|
|
|
2006-06-07 06:30:59 +08:00
|
|
|
// Rerun the compiler, capturing any error messages to print them.
|
2013-06-19 01:20:08 +08:00
|
|
|
SmallString<128> ErrorFilename;
|
2014-06-13 11:07:50 +08:00
|
|
|
std::error_code EC = sys::fs::createTemporaryFile(
|
2014-10-08 05:47:23 +08:00
|
|
|
"bugpoint.program_error_messages", "", ErrorFilename);
|
2013-06-19 01:20:08 +08:00
|
|
|
if (EC) {
|
|
|
|
errs() << "Error making unique filename: " << EC.message() << "\n";
|
2006-08-24 04:34:57 +08:00
|
|
|
exit(1);
|
|
|
|
}
|
2014-07-13 21:28:18 +08:00
|
|
|
|
2013-06-13 23:47:11 +08:00
|
|
|
RunProgramWithTimeout(ProgPath, Args, "", ErrorFilename.str(),
|
|
|
|
ErrorFilename.str(), Timeout, MemoryLimit);
|
2010-05-24 15:49:55 +08:00
|
|
|
// FIXME: check return code ?
|
2006-06-07 06:30:59 +08:00
|
|
|
|
2015-10-15 04:29:54 +08:00
|
|
|
// Print out the error messages generated by CC if possible...
|
2006-06-07 06:30:59 +08:00
|
|
|
std::ifstream ErrorFile(ErrorFilename.c_str());
|
|
|
|
if (ErrorFile) {
|
|
|
|
std::copy(std::istreambuf_iterator<char>(ErrorFile),
|
|
|
|
std::istreambuf_iterator<char>(),
|
|
|
|
std::ostreambuf_iterator<char>(OS));
|
|
|
|
ErrorFile.close();
|
|
|
|
}
|
|
|
|
|
2013-06-19 01:20:08 +08:00
|
|
|
sys::fs::remove(ErrorFilename.c_str());
|
2016-09-07 01:18:22 +08:00
|
|
|
return make_error<StringError>(OS.str(), inconvertibleErrorCode());
|
2006-06-07 06:30:59 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
//===---------------------------------------------------------------------===//
|
|
|
|
// LLI Implementation of AbstractIntepreter interface
|
|
|
|
//
|
|
|
|
namespace {
|
2016-09-02 09:21:37 +08:00
|
|
|
class LLI : public AbstractInterpreter {
|
|
|
|
std::string LLIPath; // The path to the LLI executable
|
|
|
|
std::vector<std::string> ToolArgs; // Args to pass to LLI
|
|
|
|
public:
|
|
|
|
LLI(const std::string &Path, const std::vector<std::string> *Args)
|
2006-06-07 06:30:59 +08:00
|
|
|
: LLIPath(Path) {
|
2016-09-02 09:21:37 +08:00
|
|
|
ToolArgs.clear();
|
|
|
|
if (Args) {
|
|
|
|
ToolArgs = *Args;
|
2006-06-07 06:30:59 +08:00
|
|
|
}
|
2016-09-02 09:21:37 +08:00
|
|
|
}
|
2006-06-07 06:30:59 +08:00
|
|
|
|
2016-09-07 01:18:22 +08:00
|
|
|
Expected<int> ExecuteProgram(
|
2016-09-02 09:21:37 +08:00
|
|
|
const std::string &Bitcode, const std::vector<std::string> &Args,
|
|
|
|
const std::string &InputFile, const std::string &OutputFile,
|
2016-09-07 01:18:22 +08:00
|
|
|
const std::vector<std::string> &CCArgs,
|
2016-09-02 09:21:37 +08:00
|
|
|
const std::vector<std::string> &SharedLibs = std::vector<std::string>(),
|
|
|
|
unsigned Timeout = 0, unsigned MemoryLimit = 0) override;
|
|
|
|
};
|
2006-06-07 06:30:59 +08:00
|
|
|
}
|
|
|
|
|
2016-09-07 01:18:22 +08:00
|
|
|
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) {
|
2018-06-13 01:43:52 +08:00
|
|
|
std::vector<StringRef> LLIArgs;
|
2019-09-14 08:32:13 +08:00
|
|
|
LLIArgs.push_back(LLIPath);
|
2006-06-07 06:30:59 +08:00
|
|
|
LLIArgs.push_back("-force-interpreter=true");
|
|
|
|
|
2010-11-04 00:14:07 +08:00
|
|
|
for (std::vector<std::string>::const_iterator i = SharedLibs.begin(),
|
2016-09-02 09:21:37 +08:00
|
|
|
e = SharedLibs.end();
|
|
|
|
i != e; ++i) {
|
2009-11-17 18:20:22 +08:00
|
|
|
LLIArgs.push_back("-load");
|
2018-06-13 01:43:52 +08:00
|
|
|
LLIArgs.push_back(*i);
|
2009-11-17 18:20:22 +08:00
|
|
|
}
|
|
|
|
|
2006-06-07 06:30:59 +08:00
|
|
|
// Add any extra LLI args.
|
|
|
|
for (unsigned i = 0, e = ToolArgs.size(); i != e; ++i)
|
2018-06-13 01:43:52 +08:00
|
|
|
LLIArgs.push_back(ToolArgs[i]);
|
2006-06-07 06:30:59 +08:00
|
|
|
|
2018-06-13 01:43:52 +08:00
|
|
|
LLIArgs.push_back(Bitcode);
|
2006-06-07 06:30:59 +08:00
|
|
|
// Add optional parameters to the running program from Argv
|
2016-09-02 09:21:37 +08:00
|
|
|
for (unsigned i = 0, e = Args.size(); i != e; ++i)
|
2018-06-13 01:43:52 +08:00
|
|
|
LLIArgs.push_back(Args[i]);
|
2006-06-07 06:30:59 +08:00
|
|
|
|
2016-09-02 09:21:37 +08:00
|
|
|
outs() << "<lli>";
|
|
|
|
outs().flush();
|
2018-05-14 20:53:11 +08:00
|
|
|
LLVM_DEBUG(errs() << "\nAbout to run:\t";
|
|
|
|
for (unsigned i = 0, e = LLIArgs.size() - 1; i != e; ++i) errs()
|
|
|
|
<< " " << LLIArgs[i];
|
|
|
|
errs() << "\n";);
|
2018-06-13 01:43:52 +08:00
|
|
|
return RunProgramWithTimeout(LLIPath, LLIArgs, InputFile, OutputFile,
|
2016-09-07 01:18:22 +08:00
|
|
|
OutputFile, Timeout, MemoryLimit);
|
2006-06-07 06:30:59 +08:00
|
|
|
}
|
|
|
|
|
2016-09-02 09:21:37 +08:00
|
|
|
void AbstractInterpreter::anchor() {}
|
2011-12-20 10:50:00 +08:00
|
|
|
|
[bugpoint] Find 'opt', etc., in bugpoint directory
Summary:
When bugpoint attempts to find the other executables it needs to run,
such as `opt` or `clang`, it tries searching the user's PATH. However,
in many cases, the 'bugpoint' executable is part of an LLVM build, and
the 'opt' executable it's looking for is in that same directory.
Many LLVM tools handle this case by using the `Paths` parameter of
`llvm::sys::findProgramByName`, passing the parent path of the currently
running executable. Do this same thing for bugpoint. However, to
preserve the current behavior exactly, first search the user's PATH,
and then search for 'opt' in the directory containing 'bugpoint'.
Test Plan:
`check-llvm`. Many of the existing bugpoint tests no longer need to use the
`--opt-command` option as a result of these changes.
Reviewers: MatzeB, silvas, davide
Reviewed By: MatzeB, davide
Subscribers: davide, llvm-commits
Differential Revision: https://reviews.llvm.org/D54884
llvm-svn: 348734
2018-12-10 08:56:13 +08:00
|
|
|
ErrorOr<std::string> llvm::FindProgramByName(const std::string &ExeName,
|
2013-06-19 00:47:55 +08:00
|
|
|
const char *Argv0,
|
|
|
|
void *MainAddr) {
|
2013-06-14 23:12:13 +08:00
|
|
|
// Check the directory that the calling program is in. We can do
|
|
|
|
// this if ProgramPath contains at least one / character, indicating that it
|
|
|
|
// is a relative path to the executable itself.
|
2013-06-26 13:01:35 +08:00
|
|
|
std::string Main = sys::fs::getMainExecutable(Argv0, MainAddr);
|
|
|
|
StringRef Result = sys::path::parent_path(Main);
|
[bugpoint] Find 'opt', etc., in bugpoint directory
Summary:
When bugpoint attempts to find the other executables it needs to run,
such as `opt` or `clang`, it tries searching the user's PATH. However,
in many cases, the 'bugpoint' executable is part of an LLVM build, and
the 'opt' executable it's looking for is in that same directory.
Many LLVM tools handle this case by using the `Paths` parameter of
`llvm::sys::findProgramByName`, passing the parent path of the currently
running executable. Do this same thing for bugpoint. However, to
preserve the current behavior exactly, first search the user's PATH,
and then search for 'opt' in the directory containing 'bugpoint'.
Test Plan:
`check-llvm`. Many of the existing bugpoint tests no longer need to use the
`--opt-command` option as a result of these changes.
Reviewers: MatzeB, silvas, davide
Reviewed By: MatzeB, davide
Subscribers: davide, llvm-commits
Differential Revision: https://reviews.llvm.org/D54884
llvm-svn: 348734
2018-12-10 08:56:13 +08:00
|
|
|
if (ErrorOr<std::string> Path = sys::findProgramByName(ExeName, Result))
|
|
|
|
return *Path;
|
2013-06-19 01:20:08 +08:00
|
|
|
|
[bugpoint] Find 'opt', etc., in bugpoint directory
Summary:
When bugpoint attempts to find the other executables it needs to run,
such as `opt` or `clang`, it tries searching the user's PATH. However,
in many cases, the 'bugpoint' executable is part of an LLVM build, and
the 'opt' executable it's looking for is in that same directory.
Many LLVM tools handle this case by using the `Paths` parameter of
`llvm::sys::findProgramByName`, passing the parent path of the currently
running executable. Do this same thing for bugpoint. However, to
preserve the current behavior exactly, first search the user's PATH,
and then search for 'opt' in the directory containing 'bugpoint'.
Test Plan:
`check-llvm`. Many of the existing bugpoint tests no longer need to use the
`--opt-command` option as a result of these changes.
Reviewers: MatzeB, silvas, davide
Reviewed By: MatzeB, davide
Subscribers: davide, llvm-commits
Differential Revision: https://reviews.llvm.org/D54884
llvm-svn: 348734
2018-12-10 08:56:13 +08:00
|
|
|
// Check the user PATH.
|
|
|
|
return sys::findProgramByName(ExeName);
|
2013-06-14 23:12:13 +08:00
|
|
|
}
|
|
|
|
|
2006-06-07 06:30:59 +08:00
|
|
|
// LLI create method - Try to find the LLI executable
|
2016-09-02 09:21:37 +08:00
|
|
|
AbstractInterpreter *
|
|
|
|
AbstractInterpreter::createLLI(const char *Argv0, std::string &Message,
|
|
|
|
const std::vector<std::string> *ToolArgs) {
|
[bugpoint] Find 'opt', etc., in bugpoint directory
Summary:
When bugpoint attempts to find the other executables it needs to run,
such as `opt` or `clang`, it tries searching the user's PATH. However,
in many cases, the 'bugpoint' executable is part of an LLVM build, and
the 'opt' executable it's looking for is in that same directory.
Many LLVM tools handle this case by using the `Paths` parameter of
`llvm::sys::findProgramByName`, passing the parent path of the currently
running executable. Do this same thing for bugpoint. However, to
preserve the current behavior exactly, first search the user's PATH,
and then search for 'opt' in the directory containing 'bugpoint'.
Test Plan:
`check-llvm`. Many of the existing bugpoint tests no longer need to use the
`--opt-command` option as a result of these changes.
Reviewers: MatzeB, silvas, davide
Reviewed By: MatzeB, davide
Subscribers: davide, llvm-commits
Differential Revision: https://reviews.llvm.org/D54884
llvm-svn: 348734
2018-12-10 08:56:13 +08:00
|
|
|
if (ErrorOr<std::string> LLIPath =
|
|
|
|
FindProgramByName("lli", Argv0, (void *)(intptr_t)&createLLI)) {
|
|
|
|
Message = "Found lli: " + *LLIPath + "\n";
|
|
|
|
return new LLI(*LLIPath, ToolArgs);
|
|
|
|
} else {
|
|
|
|
Message = LLIPath.getError().message() + "\n";
|
|
|
|
return nullptr;
|
2006-06-07 06:30:59 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-02-09 02:20:48 +08:00
|
|
|
//===---------------------------------------------------------------------===//
|
|
|
|
// 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 {
|
2016-09-02 09:21:37 +08:00
|
|
|
class CustomCompiler : public AbstractInterpreter {
|
|
|
|
std::string CompilerCommand;
|
|
|
|
std::vector<std::string> CompilerArgs;
|
|
|
|
|
|
|
|
public:
|
|
|
|
CustomCompiler(const std::string &CompilerCmd,
|
|
|
|
std::vector<std::string> CompArgs)
|
|
|
|
: CompilerCommand(CompilerCmd), CompilerArgs(std::move(CompArgs)) {}
|
|
|
|
|
2016-09-07 01:18:22 +08:00
|
|
|
Error compileProgram(const std::string &Bitcode, unsigned Timeout = 0,
|
|
|
|
unsigned MemoryLimit = 0) override;
|
2016-09-02 09:21:37 +08:00
|
|
|
|
2016-09-07 01:18:22 +08:00
|
|
|
Expected<int> ExecuteProgram(
|
2016-09-02 09:21:37 +08:00
|
|
|
const std::string &Bitcode, const std::vector<std::string> &Args,
|
|
|
|
const std::string &InputFile, const std::string &OutputFile,
|
|
|
|
const std::vector<std::string> &CCArgs = std::vector<std::string>(),
|
|
|
|
const std::vector<std::string> &SharedLibs = std::vector<std::string>(),
|
|
|
|
unsigned Timeout = 0, unsigned MemoryLimit = 0) override {
|
2016-09-07 01:18:22 +08:00
|
|
|
return make_error<StringError>(
|
|
|
|
"Execution not supported with -compile-custom",
|
|
|
|
inconvertibleErrorCode());
|
2016-09-02 09:21:37 +08:00
|
|
|
}
|
|
|
|
};
|
2011-02-09 02:20:48 +08:00
|
|
|
}
|
|
|
|
|
2016-09-07 01:18:22 +08:00
|
|
|
Error CustomCompiler::compileProgram(const std::string &Bitcode,
|
|
|
|
unsigned Timeout, unsigned MemoryLimit) {
|
2011-02-09 02:20:48 +08:00
|
|
|
|
2018-06-13 01:43:52 +08:00
|
|
|
std::vector<StringRef> ProgramArgs;
|
2019-09-14 08:32:13 +08:00
|
|
|
ProgramArgs.push_back(CompilerCommand);
|
2011-02-09 02:20:48 +08:00
|
|
|
|
2019-09-14 08:32:13 +08:00
|
|
|
for (const auto &Arg : CompilerArgs)
|
|
|
|
ProgramArgs.push_back(Arg);
|
2018-06-13 01:43:52 +08:00
|
|
|
ProgramArgs.push_back(Bitcode);
|
2011-02-09 02:20:48 +08:00
|
|
|
|
|
|
|
// Add optional parameters to the running program from Argv
|
2019-09-14 08:32:13 +08:00
|
|
|
for (const auto &Arg : CompilerArgs)
|
|
|
|
ProgramArgs.push_back(Arg);
|
2011-02-09 02:20:48 +08:00
|
|
|
|
2018-06-13 01:43:52 +08:00
|
|
|
if (RunProgramWithTimeout(CompilerCommand, ProgramArgs, "", "", "", Timeout,
|
|
|
|
MemoryLimit))
|
|
|
|
return ProcessFailure(CompilerCommand, ProgramArgs, Timeout, MemoryLimit);
|
2016-09-07 01:18:22 +08:00
|
|
|
return Error::success();
|
2011-02-09 02:20:48 +08:00
|
|
|
}
|
|
|
|
|
2008-04-29 04:53:48 +08:00
|
|
|
//===---------------------------------------------------------------------===//
|
|
|
|
// Custom execution command implementation of AbstractIntepreter interface
|
|
|
|
//
|
|
|
|
// Allows using a custom command for executing the bitcode, thus allows,
|
2010-11-04 00:14:07 +08:00
|
|
|
// for example, to invoke a cross compiler for code generation followed by
|
2008-04-29 04:53:48 +08:00
|
|
|
// a simulator that executes the generated binary.
|
|
|
|
namespace {
|
2016-09-02 09:21:37 +08:00
|
|
|
class CustomExecutor : public AbstractInterpreter {
|
|
|
|
std::string ExecutionCommand;
|
|
|
|
std::vector<std::string> ExecutorArgs;
|
|
|
|
|
|
|
|
public:
|
|
|
|
CustomExecutor(const std::string &ExecutionCmd,
|
|
|
|
std::vector<std::string> ExecArgs)
|
|
|
|
: ExecutionCommand(ExecutionCmd), ExecutorArgs(std::move(ExecArgs)) {}
|
|
|
|
|
2016-09-07 01:18:22 +08:00
|
|
|
Expected<int> ExecuteProgram(
|
2016-09-02 09:21:37 +08:00
|
|
|
const std::string &Bitcode, const std::vector<std::string> &Args,
|
|
|
|
const std::string &InputFile, const std::string &OutputFile,
|
2016-09-07 01:18:22 +08:00
|
|
|
const std::vector<std::string> &CCArgs,
|
2016-09-02 09:21:37 +08:00
|
|
|
const std::vector<std::string> &SharedLibs = std::vector<std::string>(),
|
|
|
|
unsigned Timeout = 0, unsigned MemoryLimit = 0) override;
|
|
|
|
};
|
2008-04-29 04:53:48 +08:00
|
|
|
}
|
|
|
|
|
2016-09-07 01:18:22 +08:00
|
|
|
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) {
|
2016-09-02 09:21:37 +08:00
|
|
|
|
2018-06-13 01:43:52 +08:00
|
|
|
std::vector<StringRef> ProgramArgs;
|
|
|
|
ProgramArgs.push_back(ExecutionCommand);
|
2008-04-29 04:53:48 +08:00
|
|
|
|
|
|
|
for (std::size_t i = 0; i < ExecutorArgs.size(); ++i)
|
2018-06-13 01:43:52 +08:00
|
|
|
ProgramArgs.push_back(ExecutorArgs[i]);
|
|
|
|
ProgramArgs.push_back(Bitcode);
|
2008-04-29 04:53:48 +08:00
|
|
|
|
|
|
|
// Add optional parameters to the running program from Argv
|
2010-04-12 13:08:25 +08:00
|
|
|
for (unsigned i = 0, e = Args.size(); i != e; ++i)
|
2018-06-13 01:43:52 +08:00
|
|
|
ProgramArgs.push_back(Args[i]);
|
2008-04-29 04:53:48 +08:00
|
|
|
|
2018-06-13 01:43:52 +08:00
|
|
|
return RunProgramWithTimeout(ExecutionCommand, ProgramArgs, InputFile,
|
2016-09-07 01:18:22 +08:00
|
|
|
OutputFile, OutputFile, Timeout, MemoryLimit);
|
2008-04-29 04:53:48 +08:00
|
|
|
}
|
|
|
|
|
2011-02-09 02:20:48 +08:00
|
|
|
// 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
|
2017-03-03 00:50:48 +08:00
|
|
|
// as a single argument because then the program sees only a single
|
2011-02-09 02:20:48 +08:00
|
|
|
// command line argument (with spaces in it: "foo bar" instead
|
|
|
|
// of "foo" and "bar").
|
|
|
|
//
|
2017-03-03 00:50:48 +08:00
|
|
|
// 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'
|
|
|
|
//
|
[bugpoint] Find 'opt', etc., in bugpoint directory
Summary:
When bugpoint attempts to find the other executables it needs to run,
such as `opt` or `clang`, it tries searching the user's PATH. However,
in many cases, the 'bugpoint' executable is part of an LLVM build, and
the 'opt' executable it's looking for is in that same directory.
Many LLVM tools handle this case by using the `Paths` parameter of
`llvm::sys::findProgramByName`, passing the parent path of the currently
running executable. Do this same thing for bugpoint. However, to
preserve the current behavior exactly, first search the user's PATH,
and then search for 'opt' in the directory containing 'bugpoint'.
Test Plan:
`check-llvm`. Many of the existing bugpoint tests no longer need to use the
`--opt-command` option as a result of these changes.
Reviewers: MatzeB, silvas, davide
Reviewed By: MatzeB, davide
Subscribers: davide, llvm-commits
Differential Revision: https://reviews.llvm.org/D54884
llvm-svn: 348734
2018-12-10 08:56:13 +08:00
|
|
|
static void lexCommand(const char *Argv0, std::string &Message,
|
|
|
|
const std::string &CommandLine, std::string &CmdPath,
|
|
|
|
std::vector<std::string> &Args) {
|
2008-04-29 04:53:48 +08:00
|
|
|
|
2017-03-03 00:50:48 +08:00
|
|
|
std::string Token;
|
|
|
|
std::string Command;
|
|
|
|
bool FoundPath = false;
|
|
|
|
|
|
|
|
// first argument is the PATH.
|
|
|
|
// Skip repeated whitespace, leading whitespace and trailing whitespace.
|
|
|
|
for (std::size_t Pos = 0u; Pos <= CommandLine.size(); ++Pos) {
|
|
|
|
if ('\\' == CommandLine[Pos]) {
|
|
|
|
if (Pos + 1 < CommandLine.size())
|
|
|
|
Token.push_back(CommandLine[++Pos]);
|
|
|
|
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (' ' == CommandLine[Pos] || CommandLine.size() == Pos) {
|
|
|
|
if (Token.empty())
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (!FoundPath) {
|
|
|
|
Command = Token;
|
|
|
|
FoundPath = true;
|
|
|
|
Token.clear();
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
Args.push_back(Token);
|
|
|
|
Token.clear();
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
Token.push_back(CommandLine[Pos]);
|
2008-04-29 04:53:48 +08:00
|
|
|
}
|
|
|
|
|
[bugpoint] Find 'opt', etc., in bugpoint directory
Summary:
When bugpoint attempts to find the other executables it needs to run,
such as `opt` or `clang`, it tries searching the user's PATH. However,
in many cases, the 'bugpoint' executable is part of an LLVM build, and
the 'opt' executable it's looking for is in that same directory.
Many LLVM tools handle this case by using the `Paths` parameter of
`llvm::sys::findProgramByName`, passing the parent path of the currently
running executable. Do this same thing for bugpoint. However, to
preserve the current behavior exactly, first search the user's PATH,
and then search for 'opt' in the directory containing 'bugpoint'.
Test Plan:
`check-llvm`. Many of the existing bugpoint tests no longer need to use the
`--opt-command` option as a result of these changes.
Reviewers: MatzeB, silvas, davide
Reviewed By: MatzeB, davide
Subscribers: davide, llvm-commits
Differential Revision: https://reviews.llvm.org/D54884
llvm-svn: 348734
2018-12-10 08:56:13 +08:00
|
|
|
auto Path = FindProgramByName(Command, Argv0, (void *)(intptr_t)&lexCommand);
|
2014-11-04 09:29:59 +08:00
|
|
|
if (!Path) {
|
2017-03-03 00:50:48 +08:00
|
|
|
Message = std::string("Cannot find '") + Command +
|
|
|
|
"' in PATH: " + Path.getError().message() + "\n";
|
2011-02-09 02:20:48 +08:00
|
|
|
return;
|
2008-04-29 04:53:48 +08:00
|
|
|
}
|
2014-11-04 09:29:59 +08:00
|
|
|
CmdPath = *Path;
|
2008-04-29 04:53:48 +08:00
|
|
|
|
|
|
|
Message = "Found command in: " + CmdPath + "\n";
|
2011-02-09 02:20:48 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Custom execution environment create method, takes the execution command
|
|
|
|
// as arguments
|
|
|
|
AbstractInterpreter *AbstractInterpreter::createCustomCompiler(
|
[bugpoint] Find 'opt', etc., in bugpoint directory
Summary:
When bugpoint attempts to find the other executables it needs to run,
such as `opt` or `clang`, it tries searching the user's PATH. However,
in many cases, the 'bugpoint' executable is part of an LLVM build, and
the 'opt' executable it's looking for is in that same directory.
Many LLVM tools handle this case by using the `Paths` parameter of
`llvm::sys::findProgramByName`, passing the parent path of the currently
running executable. Do this same thing for bugpoint. However, to
preserve the current behavior exactly, first search the user's PATH,
and then search for 'opt' in the directory containing 'bugpoint'.
Test Plan:
`check-llvm`. Many of the existing bugpoint tests no longer need to use the
`--opt-command` option as a result of these changes.
Reviewers: MatzeB, silvas, davide
Reviewed By: MatzeB, davide
Subscribers: davide, llvm-commits
Differential Revision: https://reviews.llvm.org/D54884
llvm-svn: 348734
2018-12-10 08:56:13 +08:00
|
|
|
const char *Argv0, std::string &Message,
|
|
|
|
const std::string &CompileCommandLine) {
|
2011-02-09 02:20:48 +08:00
|
|
|
|
|
|
|
std::string CmdPath;
|
|
|
|
std::vector<std::string> Args;
|
[bugpoint] Find 'opt', etc., in bugpoint directory
Summary:
When bugpoint attempts to find the other executables it needs to run,
such as `opt` or `clang`, it tries searching the user's PATH. However,
in many cases, the 'bugpoint' executable is part of an LLVM build, and
the 'opt' executable it's looking for is in that same directory.
Many LLVM tools handle this case by using the `Paths` parameter of
`llvm::sys::findProgramByName`, passing the parent path of the currently
running executable. Do this same thing for bugpoint. However, to
preserve the current behavior exactly, first search the user's PATH,
and then search for 'opt' in the directory containing 'bugpoint'.
Test Plan:
`check-llvm`. Many of the existing bugpoint tests no longer need to use the
`--opt-command` option as a result of these changes.
Reviewers: MatzeB, silvas, davide
Reviewed By: MatzeB, davide
Subscribers: davide, llvm-commits
Differential Revision: https://reviews.llvm.org/D54884
llvm-svn: 348734
2018-12-10 08:56:13 +08:00
|
|
|
lexCommand(Argv0, Message, CompileCommandLine, CmdPath, Args);
|
2011-02-09 02:20:48 +08:00
|
|
|
if (CmdPath.empty())
|
2014-04-25 12:24:47 +08:00
|
|
|
return nullptr;
|
2011-02-09 02:20:48 +08:00
|
|
|
|
|
|
|
return new CustomCompiler(CmdPath, Args);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Custom execution environment create method, takes the execution command
|
|
|
|
// as arguments
|
2016-09-02 09:21:37 +08:00
|
|
|
AbstractInterpreter *
|
[bugpoint] Find 'opt', etc., in bugpoint directory
Summary:
When bugpoint attempts to find the other executables it needs to run,
such as `opt` or `clang`, it tries searching the user's PATH. However,
in many cases, the 'bugpoint' executable is part of an LLVM build, and
the 'opt' executable it's looking for is in that same directory.
Many LLVM tools handle this case by using the `Paths` parameter of
`llvm::sys::findProgramByName`, passing the parent path of the currently
running executable. Do this same thing for bugpoint. However, to
preserve the current behavior exactly, first search the user's PATH,
and then search for 'opt' in the directory containing 'bugpoint'.
Test Plan:
`check-llvm`. Many of the existing bugpoint tests no longer need to use the
`--opt-command` option as a result of these changes.
Reviewers: MatzeB, silvas, davide
Reviewed By: MatzeB, davide
Subscribers: davide, llvm-commits
Differential Revision: https://reviews.llvm.org/D54884
llvm-svn: 348734
2018-12-10 08:56:13 +08:00
|
|
|
AbstractInterpreter::createCustomExecutor(const char *Argv0,
|
|
|
|
std::string &Message,
|
2016-09-02 09:21:37 +08:00
|
|
|
const std::string &ExecCommandLine) {
|
2011-02-09 02:20:48 +08:00
|
|
|
|
|
|
|
std::string CmdPath;
|
|
|
|
std::vector<std::string> Args;
|
[bugpoint] Find 'opt', etc., in bugpoint directory
Summary:
When bugpoint attempts to find the other executables it needs to run,
such as `opt` or `clang`, it tries searching the user's PATH. However,
in many cases, the 'bugpoint' executable is part of an LLVM build, and
the 'opt' executable it's looking for is in that same directory.
Many LLVM tools handle this case by using the `Paths` parameter of
`llvm::sys::findProgramByName`, passing the parent path of the currently
running executable. Do this same thing for bugpoint. However, to
preserve the current behavior exactly, first search the user's PATH,
and then search for 'opt' in the directory containing 'bugpoint'.
Test Plan:
`check-llvm`. Many of the existing bugpoint tests no longer need to use the
`--opt-command` option as a result of these changes.
Reviewers: MatzeB, silvas, davide
Reviewed By: MatzeB, davide
Subscribers: davide, llvm-commits
Differential Revision: https://reviews.llvm.org/D54884
llvm-svn: 348734
2018-12-10 08:56:13 +08:00
|
|
|
lexCommand(Argv0, Message, ExecCommandLine, CmdPath, Args);
|
2011-02-09 02:20:48 +08:00
|
|
|
if (CmdPath.empty())
|
2014-04-25 12:24:47 +08:00
|
|
|
return nullptr;
|
2008-04-29 04:53:48 +08:00
|
|
|
|
|
|
|
return new CustomExecutor(CmdPath, Args);
|
|
|
|
}
|
|
|
|
|
2006-06-07 06:30:59 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// LLC Implementation of AbstractIntepreter interface
|
|
|
|
//
|
2016-09-07 01:18:22 +08:00
|
|
|
Expected<CC::FileType> LLC::OutputCode(const std::string &Bitcode,
|
|
|
|
std::string &OutputAsmFile,
|
|
|
|
unsigned Timeout, unsigned MemoryLimit) {
|
2010-03-16 14:41:47 +08:00
|
|
|
const char *Suffix = (UseIntegratedAssembler ? ".llc.o" : ".llc.s");
|
2013-06-19 01:20:08 +08:00
|
|
|
|
|
|
|
SmallString<128> UniqueFile;
|
2014-06-13 11:07:50 +08:00
|
|
|
std::error_code EC =
|
2013-07-06 05:01:08 +08:00
|
|
|
sys::fs::createUniqueFile(Bitcode + "-%%%%%%%" + Suffix, UniqueFile);
|
2013-06-19 01:20:08 +08:00
|
|
|
if (EC) {
|
|
|
|
errs() << "Error making unique filename: " << EC.message() << "\n";
|
2006-08-24 04:34:57 +08:00
|
|
|
exit(1);
|
|
|
|
}
|
2013-06-19 01:20:08 +08:00
|
|
|
OutputAsmFile = UniqueFile.str();
|
2018-06-13 01:43:52 +08:00
|
|
|
std::vector<StringRef> LLCArgs;
|
|
|
|
LLCArgs.push_back(LLCPath);
|
2006-06-07 06:30:59 +08:00
|
|
|
|
|
|
|
// Add any extra LLC args.
|
|
|
|
for (unsigned i = 0, e = ToolArgs.size(); i != e; ++i)
|
2018-06-13 01:43:52 +08:00
|
|
|
LLCArgs.push_back(ToolArgs[i]);
|
2006-06-07 06:30:59 +08:00
|
|
|
|
2010-03-16 14:41:47 +08:00
|
|
|
LLCArgs.push_back("-o");
|
2018-06-13 01:43:52 +08:00
|
|
|
LLCArgs.push_back(OutputAsmFile); // Output to the Asm file
|
|
|
|
LLCArgs.push_back(Bitcode); // This is the input bitcode
|
2010-11-04 00:14:07 +08:00
|
|
|
|
2010-03-16 14:41:47 +08:00
|
|
|
if (UseIntegratedAssembler)
|
|
|
|
LLCArgs.push_back("-filetype=obj");
|
2010-11-04 00:14:07 +08:00
|
|
|
|
2010-03-16 14:41:47 +08:00
|
|
|
outs() << (UseIntegratedAssembler ? "<llc-ia>" : "<llc>");
|
|
|
|
outs().flush();
|
2018-05-14 20:53:11 +08:00
|
|
|
LLVM_DEBUG(errs() << "\nAbout to run:\t";
|
|
|
|
for (unsigned i = 0, e = LLCArgs.size() - 1; i != e; ++i) errs()
|
|
|
|
<< " " << LLCArgs[i];
|
|
|
|
errs() << "\n";);
|
2018-06-13 01:43:52 +08:00
|
|
|
if (RunProgramWithTimeout(LLCPath, LLCArgs, "", "", "", Timeout, MemoryLimit))
|
|
|
|
return ProcessFailure(LLCPath, LLCArgs, Timeout, MemoryLimit);
|
2015-10-15 04:29:54 +08:00
|
|
|
return UseIntegratedAssembler ? CC::ObjectFile : CC::AsmFile;
|
2006-06-07 06:30:59 +08:00
|
|
|
}
|
|
|
|
|
2016-09-07 01:18:22 +08:00
|
|
|
Error LLC::compileProgram(const std::string &Bitcode, unsigned Timeout,
|
|
|
|
unsigned MemoryLimit) {
|
2013-06-18 03:21:38 +08:00
|
|
|
std::string OutputAsmFile;
|
2016-09-07 01:18:22 +08:00
|
|
|
Expected<CC::FileType> Result =
|
|
|
|
OutputCode(Bitcode, OutputAsmFile, Timeout, MemoryLimit);
|
2013-06-18 03:21:38 +08:00
|
|
|
sys::fs::remove(OutputAsmFile);
|
2016-09-07 01:18:22 +08:00
|
|
|
if (Error E = Result.takeError())
|
|
|
|
return E;
|
|
|
|
return Error::success();
|
2006-06-07 06:30:59 +08:00
|
|
|
}
|
|
|
|
|
2016-09-07 01:18:22 +08:00
|
|
|
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) {
|
2006-06-07 06:30:59 +08:00
|
|
|
|
2013-06-18 03:21:38 +08:00
|
|
|
std::string OutputAsmFile;
|
2016-09-07 01:18:22 +08:00
|
|
|
Expected<CC::FileType> FileKind =
|
|
|
|
OutputCode(Bitcode, OutputAsmFile, Timeout, MemoryLimit);
|
2013-06-18 03:21:38 +08:00
|
|
|
FileRemover OutFileRemover(OutputAsmFile, !SaveTemps);
|
2016-09-07 01:18:22 +08:00
|
|
|
if (Error E = FileKind.takeError())
|
|
|
|
return std::move(E);
|
2006-06-07 06:30:59 +08:00
|
|
|
|
2015-10-15 04:29:54 +08:00
|
|
|
std::vector<std::string> CCArgs(ArgsForCC);
|
|
|
|
CCArgs.insert(CCArgs.end(), SharedLibs.begin(), SharedLibs.end());
|
2006-06-07 06:30:59 +08:00
|
|
|
|
2015-10-15 04:29:54 +08:00
|
|
|
// Assuming LLC worked, compile the result with CC and run it.
|
2016-09-07 01:18:22 +08:00
|
|
|
return cc->ExecuteProgram(OutputAsmFile, Args, *FileKind, InputFile,
|
|
|
|
OutputFile, CCArgs, Timeout, MemoryLimit);
|
2006-06-07 06:30:59 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/// createLLC - Try to find the LLC executable
|
|
|
|
///
|
2016-09-02 09:21:37 +08:00
|
|
|
LLC *AbstractInterpreter::createLLC(const char *Argv0, std::string &Message,
|
2015-10-15 04:29:54 +08:00
|
|
|
const std::string &CCBinary,
|
2009-03-03 07:13:18 +08:00
|
|
|
const std::vector<std::string> *Args,
|
2015-10-15 04:29:54 +08:00
|
|
|
const std::vector<std::string> *CCArgs,
|
2010-03-16 14:41:47 +08:00
|
|
|
bool UseIntegratedAssembler) {
|
[bugpoint] Find 'opt', etc., in bugpoint directory
Summary:
When bugpoint attempts to find the other executables it needs to run,
such as `opt` or `clang`, it tries searching the user's PATH. However,
in many cases, the 'bugpoint' executable is part of an LLVM build, and
the 'opt' executable it's looking for is in that same directory.
Many LLVM tools handle this case by using the `Paths` parameter of
`llvm::sys::findProgramByName`, passing the parent path of the currently
running executable. Do this same thing for bugpoint. However, to
preserve the current behavior exactly, first search the user's PATH,
and then search for 'opt' in the directory containing 'bugpoint'.
Test Plan:
`check-llvm`. Many of the existing bugpoint tests no longer need to use the
`--opt-command` option as a result of these changes.
Reviewers: MatzeB, silvas, davide
Reviewed By: MatzeB, davide
Subscribers: davide, llvm-commits
Differential Revision: https://reviews.llvm.org/D54884
llvm-svn: 348734
2018-12-10 08:56:13 +08:00
|
|
|
ErrorOr<std::string> LLCPath =
|
|
|
|
FindProgramByName("llc", Argv0, (void *)(intptr_t)&createLLC);
|
|
|
|
if (!LLCPath) {
|
|
|
|
Message = LLCPath.getError().message() + "\n";
|
2014-04-25 12:24:47 +08:00
|
|
|
return nullptr;
|
2006-06-07 06:30:59 +08:00
|
|
|
}
|
|
|
|
|
[bugpoint] Find 'opt', etc., in bugpoint directory
Summary:
When bugpoint attempts to find the other executables it needs to run,
such as `opt` or `clang`, it tries searching the user's PATH. However,
in many cases, the 'bugpoint' executable is part of an LLVM build, and
the 'opt' executable it's looking for is in that same directory.
Many LLVM tools handle this case by using the `Paths` parameter of
`llvm::sys::findProgramByName`, passing the parent path of the currently
running executable. Do this same thing for bugpoint. However, to
preserve the current behavior exactly, first search the user's PATH,
and then search for 'opt' in the directory containing 'bugpoint'.
Test Plan:
`check-llvm`. Many of the existing bugpoint tests no longer need to use the
`--opt-command` option as a result of these changes.
Reviewers: MatzeB, silvas, davide
Reviewed By: MatzeB, davide
Subscribers: davide, llvm-commits
Differential Revision: https://reviews.llvm.org/D54884
llvm-svn: 348734
2018-12-10 08:56:13 +08:00
|
|
|
CC *cc = CC::create(Argv0, Message, CCBinary, CCArgs);
|
2015-10-15 04:29:54 +08:00
|
|
|
if (!cc) {
|
2009-07-16 00:35:29 +08:00
|
|
|
errs() << Message << "\n";
|
2006-06-07 06:30:59 +08:00
|
|
|
exit(1);
|
|
|
|
}
|
[bugpoint] Find 'opt', etc., in bugpoint directory
Summary:
When bugpoint attempts to find the other executables it needs to run,
such as `opt` or `clang`, it tries searching the user's PATH. However,
in many cases, the 'bugpoint' executable is part of an LLVM build, and
the 'opt' executable it's looking for is in that same directory.
Many LLVM tools handle this case by using the `Paths` parameter of
`llvm::sys::findProgramByName`, passing the parent path of the currently
running executable. Do this same thing for bugpoint. However, to
preserve the current behavior exactly, first search the user's PATH,
and then search for 'opt' in the directory containing 'bugpoint'.
Test Plan:
`check-llvm`. Many of the existing bugpoint tests no longer need to use the
`--opt-command` option as a result of these changes.
Reviewers: MatzeB, silvas, davide
Reviewed By: MatzeB, davide
Subscribers: davide, llvm-commits
Differential Revision: https://reviews.llvm.org/D54884
llvm-svn: 348734
2018-12-10 08:56:13 +08:00
|
|
|
Message = "Found llc: " + *LLCPath + "\n";
|
|
|
|
return new LLC(*LLCPath, cc, Args, UseIntegratedAssembler);
|
2006-06-07 06:30:59 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
//===---------------------------------------------------------------------===//
|
|
|
|
// JIT Implementation of AbstractIntepreter interface
|
|
|
|
//
|
|
|
|
namespace {
|
2016-09-02 09:21:37 +08:00
|
|
|
class JIT : public AbstractInterpreter {
|
|
|
|
std::string LLIPath; // The path to the LLI executable
|
|
|
|
std::vector<std::string> ToolArgs; // Args to pass to LLI
|
|
|
|
public:
|
|
|
|
JIT(const std::string &Path, const std::vector<std::string> *Args)
|
2006-06-07 06:30:59 +08:00
|
|
|
: LLIPath(Path) {
|
2016-09-02 09:21:37 +08:00
|
|
|
ToolArgs.clear();
|
|
|
|
if (Args) {
|
|
|
|
ToolArgs = *Args;
|
2006-06-07 06:30:59 +08:00
|
|
|
}
|
2016-09-02 09:21:37 +08:00
|
|
|
}
|
2006-06-07 06:30:59 +08:00
|
|
|
|
2016-09-07 01:18:22 +08:00
|
|
|
Expected<int> ExecuteProgram(
|
2016-09-02 09:21:37 +08:00
|
|
|
const std::string &Bitcode, const std::vector<std::string> &Args,
|
|
|
|
const std::string &InputFile, const std::string &OutputFile,
|
|
|
|
const std::vector<std::string> &CCArgs = std::vector<std::string>(),
|
|
|
|
const std::vector<std::string> &SharedLibs = std::vector<std::string>(),
|
|
|
|
unsigned Timeout = 0, unsigned MemoryLimit = 0) override;
|
|
|
|
};
|
2006-06-07 06:30:59 +08:00
|
|
|
}
|
|
|
|
|
2016-09-07 01:18:22 +08:00
|
|
|
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) {
|
2006-06-07 06:30:59 +08:00
|
|
|
// Construct a vector of parameters, incorporating those from the command-line
|
2018-06-13 01:43:52 +08:00
|
|
|
std::vector<StringRef> JITArgs;
|
2019-09-14 08:32:13 +08:00
|
|
|
JITArgs.push_back(LLIPath);
|
2006-06-07 06:30:59 +08:00
|
|
|
JITArgs.push_back("-force-interpreter=false");
|
|
|
|
|
|
|
|
// Add any extra LLI args.
|
|
|
|
for (unsigned i = 0, e = ToolArgs.size(); i != e; ++i)
|
2018-06-13 01:43:52 +08:00
|
|
|
JITArgs.push_back(ToolArgs[i]);
|
2006-06-07 06:30:59 +08:00
|
|
|
|
|
|
|
for (unsigned i = 0, e = SharedLibs.size(); i != e; ++i) {
|
|
|
|
JITArgs.push_back("-load");
|
2018-06-13 01:43:52 +08:00
|
|
|
JITArgs.push_back(SharedLibs[i]);
|
2006-06-07 06:30:59 +08:00
|
|
|
}
|
2019-09-14 08:32:13 +08:00
|
|
|
JITArgs.push_back(Bitcode);
|
2006-06-07 06:30:59 +08:00
|
|
|
// Add optional parameters to the running program from Argv
|
2016-09-02 09:21:37 +08:00
|
|
|
for (unsigned i = 0, e = Args.size(); i != e; ++i)
|
2018-06-13 01:43:52 +08:00
|
|
|
JITArgs.push_back(Args[i]);
|
2006-06-07 06:30:59 +08:00
|
|
|
|
2016-09-02 09:21:37 +08:00
|
|
|
outs() << "<jit>";
|
|
|
|
outs().flush();
|
2018-05-14 20:53:11 +08:00
|
|
|
LLVM_DEBUG(errs() << "\nAbout to run:\t";
|
|
|
|
for (unsigned i = 0, e = JITArgs.size() - 1; i != e; ++i) errs()
|
|
|
|
<< " " << JITArgs[i];
|
|
|
|
errs() << "\n";);
|
|
|
|
LLVM_DEBUG(errs() << "\nSending output to " << OutputFile << "\n");
|
2018-06-13 01:43:52 +08:00
|
|
|
return RunProgramWithTimeout(LLIPath, JITArgs, InputFile, OutputFile,
|
2016-09-07 01:18:22 +08:00
|
|
|
OutputFile, Timeout, MemoryLimit);
|
2006-06-07 06:30:59 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/// createJIT - Try to find the LLI executable
|
|
|
|
///
|
2016-09-02 09:21:37 +08:00
|
|
|
AbstractInterpreter *
|
|
|
|
AbstractInterpreter::createJIT(const char *Argv0, std::string &Message,
|
|
|
|
const std::vector<std::string> *Args) {
|
[bugpoint] Find 'opt', etc., in bugpoint directory
Summary:
When bugpoint attempts to find the other executables it needs to run,
such as `opt` or `clang`, it tries searching the user's PATH. However,
in many cases, the 'bugpoint' executable is part of an LLVM build, and
the 'opt' executable it's looking for is in that same directory.
Many LLVM tools handle this case by using the `Paths` parameter of
`llvm::sys::findProgramByName`, passing the parent path of the currently
running executable. Do this same thing for bugpoint. However, to
preserve the current behavior exactly, first search the user's PATH,
and then search for 'opt' in the directory containing 'bugpoint'.
Test Plan:
`check-llvm`. Many of the existing bugpoint tests no longer need to use the
`--opt-command` option as a result of these changes.
Reviewers: MatzeB, silvas, davide
Reviewed By: MatzeB, davide
Subscribers: davide, llvm-commits
Differential Revision: https://reviews.llvm.org/D54884
llvm-svn: 348734
2018-12-10 08:56:13 +08:00
|
|
|
if (ErrorOr<std::string> LLIPath =
|
|
|
|
FindProgramByName("lli", Argv0, (void *)(intptr_t)&createJIT)) {
|
|
|
|
Message = "Found lli: " + *LLIPath + "\n";
|
|
|
|
return new JIT(*LLIPath, Args);
|
|
|
|
} else {
|
|
|
|
Message = LLIPath.getError().message() + "\n";
|
|
|
|
return nullptr;
|
2006-06-07 06:30:59 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//===---------------------------------------------------------------------===//
|
2015-10-15 04:29:54 +08:00
|
|
|
// CC abstraction
|
2006-06-07 06:30:59 +08:00
|
|
|
//
|
2009-07-11 05:39:28 +08:00
|
|
|
|
2018-06-13 01:43:52 +08:00
|
|
|
static bool IsARMArchitecture(std::vector<StringRef> Args) {
|
|
|
|
for (size_t I = 0; I < Args.size(); ++I) {
|
|
|
|
if (!Args[I].equals_lower("-arch"))
|
|
|
|
continue;
|
|
|
|
++I;
|
|
|
|
if (I == Args.size())
|
|
|
|
break;
|
|
|
|
if (Args[I].startswith_lower("arm"))
|
|
|
|
return true;
|
2009-07-11 05:39:28 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-09-07 01:18:22 +08:00
|
|
|
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) {
|
2018-06-13 01:43:52 +08:00
|
|
|
std::vector<StringRef> CCArgs;
|
2006-06-07 06:30:59 +08:00
|
|
|
|
2018-06-13 01:43:52 +08:00
|
|
|
CCArgs.push_back(CCPath);
|
2006-06-07 06:30:59 +08:00
|
|
|
|
2010-03-16 14:41:47 +08:00
|
|
|
if (TargetTriple.getArch() == Triple::x86)
|
2015-10-15 04:29:54 +08:00
|
|
|
CCArgs.push_back("-m32");
|
2010-03-16 14:41:47 +08:00
|
|
|
|
2016-09-02 09:21:37 +08:00
|
|
|
for (std::vector<std::string>::const_iterator I = ccArgs.begin(),
|
|
|
|
E = ccArgs.end();
|
|
|
|
I != E; ++I)
|
2018-06-13 01:43:52 +08:00
|
|
|
CCArgs.push_back(*I);
|
2009-03-03 07:13:18 +08:00
|
|
|
|
2006-06-07 06:30:59 +08:00
|
|
|
// Specify -x explicitly in case the extension is wonky
|
2010-03-16 14:41:47 +08:00
|
|
|
if (fileType != ObjectFile) {
|
2015-10-15 04:29:54 +08:00
|
|
|
CCArgs.push_back("-x");
|
2010-03-16 14:41:47 +08:00
|
|
|
if (fileType == CFile) {
|
2015-10-15 04:29:54 +08:00
|
|
|
CCArgs.push_back("c");
|
|
|
|
CCArgs.push_back("-fno-strict-aliasing");
|
2010-03-16 14:41:47 +08:00
|
|
|
} else {
|
2015-10-15 04:29:54 +08:00
|
|
|
CCArgs.push_back("assembler");
|
2010-03-16 14:41:47 +08:00
|
|
|
|
|
|
|
// For ARM architectures we don't want this flag. bugpoint isn't
|
|
|
|
// explicitly told what architecture it is working on, so we get
|
2015-10-15 04:29:54 +08:00
|
|
|
// it from cc flags
|
|
|
|
if (TargetTriple.isOSDarwin() && !IsARMArchitecture(CCArgs))
|
|
|
|
CCArgs.push_back("-force_cpusubtype_ALL");
|
2010-03-16 14:41:47 +08:00
|
|
|
}
|
2006-06-07 06:30:59 +08:00
|
|
|
}
|
2010-11-04 00:14:07 +08:00
|
|
|
|
2018-06-13 01:43:52 +08:00
|
|
|
CCArgs.push_back(ProgramFile); // Specify the input filename.
|
2010-11-04 00:14:07 +08:00
|
|
|
|
2015-10-15 04:29:54 +08:00
|
|
|
CCArgs.push_back("-x");
|
|
|
|
CCArgs.push_back("none");
|
|
|
|
CCArgs.push_back("-o");
|
2013-06-19 01:20:08 +08:00
|
|
|
|
|
|
|
SmallString<128> OutputBinary;
|
2014-06-13 11:07:50 +08:00
|
|
|
std::error_code EC =
|
2015-10-15 04:29:54 +08:00
|
|
|
sys::fs::createUniqueFile(ProgramFile + "-%%%%%%%.cc.exe", OutputBinary);
|
2013-06-19 01:20:08 +08:00
|
|
|
if (EC) {
|
|
|
|
errs() << "Error making unique filename: " << EC.message() << "\n";
|
2006-08-24 04:34:57 +08:00
|
|
|
exit(1);
|
|
|
|
}
|
2018-06-13 01:43:52 +08:00
|
|
|
CCArgs.push_back(OutputBinary); // Output to the right file...
|
2006-06-07 06:30:59 +08:00
|
|
|
|
2015-10-15 04:29:54 +08:00
|
|
|
// Add any arguments intended for CC. We locate them here because this is
|
2006-06-07 06:30:59 +08:00
|
|
|
// most likely -L and -l options that need to come before other libraries but
|
|
|
|
// after the source. Other options won't be sensitive to placement on the
|
|
|
|
// command line, so this should be safe.
|
2015-10-15 04:29:54 +08:00
|
|
|
for (unsigned i = 0, e = ArgsForCC.size(); i != e; ++i)
|
2018-06-13 01:43:52 +08:00
|
|
|
CCArgs.push_back(ArgsForCC[i]);
|
2006-06-07 06:30:59 +08:00
|
|
|
|
2016-09-02 09:21:37 +08:00
|
|
|
CCArgs.push_back("-lm"); // Hard-code the math library...
|
|
|
|
CCArgs.push_back("-O2"); // Optimize the program a bit...
|
2009-08-18 11:35:57 +08:00
|
|
|
if (TargetTriple.getArch() == Triple::sparc)
|
2015-10-15 04:29:54 +08:00
|
|
|
CCArgs.push_back("-mcpu=v9");
|
2006-06-07 06:30:59 +08:00
|
|
|
|
2016-09-02 09:21:37 +08:00
|
|
|
outs() << "<CC>";
|
|
|
|
outs().flush();
|
2018-05-14 20:53:11 +08:00
|
|
|
LLVM_DEBUG(errs() << "\nAbout to run:\t";
|
|
|
|
for (unsigned i = 0, e = CCArgs.size() - 1; i != e; ++i) errs()
|
|
|
|
<< " " << CCArgs[i];
|
|
|
|
errs() << "\n";);
|
2018-06-13 01:43:52 +08:00
|
|
|
if (RunProgramWithTimeout(CCPath, CCArgs, "", "", ""))
|
|
|
|
return ProcessFailure(CCPath, CCArgs);
|
2006-06-07 06:30:59 +08:00
|
|
|
|
2018-06-13 01:43:52 +08:00
|
|
|
std::vector<StringRef> ProgramArgs;
|
2010-07-25 07:02:11 +08:00
|
|
|
|
|
|
|
// Declared here so that the destructor only runs after
|
|
|
|
// ProgramArgs is used.
|
|
|
|
std::string Exec;
|
2006-06-07 06:30:59 +08:00
|
|
|
|
2013-06-14 00:22:26 +08:00
|
|
|
if (RemoteClientPath.empty())
|
2018-06-13 01:43:52 +08:00
|
|
|
ProgramArgs.push_back(OutputBinary);
|
2007-05-04 02:36:15 +08:00
|
|
|
else {
|
2018-06-13 01:43:52 +08:00
|
|
|
ProgramArgs.push_back(RemoteClientPath);
|
|
|
|
ProgramArgs.push_back(RemoteHost);
|
2009-08-05 17:32:53 +08:00
|
|
|
if (!RemoteUser.empty()) {
|
|
|
|
ProgramArgs.push_back("-l");
|
2018-06-13 01:43:52 +08:00
|
|
|
ProgramArgs.push_back(RemoteUser);
|
2009-08-05 17:32:53 +08:00
|
|
|
}
|
2009-07-11 05:39:28 +08:00
|
|
|
if (!RemotePort.empty()) {
|
|
|
|
ProgramArgs.push_back("-p");
|
2018-06-13 01:43:52 +08:00
|
|
|
ProgramArgs.push_back(RemotePort);
|
2009-07-11 05:39:28 +08:00
|
|
|
}
|
2008-09-09 14:11:26 +08:00
|
|
|
if (!RemoteExtra.empty()) {
|
2018-06-13 01:43:52 +08:00
|
|
|
ProgramArgs.push_back(RemoteExtra);
|
2008-09-09 14:11:26 +08:00
|
|
|
}
|
2007-05-04 02:36:15 +08:00
|
|
|
|
2009-07-21 01:15:03 +08:00
|
|
|
// Full path to the binary. We need to cd to the exec directory because
|
|
|
|
// there is a dylib there that the exec expects to find in the CWD
|
2016-09-02 09:21:37 +08:00
|
|
|
char *env_pwd = getenv("PWD");
|
2010-07-25 07:02:11 +08:00
|
|
|
Exec = "cd ";
|
2007-05-04 02:36:15 +08:00
|
|
|
Exec += env_pwd;
|
2009-07-21 01:15:03 +08:00
|
|
|
Exec += "; ./";
|
2007-05-04 02:36:15 +08:00
|
|
|
Exec += OutputBinary.c_str();
|
2018-06-13 01:43:52 +08:00
|
|
|
ProgramArgs.push_back(Exec);
|
2007-05-04 02:36:15 +08:00
|
|
|
}
|
|
|
|
|
2006-06-07 06:30:59 +08:00
|
|
|
// Add optional parameters to the running program from Argv
|
2010-04-12 13:08:25 +08:00
|
|
|
for (unsigned i = 0, e = Args.size(); i != e; ++i)
|
2018-06-13 01:43:52 +08:00
|
|
|
ProgramArgs.push_back(Args[i]);
|
2006-06-07 06:30:59 +08:00
|
|
|
|
|
|
|
// Now that we have a binary, run it!
|
2016-09-02 09:21:37 +08:00
|
|
|
outs() << "<program>";
|
|
|
|
outs().flush();
|
2018-05-14 20:53:11 +08:00
|
|
|
LLVM_DEBUG(
|
|
|
|
errs() << "\nAbout to run:\t";
|
|
|
|
for (unsigned i = 0, e = ProgramArgs.size() - 1; i != e; ++i) errs()
|
|
|
|
<< " " << ProgramArgs[i];
|
|
|
|
errs() << "\n";);
|
2006-06-07 06:30:59 +08:00
|
|
|
|
2011-03-31 21:04:19 +08:00
|
|
|
FileRemover OutputBinaryRemover(OutputBinary.str(), !SaveTemps);
|
2007-05-04 02:36:15 +08:00
|
|
|
|
2013-06-14 00:22:26 +08:00
|
|
|
if (RemoteClientPath.empty()) {
|
2018-05-14 20:53:11 +08:00
|
|
|
LLVM_DEBUG(errs() << "<run locally>");
|
2016-09-07 01:18:22 +08:00
|
|
|
std::string Error;
|
2018-06-13 01:43:52 +08:00
|
|
|
int ExitCode = RunProgramWithTimeout(OutputBinary.str(), ProgramArgs,
|
2013-06-13 23:47:11 +08:00
|
|
|
InputFile, OutputFile, OutputFile,
|
2016-09-07 01:18:22 +08:00
|
|
|
Timeout, MemoryLimit, &Error);
|
2011-05-21 08:56:46 +08:00
|
|
|
// Treat a signal (usually SIGSEGV) or timeout as part of the program output
|
|
|
|
// so that crash-causing miscompilation is handled seamlessly.
|
|
|
|
if (ExitCode < -1) {
|
2011-05-12 00:31:24 +08:00
|
|
|
std::ofstream outFile(OutputFile.c_str(), std::ios_base::app);
|
2016-09-07 01:18:22 +08:00
|
|
|
outFile << Error << '\n';
|
2011-05-12 00:31:24 +08:00
|
|
|
outFile.close();
|
|
|
|
}
|
|
|
|
return ExitCode;
|
2009-07-15 03:10:55 +08:00
|
|
|
} else {
|
2016-09-02 09:21:37 +08:00
|
|
|
outs() << "<run remotely>";
|
|
|
|
outs().flush();
|
2018-06-13 01:43:52 +08:00
|
|
|
return RunProgramRemotelyWithTimeout(RemoteClientPath, ProgramArgs,
|
2016-09-02 09:21:37 +08:00
|
|
|
InputFile, OutputFile, OutputFile,
|
|
|
|
Timeout, MemoryLimit);
|
2009-07-15 03:10:55 +08:00
|
|
|
}
|
2006-06-07 06:30:59 +08:00
|
|
|
}
|
|
|
|
|
2016-09-07 01:18:22 +08:00
|
|
|
Error CC::MakeSharedObject(const std::string &InputFile, FileType fileType,
|
|
|
|
std::string &OutputFile,
|
|
|
|
const std::vector<std::string> &ArgsForCC) {
|
2013-06-19 01:20:08 +08:00
|
|
|
SmallString<128> UniqueFilename;
|
2014-06-13 11:07:50 +08:00
|
|
|
std::error_code EC = sys::fs::createUniqueFile(
|
2013-07-06 05:01:08 +08:00
|
|
|
InputFile + "-%%%%%%%" + LTDL_SHLIB_EXT, UniqueFilename);
|
2013-06-19 01:20:08 +08:00
|
|
|
if (EC) {
|
|
|
|
errs() << "Error making unique filename: " << EC.message() << "\n";
|
2006-08-24 04:34:57 +08:00
|
|
|
exit(1);
|
|
|
|
}
|
2013-06-19 01:20:08 +08:00
|
|
|
OutputFile = UniqueFilename.str();
|
2006-06-07 06:30:59 +08:00
|
|
|
|
2018-06-13 01:43:52 +08:00
|
|
|
std::vector<StringRef> CCArgs;
|
2010-11-04 00:14:07 +08:00
|
|
|
|
2018-06-13 01:43:52 +08:00
|
|
|
CCArgs.push_back(CCPath);
|
2009-03-12 08:53:34 +08:00
|
|
|
|
2010-03-16 14:41:47 +08:00
|
|
|
if (TargetTriple.getArch() == Triple::x86)
|
2015-10-15 04:29:54 +08:00
|
|
|
CCArgs.push_back("-m32");
|
2010-03-16 14:41:47 +08:00
|
|
|
|
2016-09-02 09:21:37 +08:00
|
|
|
for (std::vector<std::string>::const_iterator I = ccArgs.begin(),
|
|
|
|
E = ccArgs.end();
|
|
|
|
I != E; ++I)
|
2018-06-13 01:43:52 +08:00
|
|
|
CCArgs.push_back(*I);
|
2009-03-12 08:53:34 +08:00
|
|
|
|
2006-06-07 06:30:59 +08:00
|
|
|
// Compile the C/asm file into a shared object
|
2010-03-16 14:41:47 +08:00
|
|
|
if (fileType != ObjectFile) {
|
2015-10-15 04:29:54 +08:00
|
|
|
CCArgs.push_back("-x");
|
|
|
|
CCArgs.push_back(fileType == AsmFile ? "assembler" : "c");
|
2010-03-16 14:41:47 +08:00
|
|
|
}
|
2015-10-15 04:29:54 +08:00
|
|
|
CCArgs.push_back("-fno-strict-aliasing");
|
2018-06-13 01:43:52 +08:00
|
|
|
CCArgs.push_back(InputFile); // Specify the input filename.
|
2015-10-15 04:29:54 +08:00
|
|
|
CCArgs.push_back("-x");
|
|
|
|
CCArgs.push_back("none");
|
2009-08-18 11:35:57 +08:00
|
|
|
if (TargetTriple.getArch() == Triple::sparc)
|
2016-09-02 09:21:37 +08:00
|
|
|
CCArgs.push_back("-G"); // Compile a shared library, `-G' for Sparc
|
2011-04-20 05:14:45 +08:00
|
|
|
else if (TargetTriple.isOSDarwin()) {
|
2009-08-18 11:35:57 +08:00
|
|
|
// link all source files into a single module in data segment, rather than
|
2010-11-04 00:14:07 +08:00
|
|
|
// generating blocks. dynamic_lookup requires that you set
|
2009-08-18 11:35:57 +08:00
|
|
|
// MACOSX_DEPLOYMENT_TARGET=10.3 in your env. FIXME: it would be better for
|
2015-10-15 04:29:54 +08:00
|
|
|
// bugpoint to just pass that in the environment of CC.
|
|
|
|
CCArgs.push_back("-single_module");
|
2016-09-02 09:21:37 +08:00
|
|
|
CCArgs.push_back("-dynamiclib"); // `-dynamiclib' for MacOS X/PowerPC
|
2015-10-15 04:29:54 +08:00
|
|
|
CCArgs.push_back("-undefined");
|
|
|
|
CCArgs.push_back("dynamic_lookup");
|
2009-08-18 11:35:57 +08:00
|
|
|
} else
|
2016-09-02 09:21:37 +08:00
|
|
|
CCArgs.push_back("-shared"); // `-shared' for Linux/X86, maybe others
|
2009-08-18 11:35:57 +08:00
|
|
|
|
2011-10-28 06:56:32 +08:00
|
|
|
if (TargetTriple.getArch() == Triple::x86_64)
|
2016-09-02 09:21:37 +08:00
|
|
|
CCArgs.push_back("-fPIC"); // Requires shared objs to contain PIC
|
2009-08-18 11:35:57 +08:00
|
|
|
|
|
|
|
if (TargetTriple.getArch() == Triple::sparc)
|
2015-10-15 04:29:54 +08:00
|
|
|
CCArgs.push_back("-mcpu=v9");
|
2006-06-07 06:30:59 +08:00
|
|
|
|
2015-10-15 04:29:54 +08:00
|
|
|
CCArgs.push_back("-o");
|
2018-06-13 01:43:52 +08:00
|
|
|
CCArgs.push_back(OutputFile); // Output to the right filename.
|
2015-10-15 04:29:54 +08:00
|
|
|
CCArgs.push_back("-O2"); // Optimize the program a bit.
|
2006-06-28 04:35:36 +08:00
|
|
|
|
2015-10-15 04:29:54 +08:00
|
|
|
// Add any arguments intended for CC. We locate them here because this is
|
2006-06-28 04:35:36 +08:00
|
|
|
// most likely -L and -l options that need to come before other libraries but
|
|
|
|
// after the source. Other options won't be sensitive to placement on the
|
|
|
|
// command line, so this should be safe.
|
2015-10-15 04:29:54 +08:00
|
|
|
for (unsigned i = 0, e = ArgsForCC.size(); i != e; ++i)
|
2018-06-13 01:43:52 +08:00
|
|
|
CCArgs.push_back(ArgsForCC[i]);
|
2006-06-28 04:35:36 +08:00
|
|
|
|
2016-09-02 09:21:37 +08:00
|
|
|
outs() << "<CC>";
|
|
|
|
outs().flush();
|
2018-05-14 20:53:11 +08:00
|
|
|
LLVM_DEBUG(errs() << "\nAbout to run:\t";
|
|
|
|
for (unsigned i = 0, e = CCArgs.size() - 1; i != e; ++i) errs()
|
|
|
|
<< " " << CCArgs[i];
|
|
|
|
errs() << "\n";);
|
2018-06-13 01:43:52 +08:00
|
|
|
if (RunProgramWithTimeout(CCPath, CCArgs, "", "", ""))
|
|
|
|
return ProcessFailure(CCPath, CCArgs);
|
2017-06-29 07:15:16 +08:00
|
|
|
return Error::success();
|
2006-06-07 06:30:59 +08:00
|
|
|
}
|
|
|
|
|
2015-10-15 04:29:54 +08:00
|
|
|
/// create - Try to find the CC executable
|
2006-06-07 06:30:59 +08:00
|
|
|
///
|
[bugpoint] Find 'opt', etc., in bugpoint directory
Summary:
When bugpoint attempts to find the other executables it needs to run,
such as `opt` or `clang`, it tries searching the user's PATH. However,
in many cases, the 'bugpoint' executable is part of an LLVM build, and
the 'opt' executable it's looking for is in that same directory.
Many LLVM tools handle this case by using the `Paths` parameter of
`llvm::sys::findProgramByName`, passing the parent path of the currently
running executable. Do this same thing for bugpoint. However, to
preserve the current behavior exactly, first search the user's PATH,
and then search for 'opt' in the directory containing 'bugpoint'.
Test Plan:
`check-llvm`. Many of the existing bugpoint tests no longer need to use the
`--opt-command` option as a result of these changes.
Reviewers: MatzeB, silvas, davide
Reviewed By: MatzeB, davide
Subscribers: davide, llvm-commits
Differential Revision: https://reviews.llvm.org/D54884
llvm-svn: 348734
2018-12-10 08:56:13 +08:00
|
|
|
CC *CC::create(const char *Argv0, std::string &Message,
|
|
|
|
const std::string &CCBinary,
|
2016-09-02 09:21:37 +08:00
|
|
|
const std::vector<std::string> *Args) {
|
[bugpoint] Find 'opt', etc., in bugpoint directory
Summary:
When bugpoint attempts to find the other executables it needs to run,
such as `opt` or `clang`, it tries searching the user's PATH. However,
in many cases, the 'bugpoint' executable is part of an LLVM build, and
the 'opt' executable it's looking for is in that same directory.
Many LLVM tools handle this case by using the `Paths` parameter of
`llvm::sys::findProgramByName`, passing the parent path of the currently
running executable. Do this same thing for bugpoint. However, to
preserve the current behavior exactly, first search the user's PATH,
and then search for 'opt' in the directory containing 'bugpoint'.
Test Plan:
`check-llvm`. Many of the existing bugpoint tests no longer need to use the
`--opt-command` option as a result of these changes.
Reviewers: MatzeB, silvas, davide
Reviewed By: MatzeB, davide
Subscribers: davide, llvm-commits
Differential Revision: https://reviews.llvm.org/D54884
llvm-svn: 348734
2018-12-10 08:56:13 +08:00
|
|
|
auto CCPath = FindProgramByName(CCBinary, Argv0, (void *)(intptr_t)&create);
|
2015-10-15 04:29:54 +08:00
|
|
|
if (!CCPath) {
|
|
|
|
Message = "Cannot find `" + CCBinary + "' in PATH: " +
|
|
|
|
CCPath.getError().message() + "\n";
|
2014-04-25 12:24:47 +08:00
|
|
|
return nullptr;
|
2006-06-07 06:30:59 +08:00
|
|
|
}
|
|
|
|
|
2013-06-14 03:25:37 +08:00
|
|
|
std::string RemoteClientPath;
|
2014-11-04 09:29:59 +08:00
|
|
|
if (!RemoteClient.empty()) {
|
|
|
|
auto Path = sys::findProgramByName(RemoteClient);
|
|
|
|
if (!Path) {
|
|
|
|
Message = "Cannot find `" + RemoteClient + "' in PATH: " +
|
|
|
|
Path.getError().message() + "\n";
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
RemoteClientPath = *Path;
|
|
|
|
}
|
2007-05-04 02:36:15 +08:00
|
|
|
|
2015-10-15 04:29:54 +08:00
|
|
|
Message = "Found CC: " + *CCPath + "\n";
|
|
|
|
return new CC(*CCPath, RemoteClientPath, Args);
|
2006-06-07 06:30:59 +08:00
|
|
|
}
|