diff options
author | Abhinav Kumar <96587705+kr-2003@users.noreply.github.com> | 2025-09-07 21:05:29 +0530 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-09-07 18:35:29 +0300 |
commit | 645dd324d1b7d028745c2a4045b69e745df2ae6a (patch) | |
tree | 44af1379a0a20cef44c260f958a18d9c124cd8ef /clang/lib/Interpreter/Interpreter.cpp | |
parent | 3216bf1b963b47752e48d54e4526160489f7677b (diff) | |
download | llvm-645dd324d1b7d028745c2a4045b69e745df2ae6a.zip llvm-645dd324d1b7d028745c2a4045b69e745df2ae6a.tar.gz llvm-645dd324d1b7d028745c2a4045b69e745df2ae6a.tar.bz2 |
[clang-repl] Sink RemoteJITUtils into Interpreter class. NFC (#155140)
This is a refactoring PR. It sinks RemoteJITUtils into Interpreter and IncrementalExecutor classes.
---------
Co-authored-by: kr-2003 <kumar.kr.abhinav@gmail.com>
Diffstat (limited to 'clang/lib/Interpreter/Interpreter.cpp')
-rw-r--r-- | clang/lib/Interpreter/Interpreter.cpp | 157 |
1 files changed, 141 insertions, 16 deletions
diff --git a/clang/lib/Interpreter/Interpreter.cpp b/clang/lib/Interpreter/Interpreter.cpp index 4799521..043e0c1 100644 --- a/clang/lib/Interpreter/Interpreter.cpp +++ b/clang/lib/Interpreter/Interpreter.cpp @@ -251,7 +251,8 @@ IncrementalCompilerBuilder::CreateCudaHost() { Interpreter::Interpreter(std::unique_ptr<CompilerInstance> Instance, llvm::Error &ErrOut, std::unique_ptr<llvm::orc::LLJITBuilder> JITBuilder, - std::unique_ptr<clang::ASTConsumer> Consumer) + std::unique_ptr<clang::ASTConsumer> Consumer, + JITConfig Config) : JITBuilder(std::move(JITBuilder)) { CI = std::move(Instance); llvm::ErrorAsOutParameter EAO(&ErrOut); @@ -285,7 +286,7 @@ Interpreter::Interpreter(std::unique_ptr<CompilerInstance> Instance, ASTContext &C = CI->getASTContext(); IncrParser->RegisterPTU(C.getTranslationUnitDecl(), std::move(M)); } - if (llvm::Error Err = CreateExecutor()) { + if (llvm::Error Err = CreateExecutor(Config)) { ErrOut = joinErrors(std::move(ErrOut), std::move(Err)); return; } @@ -347,20 +348,116 @@ const char *const Runtimes = R"( EXTERN_C void __clang_Interpreter_SetValueNoAlloc(void *This, void *OutVal, void *OpaqueType, ...); )"; +llvm::Expected<std::pair<std::unique_ptr<llvm::orc::LLJITBuilder>, uint32_t>> +Interpreter::outOfProcessJITBuilder(JITConfig Config) { + std::unique_ptr<llvm::orc::ExecutorProcessControl> EPC; + uint32_t childPid = -1; + if (!Config.OOPExecutor.empty()) { + // Launch an out-of-process executor locally in a child process. + auto ResultOrErr = IncrementalExecutor::launchExecutor( + Config.OOPExecutor, Config.UseSharedMemory, Config.SlabAllocateSize); + if (!ResultOrErr) + return ResultOrErr.takeError(); + childPid = ResultOrErr->second; + auto EPCOrErr = std::move(ResultOrErr->first); + EPC = std::move(EPCOrErr); + } else if (Config.OOPExecutorConnect != "") { +#if LLVM_ON_UNIX && LLVM_ENABLE_THREADS + auto EPCOrErr = IncrementalExecutor::connectTCPSocket( + Config.OOPExecutorConnect, Config.UseSharedMemory, + Config.SlabAllocateSize); + if (!EPCOrErr) + return EPCOrErr.takeError(); + EPC = std::move(*EPCOrErr); +#else + return llvm::make_error<llvm::StringError>( + "Out-of-process JIT over TCP is not supported on this platform", + std::error_code()); +#endif + } + + std::unique_ptr<llvm::orc::LLJITBuilder> JB; + if (EPC) { + auto JBOrErr = clang::Interpreter::createLLJITBuilder( + std::move(EPC), Config.OrcRuntimePath); + if (!JBOrErr) + return JBOrErr.takeError(); + JB = std::move(*JBOrErr); + } + + return std::make_pair(std::move(JB), childPid); +} + +llvm::Expected<std::string> +Interpreter::getOrcRuntimePath(const driver::ToolChain &TC) { + std::optional<std::string> CompilerRTPath = TC.getCompilerRTPath(); + std::optional<std::string> ResourceDir = TC.getRuntimePath(); + + if (!CompilerRTPath) { + return llvm::make_error<llvm::StringError>("CompilerRT path not found", + std::error_code()); + } + + const std::array<const char *, 3> OrcRTLibNames = { + "liborc_rt.a", "liborc_rt_osx.a", "liborc_rt-x86_64.a"}; + + for (const char *LibName : OrcRTLibNames) { + llvm::SmallString<256> CandidatePath((*CompilerRTPath).c_str()); + llvm::sys::path::append(CandidatePath, LibName); + + if (llvm::sys::fs::exists(CandidatePath)) { + return CandidatePath.str().str(); + } + } + + return llvm::make_error<llvm::StringError>( + llvm::Twine("OrcRuntime library not found in: ") + (*CompilerRTPath), + std::error_code()); +} + llvm::Expected<std::unique_ptr<Interpreter>> -Interpreter::create(std::unique_ptr<CompilerInstance> CI, - std::unique_ptr<llvm::orc::LLJITBuilder> JB) { +Interpreter::create(std::unique_ptr<CompilerInstance> CI, JITConfig Config) { llvm::Error Err = llvm::Error::success(); - auto Interp = std::unique_ptr<Interpreter>( - new Interpreter(std::move(CI), Err, JB ? std::move(JB) : nullptr)); - if (Err) - return std::move(Err); + + std::unique_ptr<llvm::orc::LLJITBuilder> JB; + + if (Config.IsOutOfProcess) { + const TargetInfo &TI = CI->getTarget(); + const llvm::Triple &Triple = TI.getTriple(); + + DiagnosticsEngine &Diags = CI->getDiagnostics(); + std::string BinaryName = llvm::sys::fs::getMainExecutable(nullptr, nullptr); + driver::Driver Driver(BinaryName, Triple.str(), Diags); + // Need fake args to get the driver to create a compilation. + std::vector<const char *> Args = {"clang", "--version"}; + std::unique_ptr<clang::driver::Compilation> C( + Driver.BuildCompilation(Args)); + if (!C) { + return llvm::make_error<llvm::StringError>( + "Failed to create driver compilation for out-of-process JIT", + std::error_code()); + } + if (Config.OrcRuntimePath == "") { + const clang::driver::ToolChain &TC = C->getDefaultToolChain(); + + auto OrcRuntimePathOrErr = getOrcRuntimePath(TC); + if (!OrcRuntimePathOrErr) { + return OrcRuntimePathOrErr.takeError(); + } + + Config.OrcRuntimePath = *OrcRuntimePathOrErr; + } + } + + auto Interp = std::unique_ptr<Interpreter>(new Interpreter( + std::move(CI), Err, std::move(JB), /*Consumer=*/nullptr, Config)); + if (auto E = std::move(Err)) + return std::move(E); // Add runtime code and set a marker to hide it from user code. Undo will not // go through that. - Err = Interp->ParseAndExecute(Runtimes); - if (Err) - return std::move(Err); + if (auto E = Interp->ParseAndExecute(Runtimes)) + return std::move(E); Interp->markUserCodeStart(); @@ -444,6 +541,12 @@ size_t Interpreter::getEffectivePTUSize() const { return PTUs.size() - InitPTUSize; } +uint32_t Interpreter::getOutOfProcessExecutorPID() const { + if (IncrExecutor) + return IncrExecutor->getOutOfProcessChildPid(); + return -1; +} + llvm::Expected<PartialTranslationUnit &> Interpreter::Parse(llvm::StringRef Code) { // If we have a device parser, parse it first. The generated code will be @@ -512,7 +615,7 @@ Interpreter::createLLJITBuilder( return std::move(*JB); } -llvm::Error Interpreter::CreateExecutor() { +llvm::Error Interpreter::CreateExecutor(JITConfig Config) { if (IncrExecutor) return llvm::make_error<llvm::StringError>("Operation failed. " "Execution engine exists", @@ -521,8 +624,26 @@ llvm::Error Interpreter::CreateExecutor() { return llvm::make_error<llvm::StringError>("Operation failed. " "No code generator available", std::error_code()); + + const std::string &TT = getCompilerInstance()->getTargetOpts().Triple; + llvm::Triple TargetTriple(TT); + bool IsWindowsTarget = TargetTriple.isOSWindows(); + + if (!IsWindowsTarget && Config.IsOutOfProcess) { + if (!JITBuilder) { + auto ResOrErr = outOfProcessJITBuilder(Config); + if (!ResOrErr) + return ResOrErr.takeError(); + JITBuilder = std::move(ResOrErr->first); + Config.ExecutorPID = ResOrErr->second; + } + if (!JITBuilder) + return llvm::make_error<llvm::StringError>( + "Operation failed. No LLJITBuilder for out-of-process JIT", + std::error_code()); + } + if (!JITBuilder) { - const std::string &TT = getCompilerInstance()->getTargetOpts().Triple; auto JTMB = createJITTargetMachineBuilder(TT); if (!JTMB) return JTMB.takeError(); @@ -533,11 +654,15 @@ llvm::Error Interpreter::CreateExecutor() { } llvm::Error Err = llvm::Error::success(); + + // Fix: Declare Executor as the appropriate unique_ptr type + std::unique_ptr<IncrementalExecutor> Executor; + #ifdef __EMSCRIPTEN__ - auto Executor = std::make_unique<WasmIncrementalExecutor>(*TSCtx); + Executor = std::make_unique<WasmIncrementalExecutor>(*TSCtx); #else - auto Executor = - std::make_unique<IncrementalExecutor>(*TSCtx, *JITBuilder, Err); + Executor = + std::make_unique<IncrementalExecutor>(*TSCtx, *JITBuilder, Config, Err); #endif if (!Err) IncrExecutor = std::move(Executor); |