[Mlir-commits] [mlir] [MLIR][ExecutionEngine] don't dump decls (PR #164478)
Maksim Levental
llvmlistbot at llvm.org
Tue Oct 21 12:48:49 PDT 2025
https://github.com/makslevental updated https://github.com/llvm/llvm-project/pull/164478
>From 25832d3c03e300e3f715113ee43bb8e7e2599eec Mon Sep 17 00:00:00 2001
From: Maksim Levental <maksim.levental at gmail.com>
Date: Tue, 21 Oct 2025 12:17:13 -0700
Subject: [PATCH] [MLIR][ExecutionEngine] don't dump decls
Currently ExecutionEngine tries to dump all functions declared in the module, even thoughs which "external" (i.e., linked at runtime). E.g.
```mlir
module {
func.func @supported_arg_types(%arg0: i32, %arg1: f32) {
vector.print %arg0 : i32
vector.print %arg1 : f32
return
}
}
```
fails with
```
Could not compile printF32:
Symbols not found: [ __mlir_printF32 ]
Program aborted due to an unhandled Error:
Symbols not found: [ __mlir_printF32 ]
```
even though `mlir_printF32` can and is provided by our own `libmlir_c_runner_utils`, which is usually loaded by the engine but of course can also be linked/loaded at runtime by whatever thing links the object file produced from the above.
So just skip functions which have no bodies during dump (i.e., are decls without defns).
---
mlir/lib/ExecutionEngine/ExecutionEngine.cpp | 2 ++
mlir/test/python/CMakeLists.txt | 2 +-
mlir/test/python/execution_engine.py | 27 +++++++++++++++-----
3 files changed, 23 insertions(+), 8 deletions(-)
diff --git a/mlir/lib/ExecutionEngine/ExecutionEngine.cpp b/mlir/lib/ExecutionEngine/ExecutionEngine.cpp
index 52162a43aeae3..2255633c746b3 100644
--- a/mlir/lib/ExecutionEngine/ExecutionEngine.cpp
+++ b/mlir/lib/ExecutionEngine/ExecutionEngine.cpp
@@ -239,6 +239,8 @@ ExecutionEngine::create(Operation *m, const ExecutionEngineOptions &options,
// Remember all entry-points if object dumping is enabled.
if (options.enableObjectDump) {
for (auto funcOp : m->getRegion(0).getOps<LLVM::LLVMFuncOp>()) {
+ if (funcOp.getBlocks().empty())
+ continue;
StringRef funcName = funcOp.getSymName();
engine->functionNames.push_back(funcName.str());
}
diff --git a/mlir/test/python/CMakeLists.txt b/mlir/test/python/CMakeLists.txt
index e1e82ef367b1e..2c123811c2998 100644
--- a/mlir/test/python/CMakeLists.txt
+++ b/mlir/test/python/CMakeLists.txt
@@ -11,7 +11,7 @@ add_public_tablegen_target(MLIRPythonTestIncGen)
add_subdirectory(lib)
-set(MLIR_PYTHON_TEST_DEPENDS MLIRPythonModules)
+set(MLIR_PYTHON_TEST_DEPENDS MLIRPythonModules mlir-runner)
if(NOT MLIR_STANDALONE_BUILD)
list(APPEND MLIR_PYTHON_TEST_DEPENDS FileCheck count not)
endif()
diff --git a/mlir/test/python/execution_engine.py b/mlir/test/python/execution_engine.py
index d569fcef32bfd..146e213a9229e 100644
--- a/mlir/test/python/execution_engine.py
+++ b/mlir/test/python/execution_engine.py
@@ -1,6 +1,7 @@
# RUN: env MLIR_RUNNER_UTILS=%mlir_runner_utils MLIR_C_RUNNER_UTILS=%mlir_c_runner_utils %PYTHON %s 2>&1 | FileCheck %s
# REQUIRES: host-supports-jit
import gc, sys, os, tempfile
+from textwrap import dedent
from mlir.ir import *
from mlir.passmanager import *
from mlir.execution_engine import *
@@ -21,6 +22,7 @@
"MLIR_C_RUNNER_UTILS", "../../../../lib/libmlir_c_runner_utils.so"
)
+
# Log everything to stderr and flush so that we have a unified stream to match
# errors/info emitted by MLIR to stderr.
def log(*args):
@@ -337,6 +339,7 @@ def callback(a):
ctypes.pointer(ctypes.pointer(get_ranked_memref_descriptor(inp_arr))),
)
+
run(testUnrankedMemRefWithOffsetCallback)
@@ -785,15 +788,25 @@ def testDumpToObjectFile():
try:
with Context():
module = Module.parse(
- """
- module {
- func.func @main() attributes { llvm.emit_c_interface } {
- return
- }
- }"""
+ dedent(
+ """
+ func.func private @printF32(f32)
+ func.func @main(%arg0: f32) attributes { llvm.emit_c_interface } {
+ call @printF32(%arg0) : (f32) -> ()
+ return
+ }
+ """
+ )
)
- execution_engine = ExecutionEngine(lowerToLLVM(module), opt_level=3)
+ execution_engine = ExecutionEngine(
+ lowerToLLVM(module),
+ opt_level=3,
+ # Loading MLIR_C_RUNNER_UTILS is necessary even though we don't actually run the code (i.e., call printF32)
+ # because RTDyldObjectLinkingLayer::emit will try to resolve symbols before dumping
+ # (see the jitLinkForORC call at the bottom there).
+ shared_libs=[MLIR_C_RUNNER_UTILS],
+ )
# CHECK: Object file exists: True
print(f"Object file exists: {os.path.exists(object_path)}")
More information about the Mlir-commits
mailing list