Adding out-of-process execution support to lli.

At this time only Unix-based systems are supported.  Windows has stubs and should re-route to the simulated mode.

Thanks to Sriram Murali for contributions to this patch.




git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191843 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Andrew Kaylor
2013-10-02 17:12:36 +00:00
parent af7ae9d689
commit 0ab5c6c16b
22 changed files with 994 additions and 23 deletions

View File

@ -41,6 +41,7 @@
#include "llvm/Support/PluginLoader.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/Process.h"
#include "llvm/Support/Program.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/TargetSelect.h"
@ -83,6 +84,18 @@ namespace {
cl::desc("Execute MCJIT'ed code in a separate process."),
cl::init(false));
// Manually specify the child process for remote execution. This overrides
// the simulated remote execution that allocates address space for child
// execution. The child process resides in the disk and communicates with lli
// via stdin/stdout pipes.
cl::opt<std::string>
MCJITRemoteProcess("mcjit-remote-process",
cl::desc("Specify the filename of the process to launch "
"for remote MCJIT execution. If none is specified,"
"\n\tremote execution will be simulated in-process."),
cl::value_desc("filename"),
cl::init(""));
// Determine optimization level.
cl::opt<char>
OptLevel("O",
@ -481,30 +494,50 @@ int main(int argc, char **argv, char * const *envp) {
// Everything is prepared now, so lay out our program for the target
// address space, assign the section addresses to resolve any relocations,
// and send it to the target.
RemoteTarget Target;
Target.create();
OwningPtr<RemoteTarget> Target;
if (!MCJITRemoteProcess.empty()) { // Remote execution on a child process
if (!RemoteTarget::hostSupportsExternalRemoteTarget()) {
errs() << "Warning: host does not support external remote targets.\n"
<< " Defaulting to simulated remote execution\n";
Target.reset(RemoteTarget::createRemoteTarget());
} else {
std::string ChildEXE = sys::FindProgramByName(MCJITRemoteProcess);
if (ChildEXE == "") {
errs() << "Unable to find child target: '\''" << MCJITRemoteProcess << "\'\n";
return -1;
}
Target.reset(RemoteTarget::createExternalRemoteTarget(MCJITRemoteProcess));
}
} else {
// No child process name provided, use simulated remote execution.
Target.reset(RemoteTarget::createRemoteTarget());
}
// Create the remote target
Target->create();
// Trigger compilation.
EE->generateCodeForModule(Mod);
// Layout the target memory.
layoutRemoteTargetMemory(&Target, MM);
layoutRemoteTargetMemory(Target.get(), MM);
// Since we're executing in a (at least simulated) remote address space,
// we can't use the ExecutionEngine::runFunctionAsMain(). We have to
// grab the function address directly here and tell the remote target
// to execute the function.
// FIXME: argv and envp handling.
uint64_t Entry = (uint64_t)EE->getPointerToFunction(EntryFn);
uint64_t Entry = EE->getFunctionAddress(EntryFn->getName().str());
DEBUG(dbgs() << "Executing '" << EntryFn->getName() << "' at 0x"
<< format("%llx", Entry) << "\n");
if (Target.executeCode(Entry, Result))
errs() << "ERROR: " << Target.getErrorMsg() << "\n";
if (Target->executeCode(Entry, Result))
errs() << "ERROR: " << Target->getErrorMsg() << "\n";
Target.stop();
} else {
Target->stop();
} else { // !RemoteMCJIT
// Trigger compilation separately so code regions that need to be
// invalidated will be known.
(void)EE->getPointerToFunction(EntryFn);