[llvm] ac2daac - [ORC][examples] Port LLJITWithRemoteDebugging to SimpleRemoteEPC
Stefan Gränitz via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 29 01:24:52 PDT 2021
Author: Stefan Gränitz
Date: 2021-09-29T10:20:41+02:00
New Revision: ac2daacb310cbb1732de1c139be7a0e8e982169e
URL: https://github.com/llvm/llvm-project/commit/ac2daacb310cbb1732de1c139be7a0e8e982169e
DIFF: https://github.com/llvm/llvm-project/commit/ac2daacb310cbb1732de1c139be7a0e8e982169e.diff
LOG: [ORC][examples] Port LLJITWithRemoteDebugging to SimpleRemoteEPC
Though this is a full port of the example, it is not yet fully functional due to a threading issue in the SimpleRemoteEPC implementation. The issue was discussed in D110530, but it needs a more thorough solution. For now we are dropping the dependency to the old `OrcRPC` here (it's been the last use-case in-tree). The test for the example is under review in ... and will be re-enabled once the threading issue is solved.
Added:
Modified:
llvm/examples/OrcV2Examples/LLJITWithRemoteDebugging/LLJITWithRemoteDebugging.cpp
llvm/examples/OrcV2Examples/LLJITWithRemoteDebugging/RemoteJITUtils.cpp
llvm/examples/OrcV2Examples/LLJITWithRemoteDebugging/RemoteJITUtils.h
Removed:
################################################################################
diff --git a/llvm/examples/OrcV2Examples/LLJITWithRemoteDebugging/LLJITWithRemoteDebugging.cpp b/llvm/examples/OrcV2Examples/LLJITWithRemoteDebugging/LLJITWithRemoteDebugging.cpp
index 227ad09d7ae79..d88a4172a53cc 100644
--- a/llvm/examples/OrcV2Examples/LLJITWithRemoteDebugging/LLJITWithRemoteDebugging.cpp
+++ b/llvm/examples/OrcV2Examples/LLJITWithRemoteDebugging/LLJITWithRemoteDebugging.cpp
@@ -79,6 +79,8 @@
#include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"
#include "llvm/ExecutionEngine/Orc/LLJIT.h"
+#include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
+#include "llvm/ExecutionEngine/Orc/SimpleRemoteEPC.h"
#include "llvm/ExecutionEngine/Orc/ThreadSafeModule.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Error.h"
@@ -116,9 +118,9 @@ static cl::opt<std::string>
OOPExecutor("executor", cl::desc("Set the out-of-process executor"),
cl::value_desc("filename"));
-// Network address of a running executor process that we can connected through a
-// TCP socket. It may run locally or on a remote machine.
-static cl::opt<std::string> OOPExecutorConnect(
+// Network address of a running executor process that we can connect via TCP. It
+// may run locally or on a remote machine.
+static cl::opt<std::string> OOPExecutorConnectTCP(
"connect",
cl::desc("Connect to an out-of-process executor through a TCP socket"),
cl::value_desc("<hostname>:<port>"));
@@ -133,41 +135,6 @@ static cl::opt<bool>
ExitOnError ExitOnErr;
-static std::unique_ptr<JITLinkExecutor> connectExecutor(const char *Argv0) {
- // Connect to a running out-of-process executor through a TCP socket.
- if (!OOPExecutorConnect.empty()) {
- std::unique_ptr<TCPSocketJITLinkExecutor> Exec =
- ExitOnErr(JITLinkExecutor::ConnectTCPSocket(OOPExecutorConnect,
- std::ref(ExitOnErr)));
-
- outs() << "Connected to executor at " << OOPExecutorConnect << "\n";
- if (WaitForDebugger) {
- outs() << "Attach a debugger and press any key to continue.\n";
- fflush(stdin);
- getchar();
- }
-
- return std::move(Exec);
- }
-
- // Launch a out-of-process executor locally in a child process.
- std::unique_ptr<ChildProcessJITLinkExecutor> Exec = ExitOnErr(
- OOPExecutor.empty() ? JITLinkExecutor::FindLocal(Argv0)
- : JITLinkExecutor::CreateLocal(OOPExecutor));
-
- outs() << "Found out-of-process executor: " << Exec->getPath() << "\n";
-
- ExitOnErr(Exec->launch(std::ref(ExitOnErr)));
- if (WaitForDebugger) {
- outs() << "Launched executor in subprocess: " << Exec->getPID() << "\n"
- << "Attach a debugger and press any key to continue.\n";
- fflush(stdin);
- getchar();
- }
-
- return std::move(Exec);
-}
-
int main(int argc, char *argv[]) {
InitLLVM X(argc, argv);
@@ -177,8 +144,27 @@ int main(int argc, char *argv[]) {
ExitOnErr.setBanner(std::string(argv[0]) + ": ");
cl::ParseCommandLineOptions(argc, argv, "LLJITWithRemoteDebugging");
- // Launch/connect the out-of-process executor.
- std::unique_ptr<JITLinkExecutor> Executor = connectExecutor(argv[0]);
+ std::unique_ptr<SimpleRemoteEPC> EPC;
+ if (OOPExecutorConnectTCP.getNumOccurrences() > 0) {
+ // Connect to a running out-of-process executor through a TCP socket.
+ EPC = ExitOnErr(connectTCPSocket(OOPExecutorConnectTCP));
+ outs() << "Connected to executor at " << OOPExecutorConnectTCP << "\n";
+ } else {
+ // Launch an out-of-process executor locally in a child process.
+ std::string Path =
+ OOPExecutor.empty() ? findLocalExecutor(argv[0]) : OOPExecutor;
+ outs() << "Found out-of-process executor: " << Path << "\n";
+
+ uint64_t PID;
+ std::tie(EPC, PID) = ExitOnErr(launchLocalExecutor(Path));
+ outs() << "Launched executor in subprocess: " << PID << "\n";
+ }
+
+ if (WaitForDebugger) {
+ outs() << "Attach a debugger and press any key to continue.\n";
+ fflush(stdin);
+ getchar();
+ }
// Load the given IR files.
std::vector<ThreadSafeModule> TSMs;
@@ -211,44 +197,51 @@ int main(int argc, char *argv[]) {
JTMB.setRelocationModel(Reloc::PIC_);
// Create LLJIT and destroy it before disconnecting the target process.
- {
- std::unique_ptr<ExecutionSession> ES = Executor->startSession();
-
- outs() << "Initializing LLJIT for remote executor\n";
- auto J = ExitOnErr(LLJITBuilder()
- .setExecutionSession(std::move(ES))
- .setJITTargetMachineBuilder(std::move(JTMB))
- .setObjectLinkingLayerCreator(std::ref(*Executor))
- .create());
-
- // Add plugin for debug support.
- ExitOnErr(Executor->addDebugSupport(J->getObjLinkingLayer()));
-
- // Load required shared libraries on the remote target and add a generator
- // for each of it, so the compiler can lookup their symbols.
- for (const std::string &Path : Dylibs)
- J->getMainJITDylib().addGenerator(ExitOnErr(Executor->loadDylib(Path)));
-
- // Add the loaded IR module to the JIT. This will set up symbol tables and
- // prepare for materialization.
- for (ThreadSafeModule &TSM : TSMs)
- ExitOnErr(J->addIRModule(std::move(TSM)));
-
- // The example uses a non-lazy JIT for simplicity. Thus, looking up the main
- // function will materialize all reachable code. It also triggers debug
- // registration in the remote target process.
- JITEvaluatedSymbol MainFn = ExitOnErr(J->lookup("main"));
-
- outs() << "Running: main(";
- int Pos = 0;
- for (const std::string &Arg : InputArgv)
- outs() << (Pos++ == 0 ? "" : ", ") << "\"" << Arg << "\"";
- outs() << ")\n";
+ outs() << "Initializing LLJIT for remote executor\n";
+ auto J = ExitOnErr(LLJITBuilder()
+ .setExecutorProcessControl(std::move(EPC))
+ .setJITTargetMachineBuilder(std::move(JTMB))
+ .setObjectLinkingLayerCreator([&](auto &ES, const auto &TT) {
+ return std::make_unique<ObjectLinkingLayer>(ES);
+ })
+ .create());
+
+ // Add plugin for debug support.
+ ExitOnErr(addDebugSupport(J->getObjLinkingLayer()));
+
+ // Load required shared libraries on the remote target and add a generator
+ // for each of it, so the compiler can lookup their symbols.
+ for (const std::string &Path : Dylibs)
+ J->getMainJITDylib().addGenerator(
+ ExitOnErr(loadDylib(J->getExecutionSession(), Path)));
+
+ // Add the loaded IR module to the JIT. This will set up symbol tables and
+ // prepare for materialization.
+ for (ThreadSafeModule &TSM : TSMs)
+ ExitOnErr(J->addIRModule(std::move(TSM)));
+
+ // The example uses a non-lazy JIT for simplicity. Thus, looking up the main
+ // function will materialize all reachable code. It also triggers debug
+ // registration in the remote target process.
+ JITEvaluatedSymbol MainFn = ExitOnErr(J->lookup("main"));
+
+ outs() << "Running: main(";
+ int Pos = 0;
+ std::vector<std::string> ActualArgv{"LLJITWithRemoteDebugging"};
+ for (const std::string &Arg : InputArgv) {
+ outs() << (Pos++ == 0 ? "" : ", ") << "\"" << Arg << "\"";
+ ActualArgv.push_back(Arg);
+ }
+ outs() << ")\n";
- // Execute the code in the remote target process and dump the result. With
- // the debugger attached to the target, it should be possible to inspect the
- // JITed code as if it was compiled statically.
- int Result = ExitOnErr(Executor->runAsMain(MainFn, InputArgv));
+ // Execute the code in the remote target process and dump the result. With
+ // the debugger attached to the target, it should be possible to inspect the
+ // JITed code as if it was compiled statically.
+ {
+ JITTargetAddress MainFnAddr = MainFn.getAddress();
+ ExecutorProcessControl &EPC =
+ J->getExecutionSession().getExecutorProcessControl();
+ int Result = ExitOnErr(EPC.runAsMain(ExecutorAddr(MainFnAddr), ActualArgv));
outs() << "Exit code: " << Result << "\n";
}
diff --git a/llvm/examples/OrcV2Examples/LLJITWithRemoteDebugging/RemoteJITUtils.cpp b/llvm/examples/OrcV2Examples/LLJITWithRemoteDebugging/RemoteJITUtils.cpp
index fdc925d8ea39d..a697c32cbd541 100644
--- a/llvm/examples/OrcV2Examples/LLJITWithRemoteDebugging/RemoteJITUtils.cpp
+++ b/llvm/examples/OrcV2Examples/LLJITWithRemoteDebugging/RemoteJITUtils.cpp
@@ -11,12 +11,10 @@
#include "llvm/ExecutionEngine/Orc/DebugObjectManagerPlugin.h"
#include "llvm/ExecutionEngine/Orc/EPCDebugObjectRegistrar.h"
#include "llvm/ExecutionEngine/Orc/EPCDynamicLibrarySearchGenerator.h"
-#include "llvm/ExecutionEngine/Orc/OrcRPCExecutorProcessControl.h"
-#include "llvm/ExecutionEngine/Orc/Shared/RPCUtils.h"
+#include "llvm/ExecutionEngine/Orc/Shared/SimpleRemoteEPCUtils.h"
#include "llvm/ExecutionEngine/Orc/TargetProcess/JITLoaderGDB.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
-#include "llvm/Support/ToolOutputFile.h"
#ifdef LLVM_ON_UNIX
#include <netdb.h>
@@ -28,176 +26,55 @@
using namespace llvm;
using namespace llvm::orc;
-namespace llvm {
-namespace orc {
-
-class RemoteExecutorProcessControl
- : public OrcRPCExecutorProcessControlBase<
- shared::MultiThreadedRPCEndpoint<JITLinkExecutor::RPCChannel>> {
-public:
- using RPCChannel = JITLinkExecutor::RPCChannel;
- using RPCEndpoint = shared::MultiThreadedRPCEndpoint<RPCChannel>;
-
-private:
- using ThisT = RemoteExecutorProcessControl;
- using BaseT = OrcRPCExecutorProcessControlBase<RPCEndpoint>;
- using MemoryAccess = OrcRPCEPCMemoryAccess<ThisT>;
- using MemoryManager = OrcRPCEPCJITLinkMemoryManager<ThisT>;
-
-public:
- using BaseT::initializeORCRPCEPCBase;
-
- RemoteExecutorProcessControl(std::unique_ptr<RPCChannel> Channel,
- std::unique_ptr<RPCEndpoint> Endpoint,
- BaseT::ErrorReporter ReportError);
-
- void initializeMemoryManagement();
- Error disconnect() override;
-
-private:
- std::unique_ptr<RPCChannel> Channel;
- std::unique_ptr<RPCEndpoint> Endpoint;
- std::unique_ptr<MemoryAccess> OwnedMemAccess;
- std::unique_ptr<MemoryManager> OwnedMemMgr;
- std::atomic<bool> Finished{false};
- std::thread ListenerThread;
-};
-
-RemoteExecutorProcessControl::RemoteExecutorProcessControl(
- std::unique_ptr<RPCChannel> Channel, std::unique_ptr<RPCEndpoint> Endpoint,
- BaseT::ErrorReporter ReportError)
- : BaseT(std::make_shared<SymbolStringPool>(), *Endpoint,
- std::move(ReportError)),
- Channel(std::move(Channel)), Endpoint(std::move(Endpoint)) {
-
- ListenerThread = std::thread([&]() {
- while (!Finished) {
- if (auto Err = this->Endpoint->handleOne()) {
- reportError(std::move(Err));
- return;
- }
- }
- });
-}
-
-void RemoteExecutorProcessControl::initializeMemoryManagement() {
- OwnedMemAccess = std::make_unique<MemoryAccess>(*this);
- OwnedMemMgr = std::make_unique<MemoryManager>(*this);
-
- // Base class needs non-owning access.
- MemAccess = OwnedMemAccess.get();
- MemMgr = OwnedMemMgr.get();
-}
-
-Error RemoteExecutorProcessControl::disconnect() {
- std::promise<MSVCPError> P;
- auto F = P.get_future();
- auto Err = closeConnection([&](Error Err) -> Error {
- P.set_value(std::move(Err));
- Finished = true;
- return Error::success();
- });
- ListenerThread.join();
- return joinErrors(std::move(Err), F.get());
-}
-
-} // namespace orc
-} // namespace llvm
-
-JITLinkExecutor::JITLinkExecutor() = default;
-JITLinkExecutor::~JITLinkExecutor() = default;
-
-Expected<std::unique_ptr<ObjectLayer>>
-JITLinkExecutor::operator()(ExecutionSession &ES, const Triple &TT) {
- assert(EPC && "RemoteExecutorProcessControl must be initialized");
- return std::make_unique<ObjectLinkingLayer>(ES, EPC->getMemMgr());
-}
-
-std::unique_ptr<ExecutionSession> JITLinkExecutor::startSession() {
- assert(OwnedEPC && "RemoteExecutorProcessControl must be initialized");
- return std::make_unique<ExecutionSession>(std::move(OwnedEPC));
-}
-
-Error JITLinkExecutor::addDebugSupport(ObjectLayer &ObjLayer) {
- auto Registrar = createJITLoaderGDBRegistrar(EPC->getExecutionSession());
+Error addDebugSupport(ObjectLayer &ObjLayer) {
+ ExecutionSession &ES = ObjLayer.getExecutionSession();
+ auto Registrar = createJITLoaderGDBRegistrar(ES);
if (!Registrar)
return Registrar.takeError();
- cast<ObjectLinkingLayer>(&ObjLayer)->addPlugin(
- std::make_unique<DebugObjectManagerPlugin>(ObjLayer.getExecutionSession(),
- std::move(*Registrar)));
+ auto *ObjLinkingLayer = cast<ObjectLinkingLayer>(&ObjLayer);
+ if (!ObjLinkingLayer)
+ return createStringError(inconvertibleErrorCode(),
+ "No debug support for given object layer type");
+ ObjLinkingLayer->addPlugin(
+ std::make_unique<DebugObjectManagerPlugin>(ES, std::move(*Registrar)));
return Error::success();
}
Expected<std::unique_ptr<DefinitionGenerator>>
-JITLinkExecutor::loadDylib(StringRef RemotePath) {
- if (auto Handle = EPC->loadDylib(RemotePath.data()))
- return std::make_unique<EPCDynamicLibrarySearchGenerator>(
- EPC->getExecutionSession(), *Handle);
+loadDylib(ExecutionSession &ES, StringRef RemotePath) {
+ if (auto Handle = ES.getExecutorProcessControl().loadDylib(RemotePath.data()))
+ return std::make_unique<EPCDynamicLibrarySearchGenerator>(ES, *Handle);
else
return Handle.takeError();
}
-Expected<int> JITLinkExecutor::runAsMain(JITEvaluatedSymbol MainSym,
- ArrayRef<std::string> Args) {
- return EPC->runAsMain(ExecutorAddr(MainSym.getAddress()), Args);
-}
-
-Error JITLinkExecutor::disconnect() { return EPC->disconnect(); }
-
-static std::string defaultPath(const char *HostArgv0, StringRef ExecutorName) {
- // This just needs to be some symbol in the binary; C++ doesn't
+static void findLocalExecutorHelper() {}
+std::string findLocalExecutor(const char *HostArgv0) {
+ // This just needs to be some static symbol in the binary; C++ doesn't
// allow taking the address of ::main however.
- void *P = (void *)(intptr_t)defaultPath;
- SmallString<256> FullName(sys::fs::getMainExecutable(HostArgv0, P));
+ uintptr_t UIntPtr = reinterpret_cast<uintptr_t>(&findLocalExecutorHelper);
+ void *VoidPtr = reinterpret_cast<void *>(UIntPtr);
+ SmallString<256> FullName(sys::fs::getMainExecutable(HostArgv0, VoidPtr));
sys::path::remove_filename(FullName);
- sys::path::append(FullName, ExecutorName);
+ sys::path::append(FullName, "llvm-jitlink-executor");
return FullName.str().str();
}
-Expected<std::unique_ptr<ChildProcessJITLinkExecutor>>
-JITLinkExecutor::FindLocal(const char *HostArgv) {
- std::string BestGuess = defaultPath(HostArgv, "llvm-jitlink-executor");
- auto Executor = CreateLocal(BestGuess);
- if (!Executor) {
- consumeError(Executor.takeError());
- return make_error<StringError>(
- formatv("Unable to find usable executor: {0}", BestGuess),
- inconvertibleErrorCode());
- }
- return Executor;
-}
-
-Expected<std::unique_ptr<ChildProcessJITLinkExecutor>>
-JITLinkExecutor::CreateLocal(std::string ExecutablePath) {
- if (!sys::fs::can_execute(ExecutablePath))
- return make_error<StringError>(
- formatv("Specified executor invalid: {0}", ExecutablePath),
- inconvertibleErrorCode());
- return std::unique_ptr<ChildProcessJITLinkExecutor>(
- new ChildProcessJITLinkExecutor(std::move(ExecutablePath)));
-}
-
-TCPSocketJITLinkExecutor::TCPSocketJITLinkExecutor(
- std::unique_ptr<RemoteExecutorProcessControl> EPC) {
- this->OwnedEPC = std::move(EPC);
- this->EPC = this->OwnedEPC.get();
-}
-
#ifndef LLVM_ON_UNIX
// FIXME: Add support for Windows.
-Error ChildProcessJITLinkExecutor::launch(ExecutionSession &ES) {
+Expected<std::pair<std::unique_ptr<SimpleRemoteEPC>, uint64_t>>
+launchLocalExecutor(StringRef ExecutablePath) {
return make_error<StringError>(
"Remote JITing not yet supported on non-unix platforms",
inconvertibleErrorCode());
}
// FIXME: Add support for Windows.
-Expected<std::unique_ptr<TCPSocketJITLinkExecutor>>
-JITLinkExecutor::ConnectTCPSocket(StringRef NetworkAddress,
- ExecutionSession &ES) {
+Expected<std::unique_ptr<SimpleRemoteEPC>>
+connectTCPSocket(StringRef NetworkAddress) {
return make_error<StringError>(
"Remote JITing not yet supported on non-unix platforms",
inconvertibleErrorCode());
@@ -205,11 +82,16 @@ JITLinkExecutor::ConnectTCPSocket(StringRef NetworkAddress,
#else
-Error ChildProcessJITLinkExecutor::launch(
- unique_function<void(Error)> ErrorReporter) {
+Expected<std::pair<std::unique_ptr<SimpleRemoteEPC>, uint64_t>>
+launchLocalExecutor(StringRef ExecutablePath) {
constexpr int ReadEnd = 0;
constexpr int WriteEnd = 1;
+ if (!sys::fs::can_execute(ExecutablePath))
+ return make_error<StringError>(
+ formatv("Specified executor invalid: {0}", ExecutablePath),
+ inconvertibleErrorCode());
+
// Pipe FDs.
int ToExecutor[2];
int FromExecutor[2];
@@ -219,7 +101,7 @@ Error ChildProcessJITLinkExecutor::launch(
return make_error<StringError>("Unable to create pipe for executor",
inconvertibleErrorCode());
- ProcessID = fork();
+ pid_t ProcessID = fork();
if (ProcessID == 0) {
// In the child...
@@ -256,22 +138,12 @@ Error ChildProcessJITLinkExecutor::launch(
close(ToExecutor[ReadEnd]);
close(FromExecutor[WriteEnd]);
- auto Channel =
- std::make_unique<RPCChannel>(FromExecutor[ReadEnd], ToExecutor[WriteEnd]);
- auto Endpoint = std::make_unique<RemoteExecutorProcessControl::RPCEndpoint>(
- *Channel, true);
-
- OwnedEPC = std::make_unique<RemoteExecutorProcessControl>(
- std::move(Channel), std::move(Endpoint), std::move(ErrorReporter));
-
- if (auto Err = OwnedEPC->initializeORCRPCEPCBase())
- return joinErrors(std::move(Err), OwnedEPC->disconnect());
-
- OwnedEPC->initializeMemoryManagement();
- EPC = OwnedEPC.get();
+ auto EPC = SimpleRemoteEPC::Create<FDSimpleRemoteEPCTransport>(
+ FromExecutor[ReadEnd], ToExecutor[WriteEnd]);
+ if (!EPC)
+ return EPC.takeError();
- shared::registerStringError<RPCChannel>();
- return Error::success();
+ return std::make_pair(std::move(*EPC), static_cast<uint64_t>(ProcessID));
}
static Expected<int> connectTCPSocketImpl(std::string Host,
@@ -313,9 +185,8 @@ static Expected<int> connectTCPSocketImpl(std::string Host,
return SockFD;
}
-Expected<std::unique_ptr<TCPSocketJITLinkExecutor>>
-JITLinkExecutor::ConnectTCPSocket(StringRef NetworkAddress,
- unique_function<void(Error)> ErrorReporter) {
+Expected<std::unique_ptr<SimpleRemoteEPC>>
+connectTCPSocket(StringRef NetworkAddress) {
auto CreateErr = [NetworkAddress](StringRef Details) {
return make_error<StringError>(
formatv("Failed to connect TCP socket '{0}': {1}", NetworkAddress,
@@ -337,21 +208,7 @@ JITLinkExecutor::ConnectTCPSocket(StringRef NetworkAddress,
if (!SockFD)
return CreateErr(toString(SockFD.takeError()));
- auto Channel = std::make_unique<RPCChannel>(*SockFD, *SockFD);
- auto Endpoint = std::make_unique<RemoteExecutorProcessControl::RPCEndpoint>(
- *Channel, true);
-
- auto EPC = std::make_unique<RemoteExecutorProcessControl>(
- std::move(Channel), std::move(Endpoint), std::move(ErrorReporter));
-
- if (auto Err = EPC->initializeORCRPCEPCBase())
- return joinErrors(std::move(Err), EPC->disconnect());
-
- EPC->initializeMemoryManagement();
- shared::registerStringError<RPCChannel>();
-
- return std::unique_ptr<TCPSocketJITLinkExecutor>(
- new TCPSocketJITLinkExecutor(std::move(EPC)));
+ return SimpleRemoteEPC::Create<FDSimpleRemoteEPCTransport>(*SockFD);
}
#endif
diff --git a/llvm/examples/OrcV2Examples/LLJITWithRemoteDebugging/RemoteJITUtils.h b/llvm/examples/OrcV2Examples/LLJITWithRemoteDebugging/RemoteJITUtils.h
index 2570f90104160..e7cad9facdea6 100644
--- a/llvm/examples/OrcV2Examples/LLJITWithRemoteDebugging/RemoteJITUtils.h
+++ b/llvm/examples/OrcV2Examples/LLJITWithRemoteDebugging/RemoteJITUtils.h
@@ -14,103 +14,31 @@
#ifndef LLVM_EXAMPLES_ORCV2EXAMPLES_LLJITWITHREMOTEDEBUGGING_REMOTEJITUTILS_H
#define LLVM_EXAMPLES_ORCV2EXAMPLES_LLJITWITHREMOTEDEBUGGING_REMOTEJITUTILS_H
-#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/Triple.h"
-#include "llvm/ExecutionEngine/JITSymbol.h"
#include "llvm/ExecutionEngine/Orc/Core.h"
#include "llvm/ExecutionEngine/Orc/Layer.h"
-#include "llvm/ExecutionEngine/Orc/ObjectTransformLayer.h"
-#include "llvm/ExecutionEngine/Orc/Shared/FDRawByteChannel.h"
+#include "llvm/ExecutionEngine/Orc/SimpleRemoteEPC.h"
#include "llvm/Support/Error.h"
+#include <cstdint>
#include <memory>
#include <string>
-#if !defined(_MSC_VER) && !defined(__MINGW32__)
-#include <unistd.h>
-#else
-#include <io.h>
-#endif
-
-namespace llvm {
-namespace orc {
-
-class ChildProcessJITLinkExecutor;
-class RemoteExecutorProcessControl;
-class TCPSocketJITLinkExecutor;
-
-class JITLinkExecutor {
-public:
- using RPCChannel = shared::FDRawByteChannel;
-
- /// Create a JITLinkExecutor for the given exectuable on disk.
- static Expected<std::unique_ptr<ChildProcessJITLinkExecutor>>
- CreateLocal(std::string ExecutablePath);
-
- /// Find the default exectuable on disk and create a JITLinkExecutor for it.
- static Expected<std::unique_ptr<ChildProcessJITLinkExecutor>>
- FindLocal(const char *JITArgv0);
-
- /// Create a JITLinkExecutor that connects to the given network address
- /// through a TCP socket. A valid NetworkAddress provides hostname and port,
- /// e.g. localhost:20000.
- static Expected<std::unique_ptr<TCPSocketJITLinkExecutor>>
- ConnectTCPSocket(StringRef NetworkAddress,
- unique_function<void(Error)> ErrorReporter);
-
- // Implement ObjectLinkingLayerCreator
- Expected<std::unique_ptr<ObjectLayer>> operator()(ExecutionSession &,
- const Triple &);
-
- std::unique_ptr<ExecutionSession> startSession();
- Error disconnect();
-
- Error addDebugSupport(ObjectLayer &ObjLayer);
-
- Expected<std::unique_ptr<DefinitionGenerator>>
- loadDylib(StringRef RemotePath);
-
- Expected<int> runAsMain(JITEvaluatedSymbol MainSym,
- ArrayRef<std::string> Args);
-
- virtual ~JITLinkExecutor();
-
-protected:
- std::unique_ptr<RemoteExecutorProcessControl> OwnedEPC;
- RemoteExecutorProcessControl *EPC{nullptr};
-
- JITLinkExecutor();
-};
-
-/// JITLinkExecutor that runs in a child process on the local machine.
-class ChildProcessJITLinkExecutor : public JITLinkExecutor {
-public:
- Error launch(unique_function<void(Error)> ErrorReporter);
-
- pid_t getPID() const { return ProcessID; }
- StringRef getPath() const { return ExecutablePath; }
-
-private:
- std::string ExecutablePath;
- pid_t ProcessID;
-
- ChildProcessJITLinkExecutor(std::string ExecutablePath)
- : ExecutablePath(std::move(ExecutablePath)) {}
+/// Find the default exectuable on disk and create a JITLinkExecutor for it.
+std::string findLocalExecutor(const char *HostArgv0);
- static std::string defaultPath(const char *HostArgv0, StringRef ExecutorName);
- friend class JITLinkExecutor;
-};
+llvm::Expected<std::pair<std::unique_ptr<llvm::orc::SimpleRemoteEPC>, uint64_t>>
+launchLocalExecutor(llvm::StringRef ExecutablePath);
-/// JITLinkExecutor connected through a TCP socket.
-class TCPSocketJITLinkExecutor : public JITLinkExecutor {
-private:
- TCPSocketJITLinkExecutor(std::unique_ptr<RemoteExecutorProcessControl> EPC);
+/// Create a JITLinkExecutor that connects to the given network address
+/// through a TCP socket. A valid NetworkAddress provides hostname and port,
+/// e.g. localhost:20000.
+llvm::Expected<std::unique_ptr<llvm::orc::SimpleRemoteEPC>>
+connectTCPSocket(llvm::StringRef NetworkAddress);
- friend class JITLinkExecutor;
-};
+llvm::Error addDebugSupport(llvm::orc::ObjectLayer &ObjLayer);
-} // namespace orc
-} // namespace llvm
+llvm::Expected<std::unique_ptr<llvm::orc::DefinitionGenerator>>
+loadDylib(llvm::orc::ExecutionSession &ES, llvm::StringRef RemotePath);
#endif
More information about the llvm-commits
mailing list