This is an automated email from the ASF dual-hosted git repository.

tqchen pushed a commit to branch orcjit-windows-arm64-855
in repository https://gitbox.apache.org/repos/asf/tvm-ffi.git

commit da30264ef122097442458cc03273b53cb65ba373
Author: Tianqi Chen <[email protected]>
AuthorDate: Mon Oct 26 03:36:10 2026 +0000

    [DOCS] Describe the Windows ARM64 object loader
---
 addons/tvm_ffi_orcjit/README.md                 | 28 +++++++++++++------------
 addons/tvm_ffi_orcjit/src/ffi/orcjit_session.cc |  6 +++---
 2 files changed, 18 insertions(+), 16 deletions(-)

diff --git a/addons/tvm_ffi_orcjit/README.md b/addons/tvm_ffi_orcjit/README.md
index 300ca3e9..06c087dc 100644
--- a/addons/tvm_ffi_orcjit/README.md
+++ b/addons/tvm_ffi_orcjit/README.md
@@ -30,7 +30,7 @@ TVM-FFI exported functions.
 - **Symbol Isolation**: Separate `load_module` calls define independent symbol 
namespaces, so they can define the same symbol without conflicts
 - **Bounded-Range Memory**: A growable Linux slab pool keeps JIT code/data 
close enough for 32-bit PC-relative relocations and supports explicit 
drained-slab reclamation
 - **Init/Fini Support**: Handles static constructors/destructors across ELF 
(`.init_array`/`.ctors`), Mach-O (`__mod_init_func`), and COFF 
(`.CRT$XC*`/`.CRT$XT*`)
-- **Cross-Platform**: Linux (x86_64, aarch64), macOS (arm64), Windows (AMD64)
+- **Cross-Platform**: Linux (x86_64, aarch64), macOS (arm64), Windows (AMD64, 
ARM64)
 - **Multi-Compiler**: Tested with LLVM Clang, GCC, Apple Clang, MSVC, and 
clang-cl
 - **TVM-FFI Integration**: Seamlessly works with TVM-FFI's stable C ABI
 - **Python API**: Simple Pythonic interface for JIT compilation and execution
@@ -44,7 +44,7 @@ can be loaded and executed by the ORC JIT:
 | -------- | --------- | :-: | :-: |
 | Linux (x86_64, aarch64) | LLVM Clang, GCC | yes | yes |
 | macOS (arm64) | LLVM Clang, Apple Clang | yes | yes |
-| Windows (AMD64) | LLVM Clang, MSVC, clang-cl | yes | no |
+| Windows (AMD64, ARM64) | LLVM Clang, MSVC, clang-cl | yes | no |
 
 Windows is C-only across all compilers. C++ objects compiled with
 `TVM_FFI_DLL_EXPORT_TYPED_FUNC` use `try`/`catch` (via 
`TVM_FFI_SAFE_CALL_BEGIN/END`),
@@ -186,19 +186,21 @@ Compile: `clang -O2 -c -o example.o example.c`
 
 ## How It Works
 
-- **LLJIT**: Built on LLVM's ORC JIT v2 with `ObjectLinkingLayer` (JITLink) for
-  all platforms.
+- **LLJIT**: Built on LLVM's ORC JIT v2 with `ObjectLinkingLayer` (JITLink),
+  except Windows ARM64, which uses `RTDyldObjectLinkingLayer` because LLVM's
+  COFF JITLink backend does not support ARM64 relocations.
 - **ELF Lifecycle** (Linux): LLVM 23.1.1+ `ELFNixPlatform` runs ordered
   constructors and destructors through `LLJIT::initialize` / `deinitialize`.
-- **InitFiniPlugin** (macOS/Windows): A local `ObjectLinkingLayer::Plugin`
-  handles Mach-O `__mod_init_func`/`__mod_term_func` and COFF
-  `.CRT$XC*`/`.CRT$XT*` while those ORC platforms remain unsuitable.
-- **DLL Import Stubs** (Windows): Custom `DefinitionGenerator` that resolves 
host
-  process symbols from all loaded DLLs and creates `__imp_*` pointer stubs in
-  JIT memory, keeping all fixups within PCRel32 range.
+- **Init/Fini Adapters** (macOS/Windows): A local `ObjectLinkingLayer::Plugin`
+  handles Mach-O `__mod_init_func`/`__mod_term_func` and AMD64 COFF
+  `.CRT$XC*`/`.CRT$XT*` while those ORC platforms remain unsuitable. Windows
+  ARM64 collects relocated CRT pointers through RuntimeDyld callbacks.
+- **DLL Imports** (Windows): A custom `DefinitionGenerator` resolves host
+  process symbols from loaded DLLs. AMD64 uses JITLink pointer and jump stubs;
+  ARM64 uses RuntimeDyld's native import slots and branch stubs.
 - **SEH Stripping** (Windows): `ObjectTransformLayer` strips `.pdata`/`.xdata`
-  relocations from COFF objects before JITLink graph building, working around a
-  JITLink limitation with COMDAT section symbols.
+  relocations from COFF objects. C++ exception handling on Windows remains
+  unsupported on both architectures.
 
 Refer to [ORCJIT_PRIMER.md](./ORCJIT_PRIMER.md) for background on object files,
 linking, LLVM ORC JIT v2, and the addon's architecture.
@@ -227,7 +229,7 @@ tvm_ffi_orcjit/
 
 ## CI
 
-Runs on Linux (x86_64, aarch64), macOS (arm64), Windows (AMD64) via
+Runs on Linux (x86_64, aarch64), macOS (arm64), Windows (AMD64, ARM64) via
 `cibuildwheel`. Each platform builds test objects with multiple compilers
 and runs the full test suite. See the `orcjit` job in 
`.github/workflows/ci_test.yml`.
 
diff --git a/addons/tvm_ffi_orcjit/src/ffi/orcjit_session.cc 
b/addons/tvm_ffi_orcjit/src/ffi/orcjit_session.cc
index a3db0990..9bad4d68 100644
--- a/addons/tvm_ffi_orcjit/src/ffi/orcjit_session.cc
+++ b/addons/tvm_ffi_orcjit/src/ffi/orcjit_session.cc
@@ -421,9 +421,9 @@ ORCJITExecutionSessionObj::ORCJITExecutionSessionObj(const 
Optional<Variant<Stri
     // Override ProcessSymbols setup to NOT add the default
     // EPCDynamicLibrarySearchGenerator. That generator resolves symbols to
     // absolute host-process addresses, which causes PCRel32 overflow when
-    // JIT code calls into DLLs >2GB away. Our DLLImportDefinitionGenerator
-    // (added after construction) wraps every resolved address in a
-    // JIT-allocated PLT stub, keeping all fixups in range.
+    // AMD64 JIT code calls into DLLs >2GB away. Our generator below uses
+    // JITLink stubs on AMD64 and native RuntimeDyld stubs on ARM64, while
+    // resolving symbols from all loaded DLLs on both architectures.
     builder.setProcessSymbolsJITDylibSetup(
         [](llvm::orc::LLJIT& J) -> llvm::Expected<llvm::orc::JITDylibSP> {
           return &J.getExecutionSession().createBareJITDylib("<Process 
Symbols>");

Reply via email to