aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Interpreter/Interpreter.cpp
diff options
context:
space:
mode:
authorAbhinav Kumar <96587705+kr-2003@users.noreply.github.com>2025-09-07 21:05:29 +0530
committerGitHub <noreply@github.com>2025-09-07 18:35:29 +0300
commit645dd324d1b7d028745c2a4045b69e745df2ae6a (patch)
tree44af1379a0a20cef44c260f958a18d9c124cd8ef /clang/lib/Interpreter/Interpreter.cpp
parent3216bf1b963b47752e48d54e4526160489f7677b (diff)
downloadllvm-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.cpp157
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);