#define DEBUG_TYPE "toolrunner"
#include "ToolRunner.h"
-#include "llvm/System/Program.h"
+#include "llvm/Support/Program.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/FileUtilities.h"
const sys::Path &StdOutFile,
const sys::Path &StdErrFile,
unsigned NumSeconds = 0,
- unsigned MemoryLimit = 0) {
+ unsigned MemoryLimit = 0,
+ std::string *ErrMsg = 0) {
const sys::Path* redirects[3];
redirects[0] = &StdInFile;
redirects[1] = &StdOutFile;
return
sys::Program::ExecuteAndWait(ProgramPath, Args, 0, redirects,
- NumSeconds, MemoryLimit);
+ NumSeconds, MemoryLimit, ErrMsg);
}
/// RunProgramRemotelyWithTimeout - This function runs the given program
return ReturnCode;
}
-static std::string ProcessFailure(sys::Path ProgPath, const char** Args) {
+static std::string ProcessFailure(sys::Path ProgPath, const char** Args,
+ unsigned Timeout = 0,
+ unsigned MemoryLimit = 0) {
std::ostringstream OS;
OS << "\nError running tool:\n ";
for (const char **Arg = Args; *Arg; ++Arg)
OS << " " << *Arg;
OS << "\n";
-
+
// Rerun the compiler, capturing any error messages to print them.
sys::Path ErrorFilename("bugpoint.program_error_messages");
std::string ErrMsg;
exit(1);
}
RunProgramWithTimeout(ProgPath, Args, sys::Path(""), ErrorFilename,
- ErrorFilename); // FIXME: check return code ?
+ ErrorFilename, Timeout, MemoryLimit);
+ // FIXME: check return code ?
// Print out the error messages generated by GCC if possible...
std::ifstream ErrorFile(ErrorFilename.c_str());
LLIArgs.push_back(LLIPath.c_str());
LLIArgs.push_back("-force-interpreter=true");
- for (std::vector<std::string>::const_iterator i = SharedLibs.begin(), e = SharedLibs.end(); i != e; ++i) {
+ for (std::vector<std::string>::const_iterator i = SharedLibs.begin(),
+ e = SharedLibs.end(); i != e; ++i) {
LLIArgs.push_back("-load");
LLIArgs.push_back((*i).c_str());
}
);
return RunProgramWithTimeout(sys::Path(LLIPath), &LLIArgs[0],
sys::Path(InputFile), sys::Path(OutputFile), sys::Path(OutputFile),
- Timeout, MemoryLimit);
+ Timeout, MemoryLimit, Error);
}
// LLI create method - Try to find the LLI executable
std::string &Message,
const std::vector<std::string> *ToolArgs) {
std::string LLIPath =
- FindExecutable("lli", Argv0, (void *)(intptr_t)&createLLI).str();
+ PrependMainExecutablePath("lli", Argv0, (void *)(intptr_t)&createLLI).str();
if (!LLIPath.empty()) {
Message = "Found lli: " + LLIPath + "\n";
return new LLI(LLIPath, ToolArgs);
}
- Message = "Cannot find `lli' in executable directory or PATH!\n";
+ Message = "Cannot find `lli' in executable directory!\n";
return 0;
}
// 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
+// for example, to invoke a cross compiler for code generation followed by
// a simulator that executes the generated binary.
namespace {
class CustomExecutor : public AbstractInterpreter {
return RunProgramWithTimeout(
sys::Path(ExecutionCommand),
- &ProgramArgs[0], sys::Path(InputFile), sys::Path(OutputFile),
- sys::Path(OutputFile), Timeout, MemoryLimit);
+ &ProgramArgs[0], sys::Path(InputFile), sys::Path(OutputFile),
+ sys::Path(OutputFile), Timeout, MemoryLimit, Error);
}
// Custom execution environment create method, takes the execution command
// 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 program sees only a single
- // command line argument (with spaces in it: "foo bar" instead
+ // command line argument (with spaces in it: "foo bar" instead
// of "foo" and "bar").
- // code borrowed from:
+ // code borrowed from:
// http://oopweb.com/CPP/Documents/CPPHOWTO/Volume/C++Programming-HOWTO-7.html
- std::string::size_type lastPos =
+ std::string::size_type lastPos =
ExecCommandLine.find_first_not_of(delimiters, 0);
- std::string::size_type pos =
+ std::string::size_type pos =
ExecCommandLine.find_first_of(delimiters, lastPos);
while (std::string::npos != pos || std::string::npos != lastPos) {
std::string CmdPath = sys::Program::FindProgramByName(Command).str();
if (CmdPath.empty()) {
- Message =
- std::string("Cannot find '") + Command +
- "' in executable directory or PATH!\n";
+ Message =
+ std::string("Cannot find '") + Command +
+ "' in PATH!\n";
return 0;
}
//===----------------------------------------------------------------------===//
// LLC Implementation of AbstractIntepreter interface
//
-GCC::FileType LLC::OutputCode(const std::string &Bitcode,
- sys::Path &OutputAsmFile, std::string &Error) {
+GCC::FileType LLC::OutputCode(const std::string &Bitcode,
+ sys::Path &OutputAsmFile, std::string &Error,
+ unsigned Timeout, unsigned MemoryLimit) {
const char *Suffix = (UseIntegratedAssembler ? ".llc.o" : ".llc.s");
sys::Path uniqueFile(Bitcode + Suffix);
std::string ErrMsg;
LLCArgs.push_back("-o");
LLCArgs.push_back(OutputAsmFile.c_str()); // Output to the Asm file
LLCArgs.push_back(Bitcode.c_str()); // This is the input bitcode
-
+
if (UseIntegratedAssembler)
LLCArgs.push_back("-filetype=obj");
-
+
LLCArgs.push_back (0);
outs() << (UseIntegratedAssembler ? "<llc-ia>" : "<llc>");
errs() << "\n";
);
if (RunProgramWithTimeout(sys::Path(LLCPath), &LLCArgs[0],
- sys::Path(), sys::Path(), sys::Path()))
- Error = ProcessFailure(sys::Path(LLCPath), &LLCArgs[0]);
- return UseIntegratedAssembler ? GCC::ObjectFile : GCC::AsmFile;
+ sys::Path(), sys::Path(), sys::Path(),
+ Timeout, MemoryLimit))
+ Error = ProcessFailure(sys::Path(LLCPath), &LLCArgs[0],
+ Timeout, MemoryLimit);
+ return UseIntegratedAssembler ? GCC::ObjectFile : GCC::AsmFile;
}
-void LLC::compileProgram(const std::string &Bitcode, std::string *Error) {
+void LLC::compileProgram(const std::string &Bitcode, std::string *Error,
+ unsigned Timeout, unsigned MemoryLimit) {
sys::Path OutputAsmFile;
- OutputCode(Bitcode, OutputAsmFile, *Error);
+ OutputCode(Bitcode, OutputAsmFile, *Error, Timeout, MemoryLimit);
OutputAsmFile.eraseFromDisk();
}
unsigned MemoryLimit) {
sys::Path OutputAsmFile;
- GCC::FileType FileKind = OutputCode(Bitcode, OutputAsmFile, *Error);
+ GCC::FileType FileKind = OutputCode(Bitcode, OutputAsmFile, *Error, Timeout,
+ MemoryLimit);
FileRemover OutFileRemover(OutputAsmFile, !SaveTemps);
std::vector<std::string> GCCArgs(ArgsForGCC);
const std::vector<std::string> *GCCArgs,
bool UseIntegratedAssembler) {
std::string LLCPath =
- FindExecutable("llc", Argv0, (void *)(intptr_t)&createLLC).str();
+ PrependMainExecutablePath("llc", Argv0, (void *)(intptr_t)&createLLC).str();
if (LLCPath.empty()) {
- Message = "Cannot find `llc' in executable directory or PATH!\n";
+ Message = "Cannot find `llc' in executable directory!\n";
return 0;
}
const std::vector<std::string> &GCCArgs =
std::vector<std::string>(),
const std::vector<std::string> &SharedLibs =
- std::vector<std::string>(),
+ std::vector<std::string>(),
unsigned Timeout = 0,
unsigned MemoryLimit = 0);
};
DEBUG(errs() << "\nSending output to " << OutputFile << "\n");
return RunProgramWithTimeout(sys::Path(LLIPath), &JITArgs[0],
sys::Path(InputFile), sys::Path(OutputFile), sys::Path(OutputFile),
- Timeout, MemoryLimit);
+ Timeout, MemoryLimit, Error);
}
/// createJIT - Try to find the LLI executable
AbstractInterpreter *AbstractInterpreter::createJIT(const char *Argv0,
std::string &Message, const std::vector<std::string> *Args) {
std::string LLIPath =
- FindExecutable("lli", Argv0, (void *)(intptr_t)&createJIT).str();
+ PrependMainExecutablePath("lli", Argv0, (void *)(intptr_t)&createJIT).str();
if (!LLIPath.empty()) {
Message = "Found lli: " + LLIPath + "\n";
return new JIT(LLIPath, Args);
}
- Message = "Cannot find `lli' in executable directory or PATH!\n";
+ Message = "Cannot find `lli' in executable directory!\n";
return 0;
}
GCC::FileType CBE::OutputCode(const std::string &Bitcode,
- sys::Path &OutputCFile, std::string &Error) {
+ sys::Path &OutputCFile, std::string &Error,
+ unsigned Timeout, unsigned MemoryLimit) {
sys::Path uniqueFile(Bitcode+".cbe.c");
std::string ErrMsg;
if (uniqueFile.makeUnique(true, &ErrMsg)) {
errs() << "\n";
);
if (RunProgramWithTimeout(LLCPath, &LLCArgs[0], sys::Path(), sys::Path(),
- sys::Path()))
- Error = ProcessFailure(LLCPath, &LLCArgs[0]);
+ sys::Path(), Timeout, MemoryLimit))
+ Error = ProcessFailure(LLCPath, &LLCArgs[0], Timeout, MemoryLimit);
return GCC::CFile;
}
-void CBE::compileProgram(const std::string &Bitcode, std::string *Error) {
+void CBE::compileProgram(const std::string &Bitcode, std::string *Error,
+ unsigned Timeout, unsigned MemoryLimit) {
sys::Path OutputCFile;
- OutputCode(Bitcode, OutputCFile, *Error);
+ OutputCode(Bitcode, OutputCFile, *Error, Timeout, MemoryLimit);
OutputCFile.eraseFromDisk();
}
unsigned Timeout,
unsigned MemoryLimit) {
sys::Path OutputCFile;
- OutputCode(Bitcode, OutputCFile, *Error);
+ OutputCode(Bitcode, OutputCFile, *Error, Timeout, MemoryLimit);
FileRemover CFileRemove(OutputCFile, !SaveTemps);
///
CBE *AbstractInterpreter::createCBE(const char *Argv0,
std::string &Message,
- const std::string &GCCBinary,
+ const std::string &GCCBinary,
const std::vector<std::string> *Args,
const std::vector<std::string> *GCCArgs) {
sys::Path LLCPath =
- FindExecutable("llc", Argv0, (void *)(intptr_t)&createCBE);
+ PrependMainExecutablePath("llc", Argv0, (void *)(intptr_t)&createCBE);
if (LLCPath.isEmpty()) {
Message =
- "Cannot find `llc' in executable directory or PATH!\n";
+ "Cannot find `llc' in executable directory!\n";
return 0;
}
// GCC abstraction
//
-static bool IsARMArchitecture(std::vector<std::string> Args) {
- for (std::vector<std::string>::const_iterator
+static bool IsARMArchitecture(std::vector<const char*> Args) {
+ for (std::vector<const char*>::const_iterator
I = Args.begin(), E = Args.end(); I != E; ++I) {
if (StringRef(*I).equals_lower("-arch")) {
++I;
// explicitly told what architecture it is working on, so we get
// it from gcc flags
if ((TargetTriple.getOS() == Triple::Darwin) &&
- !IsARMArchitecture(ArgsForGCC))
+ !IsARMArchitecture(GCCArgs))
GCCArgs.push_back("-force_cpusubtype_ALL");
}
}
-
+
GCCArgs.push_back(ProgramFile.c_str()); // Specify the input filename.
-
+
GCCArgs.push_back("-x");
GCCArgs.push_back("none");
GCCArgs.push_back("-o");
std::vector<const char*> ProgramArgs;
+ // Declared here so that the destructor only runs after
+ // ProgramArgs is used.
+ std::string Exec;
+
if (RemoteClientPath.isEmpty())
ProgramArgs.push_back(OutputBinary.c_str());
else {
// 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
char* env_pwd = getenv("PWD");
- std::string Exec = "cd ";
+ Exec = "cd ";
Exec += env_pwd;
Exec += "; ./";
Exec += OutputBinary.c_str();
DEBUG(errs() << "<run locally>");
return RunProgramWithTimeout(OutputBinary, &ProgramArgs[0],
sys::Path(InputFile), sys::Path(OutputFile), sys::Path(OutputFile),
- Timeout, MemoryLimit);
+ Timeout, MemoryLimit, Error);
} else {
outs() << "<run remotely>"; outs().flush();
return RunProgramRemotelyWithTimeout(sys::Path(RemoteClientPath),
OutputFile = uniqueFilename.str();
std::vector<const char*> GCCArgs;
-
+
GCCArgs.push_back(GCCPath.c_str());
if (TargetTriple.getArch() == Triple::x86)
GCCArgs.push_back("-G"); // Compile a shared library, `-G' for Sparc
else if (TargetTriple.getOS() == Triple::Darwin) {
// link all source files into a single module in data segment, rather than
- // generating blocks. dynamic_lookup requires that you set
+ // generating blocks. dynamic_lookup requires that you set
// MACOSX_DEPLOYMENT_TARGET=10.3 in your env. FIXME: it would be better for
// bugpoint to just pass that in the environment of GCC.
GCCArgs.push_back("-single_module");
GCCArgs.push_back(OutputFile.c_str()); // Output to the right filename.
GCCArgs.push_back("-O2"); // Optimize the program a bit.
-
-
+
+
// Add any arguments intended for GCC. We locate them here because this is
// 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
GCCArgs.push_back(ArgsForGCC[i].c_str());
GCCArgs.push_back(0); // NULL terminator
-
+
outs() << "<gcc>"; outs().flush();
DEBUG(errs() << "\nAbout to run:\t";
const std::vector<std::string> *Args) {
sys::Path GCCPath = sys::Program::FindProgramByName(GCCBinary);
if (GCCPath.isEmpty()) {
- Message = "Cannot find `"+ GCCBinary +"' in executable directory or PATH!\n";
+ Message = "Cannot find `"+ GCCBinary +"' in PATH!\n";
return 0;
}