https://github.com/kr-2003 updated 
https://github.com/llvm/llvm-project/pull/159693

>From 733ffcdabee19cae2557f7dad8754c55ddf29314 Mon Sep 17 00:00:00 2001
From: kr-2003 <kumar.kr.abhi...@gmail.com>
Date: Fri, 19 Sep 2025 07:21:22 +0530
Subject: [PATCH 1/3] LLJITBuilder in JITConfig

---
 clang/include/clang/Interpreter/Interpreter.h |  29 +++--
 clang/lib/Interpreter/Interpreter.cpp         | 115 ++++++++++--------
 2 files changed, 82 insertions(+), 62 deletions(-)

diff --git a/clang/include/clang/Interpreter/Interpreter.h 
b/clang/include/clang/Interpreter/Interpreter.h
index 078d70b3b1749..7d734897e5584 100644
--- a/clang/include/clang/Interpreter/Interpreter.h
+++ b/clang/include/clang/Interpreter/Interpreter.h
@@ -1,4 +1,5 @@
-//===--- Interpreter.h - Incremental Compilation and Execution---*- C++ 
-*-===//
+//===------ Interpreter.h - Incremental Compilation and Execution---*- C++
+//-*-===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -19,12 +20,14 @@
 #include "clang/Interpreter/Value.h"
 
 #include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/FunctionExtras.h"
 #include "llvm/ExecutionEngine/JITSymbol.h"
 #include "llvm/ExecutionEngine/Orc/ExecutorProcessControl.h"
 #include "llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.h"
 #include "llvm/Support/Error.h"
 #include <cstdint>
 #include <memory>
+#include <optional>
 #include <vector>
 
 namespace llvm {
@@ -32,6 +35,7 @@ namespace orc {
 class LLJIT;
 class LLJITBuilder;
 class ThreadSafeContext;
+class JITTargetMachineBuilder;
 } // namespace orc
 } // namespace llvm
 
@@ -132,18 +136,25 @@ class Interpreter {
     /// Representing the slab allocation size for memory management in kb.
     unsigned SlabAllocateSize = 0;
     /// Path to the ORC runtime library.
-    std::string OrcRuntimePath = "";
+    std::optional<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;
+
+    /// Factory function for creating LLJITBuilder instances.
+    /// This allows clients to customize JIT builder creation while still
+    /// providing sensible defaults.
+    llvm::unique_function<llvm::Expected<
+        std::unique_ptr<llvm::orc::LLJITBuilder>>(const JITConfig &)>
+        MakeJITBuilder = makeDefaultJITBuilder;
 
     JITConfig()
         : IsOutOfProcess(false), OOPExecutor(""), OOPExecutorConnect(""),
-          UseSharedMemory(false), SlabAllocateSize(0), OrcRuntimePath(""),
-          ExecutorPID(0), CustomizeFork(nullptr), CM(std::nullopt) {}
+          UseSharedMemory(false), SlabAllocateSize(0), OrcRuntimePath(),
+          ExecutorPID(0) {}
+
+    /// Default JIT builder factory function
+    static llvm::Expected<std::unique_ptr<llvm::orc::LLJITBuilder>>
+    makeDefaultJITBuilder(const JITConfig &Config);
   };
 
 protected:
@@ -237,4 +248,4 @@ class Interpreter {
 };
 } // namespace clang
 
-#endif // LLVM_CLANG_INTERPRETER_INTERPRETER_H
+#endif // LLVM_CLANG_INTERPRETER_INTERPRETER_H
\ No newline at end of file
diff --git a/clang/lib/Interpreter/Interpreter.cpp 
b/clang/lib/Interpreter/Interpreter.cpp
index 9cc1c450b7650..a613fbf1b8370 100644
--- a/clang/lib/Interpreter/Interpreter.cpp
+++ b/clang/lib/Interpreter/Interpreter.cpp
@@ -350,15 +350,26 @@ const char *const Runtimes = R"(
   EXTERN_C void __clang_Interpreter_SetValueNoAlloc(void *This, void *OutVal, 
void *OpaqueType, ...);
 )";
 
+static llvm::Expected<llvm::orc::JITTargetMachineBuilder>
+createJITTargetMachineBuilder(const std::string &TT) {
+  if (TT == llvm::sys::getProcessTriple())
+    // This fails immediately if the target backend is not registered
+    return llvm::orc::JITTargetMachineBuilder::detectHost();
+
+  // If the target backend is not registered, LLJITBuilder::create() will fail
+  return llvm::orc::JITTargetMachineBuilder(llvm::Triple(TT));
+}
+
+// 5. Update outOfProcessJITBuilder to work with the new system
 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,
-        Config.CustomizeFork);
+        Config.OOPExecutor, Config.UseSharedMemory, Config.SlabAllocateSize);
     if (!ResultOrErr)
       return ResultOrErr.takeError();
     childPid = ResultOrErr->second;
@@ -381,8 +392,10 @@ Interpreter::outOfProcessJITBuilder(JITConfig Config) {
 
   std::unique_ptr<llvm::orc::LLJITBuilder> JB;
   if (EPC) {
-    auto JBOrErr = clang::Interpreter::createLLJITBuilder(
-        std::move(EPC), Config.OrcRuntimePath);
+    std::string RuntimePath =
+        Config.OrcRuntimePath ? *Config.OrcRuntimePath : "";
+    auto JBOrErr =
+        clang::Interpreter::createLLJITBuilder(std::move(EPC), RuntimePath);
     if (!JBOrErr)
       return JBOrErr.takeError();
     JB = std::move(*JBOrErr);
@@ -422,9 +435,9 @@ llvm::Expected<std::unique_ptr<Interpreter>>
 Interpreter::create(std::unique_ptr<CompilerInstance> CI, JITConfig Config) {
   llvm::Error Err = llvm::Error::success();
 
-  std::unique_ptr<llvm::orc::LLJITBuilder> JB;
-
-  if (Config.IsOutOfProcess) {
+  // Auto-discover ORC runtime path if not provided and out-of-process is
+  // enabled
+  if (Config.IsOutOfProcess && !Config.OrcRuntimePath) {
     const TargetInfo &TI = CI->getTarget();
     const llvm::Triple &Triple = TI.getTriple();
 
@@ -440,16 +453,22 @@ Interpreter::create(std::unique_ptr<CompilerInstance> CI, 
JITConfig Config) {
           "Failed to create driver compilation for out-of-process JIT",
           std::error_code());
     }
-    if (Config.OrcRuntimePath == "") {
-      const clang::driver::ToolChain &TC = C->getDefaultToolChain();
+    const clang::driver::ToolChain &TC = C->getDefaultToolChain();
+    auto OrcRuntimePathOrErr = getOrcRuntimePath(TC);
+    if (!OrcRuntimePathOrErr) {
+      return OrcRuntimePathOrErr.takeError();
+    }
 
-      auto OrcRuntimePathOrErr = getOrcRuntimePath(TC);
-      if (!OrcRuntimePathOrErr) {
-        return OrcRuntimePathOrErr.takeError();
-      }
+    Config.OrcRuntimePath = *OrcRuntimePathOrErr;
+  }
 
-      Config.OrcRuntimePath = *OrcRuntimePathOrErr;
-    }
+  std::unique_ptr<llvm::orc::LLJITBuilder> JB;
+  if (Config.IsOutOfProcess ||
+      /* other conditions where we need custom builder */) {
+    auto JBOrErr = Config.MakeJITBuilder(Config);
+    if (!JBOrErr)
+      return JBOrErr.takeError();
+    JB = std::move(*JBOrErr);
   }
 
   auto Interp = std::unique_ptr<Interpreter>(new Interpreter(
@@ -590,16 +609,6 @@ Interpreter::Parse(llvm::StringRef Code) {
   return LastPTU;
 }
 
-static llvm::Expected<llvm::orc::JITTargetMachineBuilder>
-createJITTargetMachineBuilder(const std::string &TT) {
-  if (TT == llvm::sys::getProcessTriple())
-    // This fails immediately if the target backend is not registered
-    return llvm::orc::JITTargetMachineBuilder::detectHost();
-
-  // If the target backend is not registered, LLJITBuilder::create() will fail
-  return llvm::orc::JITTargetMachineBuilder(llvm::Triple(TT));
-}
-
 llvm::Expected<std::unique_ptr<llvm::orc::LLJITBuilder>>
 Interpreter::createLLJITBuilder(
     std::unique_ptr<llvm::orc::ExecutorProcessControl> EPC,
@@ -629,39 +638,16 @@ llvm::Error Interpreter::CreateExecutor(JITConfig Config) 
{
                                                "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) {
-    auto JTMB = createJITTargetMachineBuilder(TT);
-    if (!JTMB)
-      return JTMB.takeError();
-    if (Config.CM)
-      JTMB->setCodeModel(Config.CM);
-    auto JB = IncrementalExecutor::createDefaultJITBuilder(std::move(*JTMB));
-    if (!JB)
-      return JB.takeError();
-    JITBuilder = std::move(*JB);
+    // Use the factory function to create the builder
+    auto JBOrErr = Config.MakeJITBuilder(Config);
+    if (!JBOrErr)
+      return JBOrErr.takeError();
+    JITBuilder = std::move(*JBOrErr);
   }
 
   llvm::Error Err = llvm::Error::success();
 
-  // Fix: Declare Executor as the appropriate unique_ptr type
   std::unique_ptr<IncrementalExecutor> Executor;
 
 #ifdef __EMSCRIPTEN__
@@ -803,4 +789,27 @@ llvm::Error Interpreter::LoadDynamicLibrary(const char 
*name) {
 
   return llvm::Error::success();
 }
+
+llvm::Expected<std::unique_ptr<llvm::orc::LLJITBuilder>>
+Interpreter::JITConfig::makeDefaultJITBuilder(const JITConfig &Config) {
+  // Handle out-of-process JIT case
+  if (Config.IsOutOfProcess) {
+    if (!Config.OOPExecutor.empty() || !Config.OOPExecutorConnect.empty()) {
+      auto ResOrErr = Interpreter::outOfProcessJITBuilder(Config);
+      if (!ResOrErr)
+        return ResOrErr.takeError();
+      return std::move(ResOrErr->first);
+    }
+  }
+
+  // Handle in-process JIT case
+  // This would typically extract the target triple from somewhere accessible
+  // For now, we'll assume it's passed via some mechanism or use process triple
+  std::string TT = llvm::sys::getProcessTriple(); // This might need adjustment
+  auto JTMB = createJITTargetMachineBuilder(TT);
+  if (!JTMB)
+    return JTMB.takeError();
+
+  return IncrementalExecutor::createDefaultJITBuilder(std::move(*JTMB));
+}
 } // end namespace clang

>From 53b25f4839b5e354d3e1174bd29aec26dd36bcb3 Mon Sep 17 00:00:00 2001
From: kr-2003 <kumar.kr.abhi...@gmail.com>
Date: Fri, 19 Sep 2025 08:01:35 +0530
Subject: [PATCH 2/3] Refactoring code

---
 clang/include/clang/Interpreter/Interpreter.h |  4 ++--
 clang/lib/Interpreter/Interpreter.cpp         | 13 ++-----------
 2 files changed, 4 insertions(+), 13 deletions(-)

diff --git a/clang/include/clang/Interpreter/Interpreter.h 
b/clang/include/clang/Interpreter/Interpreter.h
index 7d734897e5584..ef56f319e00ef 100644
--- a/clang/include/clang/Interpreter/Interpreter.h
+++ b/clang/include/clang/Interpreter/Interpreter.h
@@ -1,5 +1,5 @@
-//===------ Interpreter.h - Incremental Compilation and Execution---*- C++
-//-*-===//
+//===--- Interpreter.h - Incremental Compilation and Execution---*- C++ 
-*-===//
+
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
diff --git a/clang/lib/Interpreter/Interpreter.cpp 
b/clang/lib/Interpreter/Interpreter.cpp
index a613fbf1b8370..c33a037408d61 100644
--- a/clang/lib/Interpreter/Interpreter.cpp
+++ b/clang/lib/Interpreter/Interpreter.cpp
@@ -353,14 +353,11 @@ const char *const Runtimes = R"(
 static llvm::Expected<llvm::orc::JITTargetMachineBuilder>
 createJITTargetMachineBuilder(const std::string &TT) {
   if (TT == llvm::sys::getProcessTriple())
-    // This fails immediately if the target backend is not registered
     return llvm::orc::JITTargetMachineBuilder::detectHost();
 
-  // If the target backend is not registered, LLJITBuilder::create() will fail
   return llvm::orc::JITTargetMachineBuilder(llvm::Triple(TT));
 }
 
-// 5. Update outOfProcessJITBuilder to work with the new system
 llvm::Expected<std::pair<std::unique_ptr<llvm::orc::LLJITBuilder>, uint32_t>>
 Interpreter::outOfProcessJITBuilder(JITConfig Config) {
   std::unique_ptr<llvm::orc::ExecutorProcessControl> EPC;
@@ -435,8 +432,6 @@ llvm::Expected<std::unique_ptr<Interpreter>>
 Interpreter::create(std::unique_ptr<CompilerInstance> CI, JITConfig Config) {
   llvm::Error Err = llvm::Error::success();
 
-  // Auto-discover ORC runtime path if not provided and out-of-process is
-  // enabled
   if (Config.IsOutOfProcess && !Config.OrcRuntimePath) {
     const TargetInfo &TI = CI->getTarget();
     const llvm::Triple &Triple = TI.getTriple();
@@ -463,8 +458,7 @@ Interpreter::create(std::unique_ptr<CompilerInstance> CI, 
JITConfig Config) {
   }
 
   std::unique_ptr<llvm::orc::LLJITBuilder> JB;
-  if (Config.IsOutOfProcess ||
-      /* other conditions where we need custom builder */) {
+  if (Config.IsOutOfProcess) {
     auto JBOrErr = Config.MakeJITBuilder(Config);
     if (!JBOrErr)
       return JBOrErr.takeError();
@@ -802,10 +796,7 @@ Interpreter::JITConfig::makeDefaultJITBuilder(const 
JITConfig &Config) {
     }
   }
 
-  // Handle in-process JIT case
-  // This would typically extract the target triple from somewhere accessible
-  // For now, we'll assume it's passed via some mechanism or use process triple
-  std::string TT = llvm::sys::getProcessTriple(); // This might need adjustment
+  std::string TT = llvm::sys::getProcessTriple();
   auto JTMB = createJITTargetMachineBuilder(TT);
   if (!JTMB)
     return JTMB.takeError();

>From 88fd4cfda4d187b049282ff5068d96f7fffd1cbe Mon Sep 17 00:00:00 2001
From: kr-2003 <kumar.kr.abhi...@gmail.com>
Date: Fri, 19 Sep 2025 19:11:14 +0530
Subject: [PATCH 3/3] Resolving unique function

---
 clang/include/clang/Interpreter/Interpreter.h | 5 +++--
 clang/lib/Interpreter/Interpreter.cpp         | 5 -----
 2 files changed, 3 insertions(+), 7 deletions(-)

diff --git a/clang/include/clang/Interpreter/Interpreter.h 
b/clang/include/clang/Interpreter/Interpreter.h
index ef56f319e00ef..e066e05c20406 100644
--- a/clang/include/clang/Interpreter/Interpreter.h
+++ b/clang/include/clang/Interpreter/Interpreter.h
@@ -23,6 +23,7 @@
 #include "llvm/ADT/FunctionExtras.h"
 #include "llvm/ExecutionEngine/JITSymbol.h"
 #include "llvm/ExecutionEngine/Orc/ExecutorProcessControl.h"
+#include "llvm/ExecutionEngine/Orc/LLJIT.h"
 #include "llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.h"
 #include "llvm/Support/Error.h"
 #include <cstdint>
@@ -143,8 +144,8 @@ class Interpreter {
     /// Factory function for creating LLJITBuilder instances.
     /// This allows clients to customize JIT builder creation while still
     /// providing sensible defaults.
-    llvm::unique_function<llvm::Expected<
-        std::unique_ptr<llvm::orc::LLJITBuilder>>(const JITConfig &)>
+    std::function<llvm::Expected<std::unique_ptr<llvm::orc::LLJITBuilder>>(
+        const JITConfig &)>
         MakeJITBuilder = makeDefaultJITBuilder;
 
     JITConfig()
diff --git a/clang/lib/Interpreter/Interpreter.cpp 
b/clang/lib/Interpreter/Interpreter.cpp
index c33a037408d61..5847d85154a80 100644
--- a/clang/lib/Interpreter/Interpreter.cpp
+++ b/clang/lib/Interpreter/Interpreter.cpp
@@ -278,12 +278,7 @@ Interpreter::Interpreter(std::unique_ptr<CompilerInstance> 
Instance,
 
   if (Act->getCodeGen()) {
     Act->CacheCodeGenModule();
-    // The initial PTU is filled by `-include` or by CUDA includes
-    // automatically.
     if (!CI->getPreprocessorOpts().Includes.empty()) {
-      // We can't really directly pass the CachedInCodeGenModule to the Jit
-      // because it will steal it, causing dangling references as explained in
-      // Interpreter::Execute
       auto M = llvm::CloneModule(*Act->getCachedCodeGenModule());
       ASTContext &C = CI->getASTContext();
       IncrParser->RegisterPTU(C.getTranslationUnitDecl(), std::move(M));

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to