[llvm] [compiler-rt] [clang] [clang-repl] [ORC] Add support for out-of-process execution on ELF (PR #79936)

2024-01-31 Thread Vassil Vassilev via cfe-commits


@@ -143,6 +169,201 @@ ReplListCompleter::operator()(llvm::StringRef Buffer, 
size_t Pos,
   return Comps;
 }
 
+static llvm::Error sanitizeOopArguments(const char *ArgV0) {
+  llvm::Triple SystemTriple(llvm::sys::getProcessTriple());
+  if ((OutOfProcessExecutor.getNumOccurrences() ||
+   OutOfProcessExecutorConnect.getNumOccurrences()) &&
+  (!SystemTriple.isOSBinFormatELF()))
+return llvm::make_error(
+"Out-process-executors are currently only supported on ELF",
+llvm::inconvertibleErrorCode());
+
+  // Only one of -oop-executor and -oop-executor-connect can be used.
+  if (!!OutOfProcessExecutor.getNumOccurrences() &&
+  !!OutOfProcessExecutorConnect.getNumOccurrences())
+return llvm::make_error(
+"Only one of -" + OutOfProcessExecutor.ArgStr + " and -" +
+OutOfProcessExecutorConnect.ArgStr + " can be specified",
+llvm::inconvertibleErrorCode());
+
+  // If -oop-executor was used but no value was specified then use a sensible
+  // default.
+  if (!!OutOfProcessExecutor.getNumOccurrences() &&
+  OutOfProcessExecutor.empty()) {
+llvm::SmallString<256> OOPExecutorPath(llvm::sys::fs::getMainExecutable(
+ArgV0, reinterpret_cast()));
+llvm::sys::path::remove_filename(OOPExecutorPath);
+llvm::sys::path::append(OOPExecutorPath, "llvm-jitlink-executor");
+OutOfProcessExecutor = OOPExecutorPath.str().str();
+  }
+
+  // Out-of-process executors must run with the ORC runtime for destructor 
support.
+  if (OrcRuntimePath.empty() && (OutOfProcessExecutor.getNumOccurrences() || 
OutOfProcessExecutorConnect.getNumOccurrences())) {
+llvm::SmallString<256> OrcPath(llvm::sys::fs::getMainExecutable(
+ArgV0, reinterpret_cast()));
+llvm::sys::path::remove_filename(OrcPath); // Remove clang-repl filename.
+llvm::sys::path::remove_filename(OrcPath); // Remove ./bin directory.
+llvm::sys::path::append(OrcPath, 
"lib/clang/18/lib/x86_64-unknown-linux-gnu/liborc_rt.a");
+OrcRuntimePath = OrcPath.str().str();
+  }
+
+  return llvm::Error::success();
+}
+
+static llvm::Expected>
+launchExecutor() {
+  constexpr int ReadEnd = 0;
+  constexpr int WriteEnd = 1;
+
+  // Pipe FDs.
+  int ToExecutor[2];
+  int FromExecutor[2];
+
+  pid_t ChildPID;
+
+  // Create pipes to/from the executor..
+  if (pipe(ToExecutor) != 0 || pipe(FromExecutor) != 0)
+return llvm::make_error(
+"Unable to create pipe for executor", llvm::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 ExecutorPath, FDSpecifier;
+{
+  ExecutorPath = std::make_unique(OutOfProcessExecutor.size() + 1);
+  strcpy(ExecutorPath.get(), OutOfProcessExecutor.data());
+
+  std::string FDSpecifierStr("filedescs=");
+  FDSpecifierStr += llvm::utostr(ToExecutor[ReadEnd]);
+  FDSpecifierStr += ',';
+  FDSpecifierStr += llvm::utostr(FromExecutor[WriteEnd]);
+  FDSpecifier = std::make_unique(FDSpecifierStr.size() + 1);
+  strcpy(FDSpecifier.get(), FDSpecifierStr.c_str());
+}
+
+char *const Args[] = {ExecutorPath.get(), FDSpecifier.get(), nullptr};
+int RC = execvp(ExecutorPath.get(), Args);
+if (RC != 0) {
+  llvm::errs() << "unable to launch out-of-process executor \""
+   << ExecutorPath.get() << "\"\n";
+  exit(1);
+}
+  }
+  // else we're the parent...
+
+  // Close the child ends of the pipes
+  close(ToExecutor[ReadEnd]);
+  close(FromExecutor[WriteEnd]);
+
+  auto S = llvm::orc::SimpleRemoteEPC::Setup();
+
+  return llvm::orc::SimpleRemoteEPC::Create<
+  llvm::orc::FDSimpleRemoteEPCTransport>(
+  std::make_unique(),
+  std::move(S), FromExecutor[ReadEnd], ToExecutor[WriteEnd]);
+}
+
+#if LLVM_ON_UNIX && LLVM_ENABLE_THREADS
+static llvm::Error createTCPSocketError(llvm::Twine Details) {
+  return llvm::make_error(
+  formatv("Failed to connect TCP socket '{0}': {1}",
+  OutOfProcessExecutorConnect, Details),
+  llvm::inconvertibleErrorCode());
+}
+
+static llvm::Expected connectTCPSocket(std::string Host,
+std::string PortStr) {
+  addrinfo *AI;
+  addrinfo Hints{};
+  Hints.ai_family = AF_INET;
+  Hints.ai_socktype = SOCK_STREAM;
+  Hints.ai_flags = AI_NUMERICSERV;
+
+  if (int EC = getaddrinfo(Host.c_str(), PortStr.c_str(), , ))
+return createTCPSocketError("Address resolution failed (" +
+llvm::StringRef(gai_strerror(EC)) + ")");
+
+  // Cycle through the returned addrinfo structures and connect to the first
+  // reachable endpoint.
+  int SockFD;
+  addrinfo *Server;
+  for (Server = AI; Server != nullptr; Server = Server->ai_next) {
+// socket might fail, e.g. if the address family is not supported. Skip to
+// 

[llvm] [compiler-rt] [clang] [clang-repl] [ORC] Add support for out-of-process execution on ELF (PR #79936)

2024-01-31 Thread Vassil Vassilev via cfe-commits


@@ -0,0 +1,61 @@
+// REQUIRES: host-supports-jit, x86_64-linux

vgvassilev wrote:

I believe this test copies some content from other tests. Would it make sense 
to add an extra `RUN` line to the tests themselves?

https://github.com/llvm/llvm-project/pull/79936
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[llvm] [compiler-rt] [clang] [clang-repl] [ORC] Add support for out-of-process execution on ELF (PR #79936)

2024-01-31 Thread Vassil Vassilev via cfe-commits

https://github.com/vgvassilev commented:

Thank you for working on this. This looks very good. I have left comments from 
my first review pass. We probably want to wait for @lhames and @weliveindetail 
to take a look.

https://github.com/llvm/llvm-project/pull/79936
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[llvm] [compiler-rt] [clang] [clang-repl] [ORC] Add support for out-of-process execution on ELF (PR #79936)

2024-01-29 Thread via cfe-commits

github-actions[bot] wrote:




:warning: C/C++ code formatter, clang-format found issues in your code. 
:warning:



You can test this locally with the following command:


``bash
git-clang-format --diff bc7a3bd864be696217c4d11eddf16bed7646b60f 
158cc5ec91bf085ec9914de26a1554606a1e3338 -- 
clang/test/Interpreter/out-of-process.cpp 
clang/include/clang/Interpreter/Interpreter.h 
clang/lib/Interpreter/IncrementalExecutor.cpp 
clang/lib/Interpreter/IncrementalExecutor.h 
clang/lib/Interpreter/Interpreter.cpp 
clang/test/Interpreter/dynamic-library.cpp clang/tools/clang-repl/ClangRepl.cpp 
compiler-rt/lib/orc/dlfcn_wrapper.cpp compiler-rt/lib/orc/elfnix_platform.cpp 
compiler-rt/lib/orc/elfnix_platform.h 
llvm/lib/ExecutionEngine/Orc/ELFNixPlatform.cpp 
llvm/lib/ExecutionEngine/Orc/LLJIT.cpp
``





View the diff from clang-format here.


``diff
diff --git a/clang/include/clang/Interpreter/Interpreter.h 
b/clang/include/clang/Interpreter/Interpreter.h
index 314beb7b72d..c1e63a9cdb6 100644
--- a/clang/include/clang/Interpreter/Interpreter.h
+++ b/clang/include/clang/Interpreter/Interpreter.h
@@ -107,7 +107,8 @@ public:
   static llvm::Expected>
   createWithOutOfProcessExecutor(
   std::unique_ptr CI,
-  std::unique_ptr EI, llvm::StringRef 
OrcRuntimePath);
+  std::unique_ptr EI,
+  llvm::StringRef OrcRuntimePath);
   const ASTContext () const;
   ASTContext ();
   const CompilerInstance *getCompilerInstance() const;
diff --git a/clang/lib/Interpreter/IncrementalExecutor.cpp 
b/clang/lib/Interpreter/IncrementalExecutor.cpp
index 30b24caa4a5..3da8d24606c 100644
--- a/clang/lib/Interpreter/IncrementalExecutor.cpp
+++ b/clang/lib/Interpreter/IncrementalExecutor.cpp
@@ -66,7 +66,8 @@ 
IncrementalExecutor::IncrementalExecutor(llvm::orc::ThreadSafeContext ,
 IncrementalExecutor::IncrementalExecutor(
 llvm::orc::ThreadSafeContext , llvm::Error ,
 const clang::TargetInfo ,
-std::unique_ptr EPC, llvm::StringRef 
OrcRuntimePath)
+std::unique_ptr EPC,
+llvm::StringRef OrcRuntimePath)
 : TSCtx(TSC) {
   using namespace llvm::orc;
   llvm::ErrorAsOutParameter EAO();
@@ -82,7 +83,8 @@ IncrementalExecutor::IncrementalExecutor(
 return llvm::Error::success();
   });
   Builder.setExecutorProcessControl(std::move(EPC));
-  
Builder.setPlatformSetUp(llvm::orc::ExecutorNativePlatform(OrcRuntimePath.str()));
+  Builder.setPlatformSetUp(
+  llvm::orc::ExecutorNativePlatform(OrcRuntimePath.str()));
 
   if (auto JitOrErr = Builder.create()) {
 Jit = std::move(*JitOrErr);
diff --git a/clang/lib/Interpreter/IncrementalExecutor.h 
b/clang/lib/Interpreter/IncrementalExecutor.h
index a73ba903518..6d75594793e 100644
--- a/clang/lib/Interpreter/IncrementalExecutor.h
+++ b/clang/lib/Interpreter/IncrementalExecutor.h
@@ -48,7 +48,8 @@ public:
   const clang::TargetInfo );
   IncrementalExecutor(llvm::orc::ThreadSafeContext , llvm::Error ,
   const clang::TargetInfo ,
-  std::unique_ptr EPC, 
llvm::StringRef OrcRuntimePath);
+  std::unique_ptr EPC,
+  llvm::StringRef OrcRuntimePath);
   ~IncrementalExecutor();
 
   llvm::Error addModule(PartialTranslationUnit );
diff --git a/clang/lib/Interpreter/Interpreter.cpp 
b/clang/lib/Interpreter/Interpreter.cpp
index 13e6be3b54a..5953afbb17f 100644
--- a/clang/lib/Interpreter/Interpreter.cpp
+++ b/clang/lib/Interpreter/Interpreter.cpp
@@ -244,7 +244,7 @@ Interpreter::~Interpreter() {
   toString(std::move(Err)));
   }
 
-if (EPC) {
+  if (EPC) {
 if (auto Err = EPC->disconnect()) {
   llvm::report_fatal_error(
   llvm::Twine("Failed to clean up EPC (IncrementalExecutor has not yet 
"
@@ -325,11 +325,11 @@ 
Interpreter::createWithCUDA(std::unique_ptr CI,
   return Interp;
 }
 
-
 llvm::Expected>
 Interpreter::createWithOutOfProcessExecutor(
 std::unique_ptr CI,
-std::unique_ptr EI, llvm::StringRef 
OrcRuntimePath) {
+std::unique_ptr EI,
+llvm::StringRef OrcRuntimePath) {
   auto Interp = create(std::move(CI));
   if (auto E = Interp.takeError()) {
 return std::move(E);
@@ -389,8 +389,8 @@ llvm::Error Interpreter::CreateExecutor() {
   llvm::Error Err = llvm::Error::success();
   std::unique_ptr Executor;
   if (EPC) {
-Executor =
-std::make_unique(*TSCtx, Err, TI, std::move(EPC), 
OrcRuntimePath);
+Executor = std::make_unique(
+*TSCtx, Err, TI, std::move(EPC), OrcRuntimePath);
   } else {
 Executor = std::make_unique(*TSCtx, Err, TI);
   }
diff --git a/clang/tools/clang-repl/ClangRepl.cpp 
b/clang/tools/clang-repl/ClangRepl.cpp
index 1c43e7b5036..9f45910ed64 100644
--- a/clang/tools/clang-repl/ClangRepl.cpp
+++ b/clang/tools/clang-repl/ClangRepl.cpp
@@ -63,10 +63,9 @@ static llvm::cl::opt 
OutOfProcessExecutorConnect(
 "oop-executor-connect",
 llvm::cl::desc("Connect to an out-of-process executor via TCP"),
 llvm::cl::cat(OOPCategory));

[llvm] [compiler-rt] [clang] [clang-repl] [ORC] Add support for out-of-process execution on ELF (PR #79936)

2024-01-29 Thread via cfe-commits

github-actions[bot] wrote:

Thank you for submitting a Pull Request (PR) to the LLVM Project!

This PR will be automatically labeled and the relevant teams will be
notified.

If you wish to, you can add reviewers by using the "Reviewers" section on this 
page.

If this is not working for you, it is probably because you do not have write
permissions for the repository. In which case you can instead tag reviewers by
name in a comment by using `@` followed by their GitHub username.

If you have received no comments on your PR for a week, you can request a review
by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate
is once a week. Please remember that you are asking for valuable time from 
other developers.

If you have further questions, they may be answered by the [LLVM GitHub User 
Guide](https://llvm.org/docs/GitHub.html).

You can also ask questions in a comment on this PR, on the [LLVM 
Discord](https://discord.com/invite/xS7Z362) or on the 
[forums](https://discourse.llvm.org/).

https://github.com/llvm/llvm-project/pull/79936
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[llvm] [compiler-rt] [clang] [clang-repl] [ORC] Add support for out-of-process execution on ELF (PR #79936)

2024-01-29 Thread via cfe-commits

https://github.com/jameshu15869 converted_to_draft 
https://github.com/llvm/llvm-project/pull/79936
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits