https://github.com/anutosh491 updated https://github.com/llvm/llvm-project/pull/230047
>From e3424c5c3a7f2cdd8dcffa74b246e4e883f953d1 Mon Sep 17 00:00:00 2001 From: anutosh491 <[email protected]> Date: Thu, 8 Oct 2026 15:18:59 +0530 Subject: [PATCH 1/4] [clang-repl] Split incremental executor builders by backend --- .../clang/Interpreter/IncrementalExecutor.h | 55 ++++---------- .../OrcIncrementalExecutorBuilder.h | 73 +++++++++++++++++++ clang/lib/Interpreter/CMakeLists.txt | 3 +- .../IncrementalExecutorBuilder.cpp | 27 +++++++ clang/lib/Interpreter/Interpreter.cpp | 2 +- ....cpp => OrcIncrementalExecutorBuilder.cpp} | 25 ++++--- clang/lib/Interpreter/Wasm.cpp | 26 ++----- clang/lib/Interpreter/Wasm.h | 7 ++ clang/tools/clang-repl/ClangRepl.cpp | 4 +- .../Interpreter/InterpreterExtensionsTest.cpp | 5 +- .../OutOfProcessInterpreterTests.cpp | 4 +- 11 files changed, 154 insertions(+), 77 deletions(-) create mode 100644 clang/include/clang/Interpreter/OrcIncrementalExecutorBuilder.h create mode 100644 clang/lib/Interpreter/IncrementalExecutorBuilder.cpp rename clang/lib/Interpreter/{IncrementalExecutor.cpp => OrcIncrementalExecutorBuilder.cpp} (95%) diff --git a/clang/include/clang/Interpreter/IncrementalExecutor.h b/clang/include/clang/Interpreter/IncrementalExecutor.h index 2e037d1f090e5..bb49e673cb529 100644 --- a/clang/include/clang/Interpreter/IncrementalExecutor.h +++ b/clang/include/clang/Interpreter/IncrementalExecutor.h @@ -13,13 +13,15 @@ #ifndef LLVM_CLANG_LIB_INTERPRETER_INCREMENTALEXECUTOR_H #define LLVM_CLANG_LIB_INTERPRETER_INCREMENTALEXECUTOR_H -#include "llvm/Support/CodeGen.h" #include "llvm/Support/Error.h" +#include <memory> +#include <string> +#include <vector> + namespace llvm { namespace orc { class ExecutorAddr; -class LLJITBuilder; class ThreadSafeContext; } // namespace orc } // namespace llvm @@ -27,53 +29,28 @@ class ThreadSafeContext; namespace clang { class IncrementalExecutor; class TargetInfo; -namespace driver { -class Compilation; -} // namespace driver +/// Common configuration and interface for incremental executor builders. class IncrementalExecutorBuilder { public: - /// Indicates whether out-of-process JIT execution is enabled. - bool IsOutOfProcess = false; - /// Path to the out-of-process JIT executor. - std::string OOPExecutor = ""; - std::string OOPExecutorConnect = ""; - /// Indicates whether to use shared memory for communication. - bool UseSharedMemory = false; - /// Representing the slab allocation size for memory management in kb. - unsigned SlabAllocateSize = 0; - /// Path to the ORC runtime library. - std::string OrcRuntimePath = ""; - /// PID of the out-of-process JIT executor. - uint32_t ExecutorPID = 0; - /// Custom lambda to be executed inside child process/executor - std::function<void()> CustomizeFork = nullptr; - /// An optional code model to provide to the JITTargetMachineBuilder - std::optional<llvm::CodeModel::Model> CM = std::nullopt; - /// An optional external IncrementalExecutor + /// An optional external IncrementalExecutor. std::unique_ptr<IncrementalExecutor> IE; - /// mllvm args from the frontend; on wasm these are re-applied after each - /// lldMain call because lld resets all cl options for test-isolation - /// purposes. + /// Frontend -mllvm arguments for backends that need to restore LLVM options. std::vector<std::string> LLVMArgs; -#ifndef __EMSCRIPTEN__ - /// An optional external orc jit builder - std::unique_ptr<llvm::orc::LLJITBuilder> JITBuilder; -#endif - /// A default callback that can be used in the IncrementalCompilerBuilder to - /// retrieve the path to the orc runtime. - std::function<llvm::Error(const driver::Compilation &)> - UpdateOrcRuntimePathCB = [this](const driver::Compilation &C) { - return UpdateOrcRuntimePath(C); - }; - - ~IncrementalExecutorBuilder(); + virtual ~IncrementalExecutorBuilder(); + + /// Create the default builder for the platform clangInterpreter is built for. + static std::unique_ptr<IncrementalExecutorBuilder> createDefault(); + + /// Return the supplied executor, or create one using the selected backend. llvm::Expected<std::unique_ptr<IncrementalExecutor>> create(llvm::orc::ThreadSafeContext &TSC, const clang::TargetInfo &TI); private: - llvm::Error UpdateOrcRuntimePath(const driver::Compilation &C); + virtual llvm::Expected<std::unique_ptr<IncrementalExecutor>> + createExecutor(llvm::orc::ThreadSafeContext &TSC, + const clang::TargetInfo &TI) = 0; }; struct PartialTranslationUnit; diff --git a/clang/include/clang/Interpreter/OrcIncrementalExecutorBuilder.h b/clang/include/clang/Interpreter/OrcIncrementalExecutorBuilder.h new file mode 100644 index 0000000000000..d443f69f65710 --- /dev/null +++ b/clang/include/clang/Interpreter/OrcIncrementalExecutorBuilder.h @@ -0,0 +1,73 @@ +//===-- OrcIncrementalExecutorBuilder.h - ORC Builder -----------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file declares the builder for ORC incremental execution. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_INTERPRETER_ORCINCREMENTALEXECUTORBUILDER_H +#define LLVM_CLANG_INTERPRETER_ORCINCREMENTALEXECUTORBUILDER_H + +#include "clang/Interpreter/IncrementalExecutor.h" +#include "llvm/Support/CodeGen.h" + +#include <cstdint> +#include <functional> +#include <optional> + +namespace llvm::orc { +class LLJITBuilder; +} + +namespace clang { +namespace driver { +class Compilation; +} + +/// Configuration for in-process and out-of-process ORC execution. +class OrcIncrementalExecutorBuilder : public IncrementalExecutorBuilder { +public: + /// Indicates whether out-of-process JIT execution is enabled. + bool IsOutOfProcess = false; + /// Path to the out-of-process JIT executor. + std::string OOPExecutor = ""; + std::string OOPExecutorConnect = ""; + /// Indicates whether to use shared memory for communication. + bool UseSharedMemory = false; + /// Representing the slab allocation size for memory management in kb. + unsigned SlabAllocateSize = 0; + /// Path to the ORC runtime library. + std::string OrcRuntimePath = ""; + /// PID of the out-of-process JIT executor. + uint32_t ExecutorPID = 0; + /// Custom lambda to be executed inside child process/executor + std::function<void()> CustomizeFork = nullptr; + /// An optional code model to provide to the JITTargetMachineBuilder + std::optional<llvm::CodeModel::Model> CM = std::nullopt; + /// An optional external ORC JIT builder. + std::unique_ptr<llvm::orc::LLJITBuilder> JITBuilder; + /// A default callback that can be used in the IncrementalCompilerBuilder to + /// retrieve the path to the orc runtime. + std::function<llvm::Error(const driver::Compilation &)> + UpdateOrcRuntimePathCB = [this](const driver::Compilation &C) { + return UpdateOrcRuntimePath(C); + }; + + OrcIncrementalExecutorBuilder(); + ~OrcIncrementalExecutorBuilder() override; + +private: + llvm::Expected<std::unique_ptr<IncrementalExecutor>> + createExecutor(llvm::orc::ThreadSafeContext &TSC, + const clang::TargetInfo &TI) override; + llvm::Error UpdateOrcRuntimePath(const driver::Compilation &C); +}; + +} // namespace clang + +#endif // LLVM_CLANG_INTERPRETER_ORCINCREMENTALEXECUTORBUILDER_H diff --git a/clang/lib/Interpreter/CMakeLists.txt b/clang/lib/Interpreter/CMakeLists.txt index 95bac67e1b9db..e945ba96afbee 100644 --- a/clang/lib/Interpreter/CMakeLists.txt +++ b/clang/lib/Interpreter/CMakeLists.txt @@ -22,13 +22,14 @@ else() OrcShared OrcTargetProcess ) - set(EXECUTOR_SOURCES IncrementalExecutor.cpp OrcIncrementalExecutor.cpp) + set(EXECUTOR_SOURCES OrcIncrementalExecutorBuilder.cpp OrcIncrementalExecutor.cpp) endif() add_clang_library(clangInterpreter DeviceOffload.cpp CodeCompletion.cpp IncrementalAction.cpp + IncrementalExecutorBuilder.cpp IncrementalParser.cpp Interpreter.cpp InterpreterValuePrinter.cpp diff --git a/clang/lib/Interpreter/IncrementalExecutorBuilder.cpp b/clang/lib/Interpreter/IncrementalExecutorBuilder.cpp new file mode 100644 index 0000000000000..f1110ebca99af --- /dev/null +++ b/clang/lib/Interpreter/IncrementalExecutorBuilder.cpp @@ -0,0 +1,27 @@ +//===-- IncrementalExecutorBuilder.cpp - Executor Builder ------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This implements the common incremental executor builder. +// +//===----------------------------------------------------------------------===// + +#include "clang/Interpreter/IncrementalExecutor.h" + +namespace clang { + +IncrementalExecutorBuilder::~IncrementalExecutorBuilder() = default; + +llvm::Expected<std::unique_ptr<IncrementalExecutor>> +IncrementalExecutorBuilder::create(llvm::orc::ThreadSafeContext &TSC, + const clang::TargetInfo &TI) { + if (IE) + return std::move(IE); + return createExecutor(TSC, TI); +} + +} // namespace clang diff --git a/clang/lib/Interpreter/Interpreter.cpp b/clang/lib/Interpreter/Interpreter.cpp index 85cefa1270049..0070f2ee35347 100644 --- a/clang/lib/Interpreter/Interpreter.cpp +++ b/clang/lib/Interpreter/Interpreter.cpp @@ -609,7 +609,7 @@ llvm::Error Interpreter::CreateExecutor() { std::error_code()); if (!IncrExecutorBuilder) - IncrExecutorBuilder = std::make_unique<IncrementalExecutorBuilder>(); + IncrExecutorBuilder = IncrementalExecutorBuilder::createDefault(); // Propagate mllvm args so the wasm executor can restore them after each // lldMain invocation (which resets all cl options for test isolation). diff --git a/clang/lib/Interpreter/IncrementalExecutor.cpp b/clang/lib/Interpreter/OrcIncrementalExecutorBuilder.cpp similarity index 95% rename from clang/lib/Interpreter/IncrementalExecutor.cpp rename to clang/lib/Interpreter/OrcIncrementalExecutorBuilder.cpp index db805bb4219a4..59e375a85fab7 100644 --- a/clang/lib/Interpreter/IncrementalExecutor.cpp +++ b/clang/lib/Interpreter/OrcIncrementalExecutorBuilder.cpp @@ -1,4 +1,4 @@ -//===--- IncrementalExecutor.cpp - Incremental Execution --------*- C++ -*-===// +//===-- OrcIncrementalExecutorBuilder.cpp - ORC Builder --------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,11 +6,11 @@ // //===----------------------------------------------------------------------===// // -// This has the implementation of the base facilities for incremental execution. +// This implements the builder for ORC incremental execution. // //===----------------------------------------------------------------------===// -#include "clang/Interpreter/IncrementalExecutor.h" +#include "clang/Interpreter/OrcIncrementalExecutorBuilder.h" #include "OrcIncrementalExecutor.h" #include "clang/Basic/TargetInfo.h" @@ -81,7 +81,13 @@ static void *getEmuTLSGetAddressPtr() { return nullptr; } #endif namespace clang { -IncrementalExecutorBuilder::~IncrementalExecutorBuilder() = default; +OrcIncrementalExecutorBuilder::OrcIncrementalExecutorBuilder() = default; +OrcIncrementalExecutorBuilder::~OrcIncrementalExecutorBuilder() = default; + +std::unique_ptr<IncrementalExecutorBuilder> +IncrementalExecutorBuilder::createDefault() { + return std::make_unique<OrcIncrementalExecutorBuilder>(); +} static llvm::Expected<llvm::orc::JITTargetMachineBuilder> createJITTargetMachineBuilder(const llvm::Triple &TT) { @@ -321,7 +327,8 @@ createLLJITBuilder(std::unique_ptr<llvm::orc::ExecutorProcessControl> EPC, static llvm::Expected< std::pair<std::unique_ptr<llvm::orc::LLJITBuilder>, uint32_t>> -outOfProcessJITBuilder(const IncrementalExecutorBuilder &IncrExecutorBuilder) { +outOfProcessJITBuilder( + const OrcIncrementalExecutorBuilder &IncrExecutorBuilder) { std::unique_ptr<llvm::orc::ExecutorProcessControl> EPC; uint32_t childPid = -1; if (!IncrExecutorBuilder.OOPExecutor.empty()) { @@ -367,10 +374,8 @@ outOfProcessJITBuilder(const IncrementalExecutorBuilder &IncrExecutorBuilder) { } llvm::Expected<std::unique_ptr<IncrementalExecutor>> -IncrementalExecutorBuilder::create(llvm::orc::ThreadSafeContext &TSC, - const clang::TargetInfo &TI) { - if (IE) - return std::move(IE); +OrcIncrementalExecutorBuilder::createExecutor(llvm::orc::ThreadSafeContext &TSC, + const clang::TargetInfo &TI) { llvm::Triple TT = TI.getTriple(); if (!TT.isOSWindows() && IsOutOfProcess) { if (!JITBuilder) { @@ -433,7 +438,7 @@ IncrementalExecutorBuilder::create(llvm::orc::ThreadSafeContext &TSC, return std::move(Executor); } -llvm::Error IncrementalExecutorBuilder::UpdateOrcRuntimePath( +llvm::Error OrcIncrementalExecutorBuilder::UpdateOrcRuntimePath( const clang::driver::Compilation &C) { if (!IsOutOfProcess) return llvm::Error::success(); diff --git a/clang/lib/Interpreter/Wasm.cpp b/clang/lib/Interpreter/Wasm.cpp index dbafaae85b556..9351ab642c707 100644 --- a/clang/lib/Interpreter/Wasm.cpp +++ b/clang/lib/Interpreter/Wasm.cpp @@ -62,19 +62,14 @@ bool link(llvm::ArrayRef<const char *> args, llvm::raw_ostream &stdoutOS, namespace clang { -IncrementalExecutorBuilder::~IncrementalExecutorBuilder() = default; +std::unique_ptr<IncrementalExecutorBuilder> +IncrementalExecutorBuilder::createDefault() { + return std::make_unique<WasmIncrementalExecutorBuilder>(); +} llvm::Expected<std::unique_ptr<IncrementalExecutor>> -IncrementalExecutorBuilder::create(llvm::orc::ThreadSafeContext &TSC, - const clang::TargetInfo &TI) { - if (IE) - return std::move(IE); - - if (IsOutOfProcess) - return llvm::createStringError(llvm::inconvertibleErrorCode(), - "Out-of-process execution is not supported " - "by the WebAssembly executor"); - +WasmIncrementalExecutorBuilder::createExecutor( + llvm::orc::ThreadSafeContext &TSC, const clang::TargetInfo &TI) { llvm::Error Err = llvm::Error::success(); std::unique_ptr<IncrementalExecutor> Executor = std::make_unique<WasmIncrementalExecutor>(Err, LLVMArgs); @@ -83,15 +78,6 @@ IncrementalExecutorBuilder::create(llvm::orc::ThreadSafeContext &TSC, return std::move(Executor); } -llvm::Error IncrementalExecutorBuilder::UpdateOrcRuntimePath( - const clang::driver::Compilation &C) { - if (IsOutOfProcess) - return llvm::createStringError(llvm::inconvertibleErrorCode(), - "Out-of-process execution is not supported " - "by the WebAssembly executor"); - return llvm::Error::success(); -} - WasmIncrementalExecutor::WasmIncrementalExecutor( llvm::Error &Err, std::vector<std::string> LLVMArgs) : StoredLLVMArgs(std::move(LLVMArgs)) { diff --git a/clang/lib/Interpreter/Wasm.h b/clang/lib/Interpreter/Wasm.h index 6340393dc6b9b..3adf82cdacb7c 100644 --- a/clang/lib/Interpreter/Wasm.h +++ b/clang/lib/Interpreter/Wasm.h @@ -24,6 +24,13 @@ namespace clang { +class WasmIncrementalExecutorBuilder : public IncrementalExecutorBuilder { +private: + llvm::Expected<std::unique_ptr<IncrementalExecutor>> + createExecutor(llvm::orc::ThreadSafeContext &TSC, + const clang::TargetInfo &TI) override; +}; + class WasmIncrementalExecutor : public IncrementalExecutor { public: WasmIncrementalExecutor(llvm::Error &Err, std::vector<std::string> LLVMArgs); diff --git a/clang/tools/clang-repl/ClangRepl.cpp b/clang/tools/clang-repl/ClangRepl.cpp index c9873540a5d66..8957a74ce17cf 100644 --- a/clang/tools/clang-repl/ClangRepl.cpp +++ b/clang/tools/clang-repl/ClangRepl.cpp @@ -16,8 +16,8 @@ #include "clang/Config/config.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Interpreter/CodeCompletion.h" -#include "clang/Interpreter/IncrementalExecutor.h" #include "clang/Interpreter/Interpreter.h" +#include "clang/Interpreter/OrcIncrementalExecutorBuilder.h" #include "clang/Lex/Preprocessor.h" #include "clang/Sema/Sema.h" @@ -294,7 +294,7 @@ int main(int argc, const char **argv) { clang::IncrementalCompilerBuilder CB; CB.SetCompilerArgs(ClangArgv); - auto IEB = std::make_unique<clang::IncrementalExecutorBuilder>(); + auto IEB = std::make_unique<clang::OrcIncrementalExecutorBuilder>(); IEB->IsOutOfProcess = !OOPExecutor.empty() || !OOPExecutorConnect.empty(); IEB->OOPExecutor = OOPExecutor; if (!OrcRuntimePath.empty()) diff --git a/clang/unittests/Interpreter/InterpreterExtensionsTest.cpp b/clang/unittests/Interpreter/InterpreterExtensionsTest.cpp index 642869e124b8b..f1cd3b38fbfd9 100644 --- a/clang/unittests/Interpreter/InterpreterExtensionsTest.cpp +++ b/clang/unittests/Interpreter/InterpreterExtensionsTest.cpp @@ -13,6 +13,7 @@ #include "InterpreterTestFixture.h" #include "clang/Interpreter/Interpreter.h" +#include "clang/Interpreter/OrcIncrementalExecutorBuilder.h" #include "clang/AST/Expr.h" #include "clang/Frontend/CompilerInstance.h" @@ -125,7 +126,7 @@ TEST_F(InterpreterExtensionsTest, CustomCrossJIT) { JIT = &J; return llvm::Error::success(); }); - auto IEB = std::make_unique<IncrementalExecutorBuilder>(); + auto IEB = std::make_unique<OrcIncrementalExecutorBuilder>(); IEB->JITBuilder = std::move(JB); llvm::Error ErrOut = llvm::Error::success(); CustomJBInterpreter Interp(std::move(CI), ErrOut, std::move(IEB)); @@ -181,7 +182,7 @@ TEST_F(InterpreterExtensionsTest, CustomIncrementalExecutor) { }; // Prepare a builder that hands out our recording executor. - auto B = std::make_unique<IncrementalExecutorBuilder>(); + auto B = IncrementalExecutorBuilder::createDefault(); B->IE = std::make_unique<RecordingIncrementalExecutor>(); IncrementalCompilerBuilder CB; diff --git a/clang/unittests/Interpreter/OutOfProcessInterpreterTests.cpp b/clang/unittests/Interpreter/OutOfProcessInterpreterTests.cpp index 3684e7e8148fa..f67ad02d918c6 100644 --- a/clang/unittests/Interpreter/OutOfProcessInterpreterTests.cpp +++ b/clang/unittests/Interpreter/OutOfProcessInterpreterTests.cpp @@ -18,8 +18,8 @@ #include "clang/AST/Mangle.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Frontend/TextDiagnosticPrinter.h" -#include "clang/Interpreter/IncrementalExecutor.h" #include "clang/Interpreter/Interpreter.h" +#include "clang/Interpreter/OrcIncrementalExecutorBuilder.h" #include "clang/Interpreter/Value.h" #include "clang/Sema/Lookup.h" #include "clang/Sema/Sema.h" @@ -115,7 +115,7 @@ createInterpreterWithRemoteExecution(std::shared_ptr<IOContext> io_ctx, Args ClangArgs = {"-Xclang", "-emit-llvm-only"}; llvm::append_range(ClangArgs, ExtraArgs); - auto Config = std::make_unique<IncrementalExecutorBuilder>(); + auto Config = std::make_unique<OrcIncrementalExecutorBuilder>(); Config->IsOutOfProcess = true; Config->OOPExecutor = getExecutorPath(); >From 1cad10520464fcfd01dcf5cbcff29fcfd26dc133 Mon Sep 17 00:00:00 2001 From: anutosh491 <[email protected]> Date: Thu, 8 Oct 2026 18:34:53 +0530 Subject: [PATCH 2/4] [clang-repl] Fix executor builder selection for Emscripten --- .../clang/Interpreter/IncrementalExecutor.h | 1 + clang/tools/clang-repl/ClangRepl.cpp | 20 +++++++++++++------ 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/clang/include/clang/Interpreter/IncrementalExecutor.h b/clang/include/clang/Interpreter/IncrementalExecutor.h index bb49e673cb529..815e2b2d9bf5c 100644 --- a/clang/include/clang/Interpreter/IncrementalExecutor.h +++ b/clang/include/clang/Interpreter/IncrementalExecutor.h @@ -41,6 +41,7 @@ class IncrementalExecutorBuilder { virtual ~IncrementalExecutorBuilder(); /// Create the default builder for the platform clangInterpreter is built for. + /// The selected backend provides this definition. static std::unique_ptr<IncrementalExecutorBuilder> createDefault(); /// Return the supplied executor, or create one using the selected backend. diff --git a/clang/tools/clang-repl/ClangRepl.cpp b/clang/tools/clang-repl/ClangRepl.cpp index 8957a74ce17cf..eadb8b2e72368 100644 --- a/clang/tools/clang-repl/ClangRepl.cpp +++ b/clang/tools/clang-repl/ClangRepl.cpp @@ -108,7 +108,10 @@ static llvm::Error sanitizeOopArguments(const char *ArgV0) { (OOPExecutor.getNumOccurrences() || OOPExecutorConnect.getNumOccurrences())) return llvm::make_error<llvm::StringError>( - "Out-of-process execution is only supported on Unix platforms", + SystemTriple.isOSEmscripten() + ? "Out-of-process execution is not supported by the WebAssembly " + "executor" + : "Out-of-process execution is only supported on Unix platforms", llvm::inconvertibleErrorCode()); // If -slab-allocate is passed, check that we're not trying to use it in @@ -294,6 +297,15 @@ int main(int argc, const char **argv) { clang::IncrementalCompilerBuilder CB; CB.SetCompilerArgs(ClangArgv); + auto SizeOrErr = getSlabAllocSize(SlabAllocateSizeString); + if (!SizeOrErr) { + llvm::logAllUnhandledErrors(SizeOrErr.takeError(), llvm::errs(), "error: "); + return EXIT_FAILURE; + } + +#ifdef __EMSCRIPTEN__ + auto IEB = clang::IncrementalExecutorBuilder::createDefault(); +#else auto IEB = std::make_unique<clang::OrcIncrementalExecutorBuilder>(); IEB->IsOutOfProcess = !OOPExecutor.empty() || !OOPExecutorConnect.empty(); IEB->OOPExecutor = OOPExecutor; @@ -302,13 +314,9 @@ int main(int argc, const char **argv) { else CB.SetDriverCompilationCallback(IEB->UpdateOrcRuntimePathCB); - auto SizeOrErr = getSlabAllocSize(SlabAllocateSizeString); - if (!SizeOrErr) { - llvm::logAllUnhandledErrors(SizeOrErr.takeError(), llvm::errs(), "error: "); - return EXIT_FAILURE; - } IEB->SlabAllocateSize = *SizeOrErr; IEB->UseSharedMemory = UseSharedMemory; +#endif std::unique_ptr<clang::CompilerInstance> DeviceCI; if (CudaEnabled) { >From e0c7e123cb6b8d6786681f8f40c2bb5068681c41 Mon Sep 17 00:00:00 2001 From: anutosh491 <[email protected]> Date: Thu, 8 Oct 2026 20:28:23 +0530 Subject: [PATCH 3/4] [clang-repl] Build Emscripten tool without ORC dependencies --- clang/tools/clang-repl/CMakeLists.txt | 17 +++++++++++++++-- clang/tools/clang-repl/ClangRepl.cpp | 11 +++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/clang/tools/clang-repl/CMakeLists.txt b/clang/tools/clang-repl/CMakeLists.txt index c3d14ceb79792..bd66fa5aeb3d4 100644 --- a/clang/tools/clang-repl/CMakeLists.txt +++ b/clang/tools/clang-repl/CMakeLists.txt @@ -3,18 +3,31 @@ set( LLVM_LINK_COMPONENTS Core LineEditor Option - OrcJIT - OrcShared Support TargetParser ) +if(NOT EMSCRIPTEN) + list(APPEND LLVM_LINK_COMPONENTS OrcJIT OrcShared) +endif() + add_clang_tool(clang-repl ClangRepl.cpp EXPORT_SYMBOLS ) +if(EMSCRIPTEN) + # Incremental modules use dlopen and resolve symbols from the tool. + target_link_options(clang-repl PRIVATE + "-fwasm-exceptions" + "SHELL:-s MAIN_MODULE=1" + "LINKER:--export=__clang_Interpreter_SetValueWithAlloc" + "LINKER:--export=__clang_Interpreter_SetValueNoAlloc" + "LINKER:--export=_ZnwmPv26__clang_Interpreter_NewTag" + ) +endif() + if(MSVC) set_target_properties(clang-repl PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS 1) diff --git a/clang/tools/clang-repl/ClangRepl.cpp b/clang/tools/clang-repl/ClangRepl.cpp index eadb8b2e72368..a5165109c65eb 100644 --- a/clang/tools/clang-repl/ClangRepl.cpp +++ b/clang/tools/clang-repl/ClangRepl.cpp @@ -276,6 +276,16 @@ int main(int argc, const char **argv) { llvm::InitializeAllAsmPrinters(); llvm::InitializeAllAsmParsers(); +#ifdef __EMSCRIPTEN__ + if (OptHostSupportsJit) { + llvm::outs() << "false\n"; + return 0; + } else if (OptHostJitTriple) { + llvm::outs() << llvm::Triple::normalize(llvm::sys::getProcessTriple()) + << '\n'; + return 0; + } +#else if (OptHostSupportsJit) { auto J = llvm::orc::LLJITBuilder().create(); if (J) @@ -291,6 +301,7 @@ int main(int argc, const char **argv) { llvm::outs() << T.normalize() << '\n'; return 0; } +#endif ExitOnErr(sanitizeOopArguments(argv[0])); >From 7baf532f057c9ac715641df8d052487a63bafcb8 Mon Sep 17 00:00:00 2001 From: anutosh491 <[email protected]> Date: Thu, 8 Oct 2026 21:25:27 +0530 Subject: [PATCH 4/4] [clang-repl] Hide backend setup behind executor builders --- .../clang/Interpreter/IncrementalExecutor.h | 21 ++++++++ .../OrcIncrementalExecutorBuilder.h | 5 ++ .../OrcIncrementalExecutorBuilder.cpp | 31 ++++++++++++ clang/lib/Interpreter/Wasm.cpp | 15 ++++++ clang/lib/Interpreter/Wasm.h | 6 +++ clang/tools/clang-repl/CMakeLists.txt | 4 -- clang/tools/clang-repl/ClangRepl.cpp | 49 +++++-------------- 7 files changed, 89 insertions(+), 42 deletions(-) diff --git a/clang/include/clang/Interpreter/IncrementalExecutor.h b/clang/include/clang/Interpreter/IncrementalExecutor.h index 815e2b2d9bf5c..6615355b798c1 100644 --- a/clang/include/clang/Interpreter/IncrementalExecutor.h +++ b/clang/include/clang/Interpreter/IncrementalExecutor.h @@ -20,6 +20,7 @@ #include <vector> namespace llvm { +class Triple; namespace orc { class ExecutorAddr; class ThreadSafeContext; @@ -28,11 +29,21 @@ class ThreadSafeContext; namespace clang { class IncrementalExecutor; +class IncrementalCompilerBuilder; class TargetInfo; /// Common configuration and interface for incremental executor builders. class IncrementalExecutorBuilder { public: + /// Options passed to the backend when configuring execution. + struct Options { + bool IsOutOfProcess = false; + std::string ExecutorPath; + std::string RuntimePath; + unsigned SlabAllocateSize = 0; + bool UseSharedMemory = false; + }; + /// An optional external IncrementalExecutor. std::unique_ptr<IncrementalExecutor> IE; /// Frontend -mllvm arguments for backends that need to restore LLVM options. @@ -44,6 +55,16 @@ class IncrementalExecutorBuilder { /// The selected backend provides this definition. static std::unique_ptr<IncrementalExecutorBuilder> createDefault(); + /// Apply execution options and configure the compiler for this backend. + virtual llvm::Error configure(IncrementalCompilerBuilder &CB, + const Options &Opts) = 0; + + /// Probe whether this backend can JIT code for the host. + virtual bool supportsJIT() const = 0; + + /// Return the host triple used by this backend. + virtual llvm::Expected<llvm::Triple> getHostJITTriple() const = 0; + /// Return the supplied executor, or create one using the selected backend. llvm::Expected<std::unique_ptr<IncrementalExecutor>> create(llvm::orc::ThreadSafeContext &TSC, const clang::TargetInfo &TI); diff --git a/clang/include/clang/Interpreter/OrcIncrementalExecutorBuilder.h b/clang/include/clang/Interpreter/OrcIncrementalExecutorBuilder.h index d443f69f65710..98de99bb99f4e 100644 --- a/clang/include/clang/Interpreter/OrcIncrementalExecutorBuilder.h +++ b/clang/include/clang/Interpreter/OrcIncrementalExecutorBuilder.h @@ -61,6 +61,11 @@ class OrcIncrementalExecutorBuilder : public IncrementalExecutorBuilder { OrcIncrementalExecutorBuilder(); ~OrcIncrementalExecutorBuilder() override; + llvm::Error configure(IncrementalCompilerBuilder &CB, + const Options &Opts) override; + bool supportsJIT() const override; + llvm::Expected<llvm::Triple> getHostJITTriple() const override; + private: llvm::Expected<std::unique_ptr<IncrementalExecutor>> createExecutor(llvm::orc::ThreadSafeContext &TSC, diff --git a/clang/lib/Interpreter/OrcIncrementalExecutorBuilder.cpp b/clang/lib/Interpreter/OrcIncrementalExecutorBuilder.cpp index 59e375a85fab7..89db2d71197a0 100644 --- a/clang/lib/Interpreter/OrcIncrementalExecutorBuilder.cpp +++ b/clang/lib/Interpreter/OrcIncrementalExecutorBuilder.cpp @@ -18,6 +18,7 @@ #include "clang/Driver/Compilation.h" #include "clang/Driver/Driver.h" #include "clang/Driver/ToolChain.h" +#include "clang/Interpreter/Interpreter.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" @@ -89,6 +90,36 @@ IncrementalExecutorBuilder::createDefault() { return std::make_unique<OrcIncrementalExecutorBuilder>(); } +llvm::Error +OrcIncrementalExecutorBuilder::configure(IncrementalCompilerBuilder &CB, + const Options &Opts) { + IsOutOfProcess = Opts.IsOutOfProcess; + OOPExecutor = Opts.ExecutorPath; + OrcRuntimePath = Opts.RuntimePath; + if (OrcRuntimePath.empty()) + CB.SetDriverCompilationCallback(UpdateOrcRuntimePathCB); + SlabAllocateSize = Opts.SlabAllocateSize; + UseSharedMemory = Opts.UseSharedMemory; + return llvm::Error::success(); +} + +bool OrcIncrementalExecutorBuilder::supportsJIT() const { + auto Triple = getHostJITTriple(); + if (!Triple) { + llvm::consumeError(Triple.takeError()); + return false; + } + return true; +} + +llvm::Expected<llvm::Triple> +OrcIncrementalExecutorBuilder::getHostJITTriple() const { + auto J = llvm::orc::LLJITBuilder().create(); + if (!J) + return J.takeError(); + return (*J)->getTargetTriple(); +} + static llvm::Expected<llvm::orc::JITTargetMachineBuilder> createJITTargetMachineBuilder(const llvm::Triple &TT) { if (TT.getTriple() == llvm::sys::getProcessTriple()) diff --git a/clang/lib/Interpreter/Wasm.cpp b/clang/lib/Interpreter/Wasm.cpp index 9351ab642c707..95e3b2f1ad96c 100644 --- a/clang/lib/Interpreter/Wasm.cpp +++ b/clang/lib/Interpreter/Wasm.cpp @@ -15,6 +15,7 @@ #include "llvm/Support/CommandLine.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Path.h" +#include "llvm/TargetParser/Host.h" #include <llvm/IR/LegacyPassManager.h> #include <llvm/IR/Module.h> #include <llvm/MC/TargetRegistry.h> @@ -67,6 +68,20 @@ IncrementalExecutorBuilder::createDefault() { return std::make_unique<WasmIncrementalExecutorBuilder>(); } +llvm::Error +WasmIncrementalExecutorBuilder::configure(IncrementalCompilerBuilder &CB, + const Options &Opts) { + if (Opts.IsOutOfProcess) + return llvm::createStringError("Out-of-process execution is not supported " + "by the WebAssembly executor"); + return llvm::Error::success(); +} + +llvm::Expected<llvm::Triple> +WasmIncrementalExecutorBuilder::getHostJITTriple() const { + return llvm::Triple(llvm::sys::getProcessTriple()); +} + llvm::Expected<std::unique_ptr<IncrementalExecutor>> WasmIncrementalExecutorBuilder::createExecutor( llvm::orc::ThreadSafeContext &TSC, const clang::TargetInfo &TI) { diff --git a/clang/lib/Interpreter/Wasm.h b/clang/lib/Interpreter/Wasm.h index 3adf82cdacb7c..4eb6c8d05f37d 100644 --- a/clang/lib/Interpreter/Wasm.h +++ b/clang/lib/Interpreter/Wasm.h @@ -25,6 +25,12 @@ namespace clang { class WasmIncrementalExecutorBuilder : public IncrementalExecutorBuilder { +public: + llvm::Error configure(IncrementalCompilerBuilder &CB, + const Options &Opts) override; + bool supportsJIT() const override { return false; } + llvm::Expected<llvm::Triple> getHostJITTriple() const override; + private: llvm::Expected<std::unique_ptr<IncrementalExecutor>> createExecutor(llvm::orc::ThreadSafeContext &TSC, diff --git a/clang/tools/clang-repl/CMakeLists.txt b/clang/tools/clang-repl/CMakeLists.txt index bd66fa5aeb3d4..f83a7e607899b 100644 --- a/clang/tools/clang-repl/CMakeLists.txt +++ b/clang/tools/clang-repl/CMakeLists.txt @@ -7,10 +7,6 @@ set( LLVM_LINK_COMPONENTS TargetParser ) -if(NOT EMSCRIPTEN) - list(APPEND LLVM_LINK_COMPONENTS OrcJIT OrcShared) -endif() - add_clang_tool(clang-repl ClangRepl.cpp diff --git a/clang/tools/clang-repl/ClangRepl.cpp b/clang/tools/clang-repl/ClangRepl.cpp index a5165109c65eb..b98230d430666 100644 --- a/clang/tools/clang-repl/ClangRepl.cpp +++ b/clang/tools/clang-repl/ClangRepl.cpp @@ -17,13 +17,11 @@ #include "clang/Frontend/CompilerInstance.h" #include "clang/Interpreter/CodeCompletion.h" #include "clang/Interpreter/Interpreter.h" -#include "clang/Interpreter/OrcIncrementalExecutorBuilder.h" #include "clang/Lex/Preprocessor.h" #include "clang/Sema/Sema.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringRef.h" -#include "llvm/ExecutionEngine/Orc/LLJIT.h" #include "llvm/LineEditor/LineEditor.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/FileSystem.h" @@ -40,8 +38,6 @@ #include <string> #include <vector> -#include "llvm/ExecutionEngine/Orc/Debugging/DebuggerSupport.h" - // Disable LSan for this test. // FIXME: Re-enable once we can assume GCC 13.2 or higher. // https://llvm.org/github.com/llvm/llvm-project/issues/67586. @@ -276,32 +272,15 @@ int main(int argc, const char **argv) { llvm::InitializeAllAsmPrinters(); llvm::InitializeAllAsmParsers(); -#ifdef __EMSCRIPTEN__ - if (OptHostSupportsJit) { - llvm::outs() << "false\n"; - return 0; - } else if (OptHostJitTriple) { - llvm::outs() << llvm::Triple::normalize(llvm::sys::getProcessTriple()) - << '\n'; - return 0; - } -#else + auto IEB = clang::IncrementalExecutorBuilder::createDefault(); if (OptHostSupportsJit) { - auto J = llvm::orc::LLJITBuilder().create(); - if (J) - llvm::outs() << "true\n"; - else { - llvm::consumeError(J.takeError()); - llvm::outs() << "false\n"; - } + llvm::outs() << (IEB->supportsJIT() ? "true\n" : "false\n"); return 0; } else if (OptHostJitTriple) { - auto J = ExitOnErr(llvm::orc::LLJITBuilder().create()); - auto T = J->getTargetTriple(); + auto T = ExitOnErr(IEB->getHostJITTriple()); llvm::outs() << T.normalize() << '\n'; return 0; } -#endif ExitOnErr(sanitizeOopArguments(argv[0])); @@ -314,20 +293,14 @@ int main(int argc, const char **argv) { return EXIT_FAILURE; } -#ifdef __EMSCRIPTEN__ - auto IEB = clang::IncrementalExecutorBuilder::createDefault(); -#else - auto IEB = std::make_unique<clang::OrcIncrementalExecutorBuilder>(); - IEB->IsOutOfProcess = !OOPExecutor.empty() || !OOPExecutorConnect.empty(); - IEB->OOPExecutor = OOPExecutor; - if (!OrcRuntimePath.empty()) - IEB->OrcRuntimePath = OrcRuntimePath; - else - CB.SetDriverCompilationCallback(IEB->UpdateOrcRuntimePathCB); - - IEB->SlabAllocateSize = *SizeOrErr; - IEB->UseSharedMemory = UseSharedMemory; -#endif + clang::IncrementalExecutorBuilder::Options ExecutorOpts; + ExecutorOpts.IsOutOfProcess = + !OOPExecutor.empty() || !OOPExecutorConnect.empty(); + ExecutorOpts.ExecutorPath = OOPExecutor; + ExecutorOpts.RuntimePath = OrcRuntimePath; + ExecutorOpts.SlabAllocateSize = *SizeOrErr; + ExecutorOpts.UseSharedMemory = UseSharedMemory; + ExitOnErr(IEB->configure(CB, ExecutorOpts)); std::unique_ptr<clang::CompilerInstance> DeviceCI; if (CudaEnabled) { _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
