[Mlir-commits] [mlir] [mlir][ExecutionEngine] Use JITLink for RISC-V (and AArch64) and fix … (PR #196023)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Wed May 6 02:51:31 PDT 2026


https://github.com/XYenChi updated https://github.com/llvm/llvm-project/pull/196023

>From 9d211de402c47c2481e31248c9d0de5520856b65 Mon Sep 17 00:00:00 2001
From: XYenChi <oriachiuan at gmail.com>
Date: Fri, 17 Apr 2026 18:47:31 +0800
Subject: [PATCH 1/3] [mlir][ExecutionEngine] Use JITLink for RISC-V (and
 AArch64) and fix JitRunner defaults

The MLIR ExecutionEngine currently always builds an
RTDyldObjectLinkingLayer. RuntimeDyld has limited/!no support for
RISC-V relocations, which causes mlir-cpu-runner and any JIT-based
MLIR client to fail on RISC-V hosts.

Switch the object linking layer selection to prefer JITLink
(ObjectLinkingLayer) on targets where it is the better-supported
backend (currently AArch64 and RISC-V), and keep
RTDyldObjectLinkingLayer for the remaining targets. This mirrors the
selection logic already used by LLJIT::createObjectLinkingLayer.

Behavioral notes:
  * AArch64 previously enabled SectionMemoryManager's reserveAlloc
    workaround under RTDyld; on the JITLink path this is unnecessary
    because JITLink performs its own allocation honoring the AArch64
    TEXT/GOT distance requirement.
  * GDB/perf JITEventListeners are only registered on the RTDyld
    path, since they are tied to RuntimeDyld. JITLink-based listener
    support can be wired up separately.
  * The COFF symbol-visibility workaround is now guarded so it only
    runs on the RTDyld path (it is an RTDyld-only API).

In addition, JitRunner now sets RelocModel=PIC_ and CodeModel=Medium
when the target triple is RISC-V, which matches the medany ABI
required by the JITLink RISC-V backend and avoids out-of-range
relocations at link time.

Includes:
  * Add llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h to
    ExecutionEngine.cpp.
  * Add llvm/Support/CodeGen.h to JitRunner.cpp for the
    Reloc/CodeModel enums.
---
 mlir/lib/ExecutionEngine/ExecutionEngine.cpp | 66 +++++++++++++++-----
 mlir/lib/ExecutionEngine/JitRunner.cpp       |  6 ++
 2 files changed, 55 insertions(+), 17 deletions(-)

diff --git a/mlir/lib/ExecutionEngine/ExecutionEngine.cpp b/mlir/lib/ExecutionEngine/ExecutionEngine.cpp
index 49a88e0000511..d099d27a92897 100644
--- a/mlir/lib/ExecutionEngine/ExecutionEngine.cpp
+++ b/mlir/lib/ExecutionEngine/ExecutionEngine.cpp
@@ -10,19 +10,21 @@
 // JIT engine.
 //
 //===----------------------------------------------------------------------===//
-#include "mlir/ExecutionEngine/ExecutionEngine.h"
 #include "mlir/Dialect/LLVMIR/LLVMDialect.h"
+#include "mlir/ExecutionEngine/ExecutionEngine.h"
 #include "mlir/IR/BuiltinOps.h"
 #include "mlir/Support/FileUtilities.h"
 #include "mlir/Target/LLVMIR/Export.h"
 
 #include "llvm/ExecutionEngine/JITEventListener.h"
+#include "llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h"
 #include "llvm/ExecutionEngine/ObjectCache.h"
 #include "llvm/ExecutionEngine/Orc/CompileUtils.h"
 #include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
 #include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
 #include "llvm/ExecutionEngine/Orc/IRTransformLayer.h"
 #include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"
+#include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
 #include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
 #include "llvm/IR/IRBuilder.h"
 #include "llvm/MC/TargetRegistry.h"
@@ -316,27 +318,57 @@ ExecutionEngine::create(Operation *m, const ExecutionEngineOptions &options,
                                            &IgnoredMemMgr) {
     // Needed to respect AArch64 ABI requirements on the distance between
     // TEXT and GOT sections.
-    bool reserveAlloc = llvmModule->getTargetTriple().isAArch64();
-    auto objectLayer = std::make_unique<RTDyldObjectLinkingLayer>(
-        session, [sectionMemoryMapper = options.sectionMemoryMapper,
-                  reserveAlloc](const MemoryBuffer &) {
-          return std::make_unique<SectionMemoryManager>(sectionMemoryMapper,
-                                                        reserveAlloc);
-        });
-
-    // Register JIT event listeners if they are enabled.
-    if (engine->gdbListener)
-      objectLayer->registerJITEventListener(*engine->gdbListener);
-    if (engine->perfListener)
-      objectLayer->registerJITEventListener(*engine->perfListener);
+
+    // Check if we should use ObjectLinkingLayer (JITLink)
+    // JITLink supports modern architectures like RISC-V, AArch64
+    // RuntimeDyld is older and provides better compatibility with legacy
+    // platforms
+
+    // Decide which layer to use
+    bool useJITLink = llvmModule->getTargetTriple().isAArch64() ||
+                      llvmModule->getTargetTriple().isRISCV();
+
+    std::unique_ptr<llvm::orc::ObjectLayer> objectLayer;
+
+    if (useJITLink) {
+      // JITLink path
+      objectLayer = std::make_unique<llvm::orc::ObjectLinkingLayer>(session);
+
+      LLVM_DEBUG(llvm::dbgs() << "Using ObjectLinkingLayer (JITLink)\n");
+
+    } else {
+      // RuntimeDyld path
+      auto rtDyldLayer = std::make_unique<llvm::orc::RTDyldObjectLinkingLayer>(
+          session,
+          [sectionMemoryMapper =
+               options.sectionMemoryMapper](const llvm::MemoryBuffer &)
+              -> std::unique_ptr<llvm::RuntimeDyld::MemoryManager> {
+            return std::make_unique<SectionMemoryManager>(sectionMemoryMapper);
+          });
+
+      // Only RTDyld supports listener
+      if (engine->gdbListener)
+        rtDyldLayer->registerJITEventListener(*engine->gdbListener);
+
+      if (engine->perfListener)
+        rtDyldLayer->registerJITEventListener(*engine->perfListener);
+
+      LLVM_DEBUG(llvm::dbgs() << "Using RTDyldObjectLinkingLayer\n");
+
+      // Upcast
+      objectLayer = std::move(rtDyldLayer);
+    }
 
     // COFF format binaries (Windows) need special handling to deal with
     // exported symbol visibility.
     // cf llvm/lib/ExecutionEngine/Orc/LLJIT.cpp LLJIT::createObjectLinkingLayer
     const llvm::Triple &targetTriple = llvmModule->getTargetTriple();
-    if (targetTriple.isOSBinFormatCOFF()) {
-      objectLayer->setOverrideObjectFlagsWithResponsibilityFlags(true);
-      objectLayer->setAutoClaimResponsibilityForObjectSymbols(true);
+    if (!useJITLink && targetTriple.isOSBinFormatCOFF()) {
+      if (auto *rtDyldLayer = dyn_cast<llvm::orc::RTDyldObjectLinkingLayer>(
+              objectLayer.get())) {
+        rtDyldLayer->setOverrideObjectFlagsWithResponsibilityFlags(true);
+        rtDyldLayer->setAutoClaimResponsibilityForObjectSymbols(true);
+      }
     }
 
     // Resolve symbols from shared libraries.
diff --git a/mlir/lib/ExecutionEngine/JitRunner.cpp b/mlir/lib/ExecutionEngine/JitRunner.cpp
index db0516533afcb..4b52669df9a6e 100644
--- a/mlir/lib/ExecutionEngine/JitRunner.cpp
+++ b/mlir/lib/ExecutionEngine/JitRunner.cpp
@@ -31,6 +31,7 @@
 #include "llvm/IR/IRBuilder.h"
 #include "llvm/IR/LLVMContext.h"
 #include "llvm/IR/LegacyPassNameParser.h"
+#include "llvm/Support/CodeGen.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/FileUtilities.h"
@@ -361,6 +362,11 @@ int mlir::JitRunnerMain(int argc, char **argv, const DialectRegistry &registry,
     tmBuilderOrError->getTargetTriple().setArchName(options.mArch);
   }
 
+  if (tmBuilderOrError->getTargetTriple().isRISCV()){
+    tmBuilderOrError->setRelocationModel(llvm::Reloc::PIC_);
+    tmBuilderOrError->setCodeModel(llvm::CodeModel::Medium);
+  }
+
   // Build TargetMachine
   auto tmOrError = tmBuilderOrError->createTargetMachine();
 

>From a3a66aacbfcd20d129df43acde09ddde173863fa Mon Sep 17 00:00:00 2001
From: XYenChi <oriachiuan at gmail.com>
Date: Wed, 6 May 2026 17:50:54 +0800
Subject: [PATCH 2/3] Update mlir/lib/ExecutionEngine/ExecutionEngine.cpp

Co-authored-by: Mehdi Amini <joker.eph at gmail.com>
---
 mlir/lib/ExecutionEngine/ExecutionEngine.cpp | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/mlir/lib/ExecutionEngine/ExecutionEngine.cpp b/mlir/lib/ExecutionEngine/ExecutionEngine.cpp
index d099d27a92897..d390f1a199bdb 100644
--- a/mlir/lib/ExecutionEngine/ExecutionEngine.cpp
+++ b/mlir/lib/ExecutionEngine/ExecutionEngine.cpp
@@ -332,10 +332,8 @@ ExecutionEngine::create(Operation *m, const ExecutionEngineOptions &options,
 
     if (useJITLink) {
       // JITLink path
+      LDBG() << "Using ObjectLinkingLayer (JITLink)";
       objectLayer = std::make_unique<llvm::orc::ObjectLinkingLayer>(session);
-
-      LLVM_DEBUG(llvm::dbgs() << "Using ObjectLinkingLayer (JITLink)\n");
-
     } else {
       // RuntimeDyld path
       auto rtDyldLayer = std::make_unique<llvm::orc::RTDyldObjectLinkingLayer>(

>From 382ae78352579142691c882c4df11cd65a9a4cff Mon Sep 17 00:00:00 2001
From: XYenChi <oriachiuan at gmail.com>
Date: Wed, 6 May 2026 17:51:21 +0800
Subject: [PATCH 3/3] Update mlir/lib/ExecutionEngine/ExecutionEngine.cpp

Co-authored-by: Mehdi Amini <joker.eph at gmail.com>
---
 mlir/lib/ExecutionEngine/ExecutionEngine.cpp | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/mlir/lib/ExecutionEngine/ExecutionEngine.cpp b/mlir/lib/ExecutionEngine/ExecutionEngine.cpp
index d390f1a199bdb..895d3ad0cc6f1 100644
--- a/mlir/lib/ExecutionEngine/ExecutionEngine.cpp
+++ b/mlir/lib/ExecutionEngine/ExecutionEngine.cpp
@@ -351,9 +351,7 @@ ExecutionEngine::create(Operation *m, const ExecutionEngineOptions &options,
       if (engine->perfListener)
         rtDyldLayer->registerJITEventListener(*engine->perfListener);
 
-      LLVM_DEBUG(llvm::dbgs() << "Using RTDyldObjectLinkingLayer\n");
-
-      // Upcast
+      LDBG() << "mlir::ExecutionEngine initialized with RTDyldObjectLinkingLayer engine";
       objectLayer = std::move(rtDyldLayer);
     }
 



More information about the Mlir-commits mailing list