[llvm] [llvm-jitlink] Replace pipes with unix domain sockets. (PR #223941)

Lang Hames via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 16 00:59:32 PDT 2026


https://github.com/lhames created https://github.com/llvm/llvm-project/pull/223941

Replace pipes with unix domain sockets for basic out-of-process execution.

The new ORC runtime doesn't support pipes -- this changes will enable llvm-jitlink to connect to the new ORC runtime's executor (once it lands).

>From 7fa6e9276eb8e02eb0e48b7a033ed88349dd447e Mon Sep 17 00:00:00 2001
From: Lang Hames <lhames at apple.com>
Date: Wed, 16 Sep 2026 17:55:14 +1000
Subject: [PATCH] [llvm-jitlink] Replace pipes with unix domain sockets.

Replace pipes with unix domain sockets for basic out-of-process
execution.

The new ORC runtime doesn't support pipes -- this changes will enable
llvm-jitlink to connect to the new ORC runtime's executor (once it
lands).
---
 .../llvm-jitlink-executor.cpp                 | 17 +++---
 llvm/tools/llvm-jitlink/llvm-jitlink.cpp      | 53 +++++--------------
 2 files changed, 20 insertions(+), 50 deletions(-)

diff --git a/llvm/tools/llvm-jitlink/llvm-jitlink-executor/llvm-jitlink-executor.cpp b/llvm/tools/llvm-jitlink/llvm-jitlink-executor/llvm-jitlink-executor.cpp
index d181858cd86990..3b0252d3c94aa2 100644
--- a/llvm/tools/llvm-jitlink/llvm-jitlink-executor/llvm-jitlink-executor.cpp
+++ b/llvm/tools/llvm-jitlink/llvm-jitlink-executor/llvm-jitlink-executor.cpp
@@ -138,8 +138,7 @@ int main(int argc, char *argv[]) {
   ExitOnErr.setBanner(std::string(argv[0]) + ": ");
 
   unsigned FirstProgramArg = 1;
-  int InFD = 0;
-  int OutFD = 0;
+  int FD = 0;
 
   if (argc < 2)
     printErrorAndExit("insufficient arguments");
@@ -164,13 +163,9 @@ int main(int argc, char *argv[]) {
 
   StringRef SpecifierType, Specifier;
   std::tie(SpecifierType, Specifier) = NextArg.split('=');
-  if (SpecifierType == "filedescs") {
-    StringRef FD1Str, FD2Str;
-    std::tie(FD1Str, FD2Str) = Specifier.split(',');
-    if (FD1Str.getAsInteger(10, InFD))
-      printErrorAndExit(FD1Str + " is not a valid file descriptor");
-    if (FD2Str.getAsInteger(10, OutFD))
-      printErrorAndExit(FD2Str + " is not a valid file descriptor");
+  if (SpecifierType == "fd") {
+    if (Specifier.getAsInteger(10, FD))
+      printErrorAndExit(Specifier + " is not a valid file descriptor");
   } else if (SpecifierType == "listen") {
     StringRef Host, PortStr;
     std::tie(Host, PortStr) = Specifier.split(':');
@@ -179,7 +174,7 @@ int main(int argc, char *argv[]) {
     if (PortStr.getAsInteger(10, Port))
       printErrorAndExit("port number '" + PortStr + "' is not a valid integer");
 
-    InFD = OutFD = openListener(Host.str(), PortStr.str());
+    FD = openListener(Host.str(), PortStr.str());
   } else
     printErrorAndExit("invalid specifier type \"" + SpecifierType + "\"");
 
@@ -203,7 +198,7 @@ int main(int argc, char *argv[]) {
                     rt_bootstrap::ExecutorSharedMemoryMapperService>());
             return Error::success();
           },
-          InFD, OutFD));
+          FD, FD));
 
   ExitOnErr(Server->waitForDisconnect());
 
diff --git a/llvm/tools/llvm-jitlink/llvm-jitlink.cpp b/llvm/tools/llvm-jitlink/llvm-jitlink.cpp
index cbc419e84b3e56..05606849797ab9 100644
--- a/llvm/tools/llvm-jitlink/llvm-jitlink.cpp
+++ b/llvm/tools/llvm-jitlink/llvm-jitlink.cpp
@@ -932,60 +932,35 @@ static Expected<std::unique_ptr<ExecutorProcessControl>> launchExecutor() {
       inconvertibleErrorCode());
 #else
 
-  constexpr int ReadEnd = 0;
-  constexpr int WriteEnd = 1;
-
-  // Pipe FDs.
-  int ToExecutor[2];
-  int FromExecutor[2];
+  constexpr int ParentSocket = 0, ChildSocket = 1;
+  int Sockets[2];
+  if (socketpair(AF_UNIX, SOCK_STREAM, 0, Sockets) == -1)
+    return make_error<StringError>(
+        Twine("Unable to create socket for executor: ") + strerror(errno),
+        inconvertibleErrorCode());
 
   pid_t ChildPID;
-
-  // Create pipes to/from the executor..
-  if (pipe(ToExecutor) != 0 || pipe(FromExecutor) != 0)
-    return make_error<StringError>("Unable to create pipe for executor",
-                                   inconvertibleErrorCode());
-
   ChildPID = fork();
 
   if (ChildPID == 0) {
     // In the child...
-
-    // Close the parent ends of the pipes
-    close(ToExecutor[WriteEnd]);
-    close(FromExecutor[ReadEnd]);
-
-    // Execute the child process.
-    std::unique_ptr<char[]> ExecutorPath, FDSpecifier;
-    {
-      ExecutorPath = std::make_unique<char[]>(OutOfProcessExecutor.size() + 1);
-      strcpy(ExecutorPath.get(), OutOfProcessExecutor.data());
-
-      std::string FDSpecifierStr("filedescs=");
-      FDSpecifierStr += utostr(ToExecutor[ReadEnd]);
-      FDSpecifierStr += ',';
-      FDSpecifierStr += utostr(FromExecutor[WriteEnd]);
-      FDSpecifier = std::make_unique<char[]>(FDSpecifierStr.size() + 1);
-      strcpy(FDSpecifier.get(), FDSpecifierStr.c_str());
-    }
-
-    char *const Args[] = {ExecutorPath.get(), FDSpecifier.get(), nullptr};
-    int RC = execvp(ExecutorPath.get(), Args);
+    close(Sockets[ParentSocket]);
+    std::string ConnSpec = "fd=" + std::to_string(Sockets[ChildSocket]);
+    char *const Args[] = {OutOfProcessExecutor.data(), ConnSpec.data(),
+                          nullptr};
+    int RC = execvp(OutOfProcessExecutor.data(), Args);
     if (RC != 0) {
       errs() << "unable to launch out-of-process executor \""
-             << ExecutorPath.get() << "\"\n";
+             << OutOfProcessExecutor << "\"\n";
       exit(1);
     }
   }
   // else we're the parent...
-
-  // Close the child ends of the pipes
-  close(ToExecutor[ReadEnd]);
-  close(FromExecutor[WriteEnd]);
+  close(Sockets[ChildSocket]);
 
   return SimpleRemoteEPC::Create<FDSimpleRemoteEPCTransport>(
       std::make_unique<DynamicThreadPoolTaskDispatcher>(MaterializationThreads),
-      FromExecutor[ReadEnd], ToExecutor[WriteEnd]);
+      Sockets[ParentSocket], Sockets[ParentSocket]);
 #endif
 }
 



More information about the llvm-commits mailing list