[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