[llvm] [compiler-rt] [clang] [clang-repl] [ORC] Add support for out-of-process execution on ELF (PR #79936)
@@ -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)
@@ -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)
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)
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)
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)
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