Skip to content

[mlir][ExecutionEngine] Add support for global constructors and destructors #78070

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 15, 2024

Conversation

fabianmcg
Copy link
Contributor

@fabianmcg fabianmcg commented Jan 13, 2024

This patch add support for executing global constructors and destructors in the ExecutionEngine.

@fabianmcg fabianmcg changed the title [mlir][ExecutionEngine] Add support for global constructors and destr… [mlir][ExecutionEngine] Add support for global constructors and destructors Jan 13, 2024
…uctors

This patch add support for executing global constructors and destructors in the
`ExecutionEngine`.
@fabianmcg fabianmcg marked this pull request as ready for review January 13, 2024 23:54
@llvmbot
Copy link
Member

llvmbot commented Jan 13, 2024

@llvm/pr-subscribers-mlir

@llvm/pr-subscribers-mlir-execution-engine

Author: Fabian Mora (fabianmcg)

Changes

This patch add support for executing global constructors and destructors in the ExecutionEngine.


Full diff: https://github.com/llvm/llvm-project/pull/78070.diff

2 Files Affected:

  • (modified) mlir/lib/ExecutionEngine/ExecutionEngine.cpp (+6)
  • (added) mlir/test/mlir-cpu-runner/global-constructors.mlir (+32)
diff --git a/mlir/lib/ExecutionEngine/ExecutionEngine.cpp b/mlir/lib/ExecutionEngine/ExecutionEngine.cpp
index 267ec236d3fd59..d4ad2da045e2c4 100644
--- a/mlir/lib/ExecutionEngine/ExecutionEngine.cpp
+++ b/mlir/lib/ExecutionEngine/ExecutionEngine.cpp
@@ -219,6 +219,9 @@ ExecutionEngine::ExecutionEngine(bool enableObjectDump,
 }
 
 ExecutionEngine::~ExecutionEngine() {
+  // Execute the global destructors from the module being processed.
+  if (jit)
+    llvm::consumeError(jit->deinitialize(jit->getMainJITDylib()));
   // Run all dynamic library destroy callbacks to prepare for the shutdown.
   for (LibraryDestroyFn destroy : destroyFns)
     destroy();
@@ -396,6 +399,9 @@ ExecutionEngine::create(Operation *m, const ExecutionEngineOptions &options,
   };
   engine->registerSymbols(runtimeSymbolMap);
 
+  // Execute the global constructors from the module being processed.
+  cantFail(engine->jit->initialize(engine->jit->getMainJITDylib()));
+
   return std::move(engine);
 }
 
diff --git a/mlir/test/mlir-cpu-runner/global-constructors.mlir b/mlir/test/mlir-cpu-runner/global-constructors.mlir
new file mode 100644
index 00000000000000..3ebcaeccc83e32
--- /dev/null
+++ b/mlir/test/mlir-cpu-runner/global-constructors.mlir
@@ -0,0 +1,32 @@
+// RUN: mlir-cpu-runner %s -e entry -entry-point-result=void  \
+// RUN: -shared-libs=%mlir_c_runner_utils | \
+// RUN: FileCheck %s
+
+// Test that the `ctor` executes before `entry` and that `dtor` executes last.
+module {
+  llvm.func @printNewline()
+  llvm.func @printI64(i64)
+  llvm.mlir.global_ctors {ctors = [@ctor], priorities = [0 : i32]}
+  llvm.mlir.global_dtors {dtors = [@dtor], priorities = [0 : i32]}
+  llvm.func @ctor() {
+    %0 = llvm.mlir.constant(1 : i64) : i64
+    llvm.call @printI64(%0) : (i64) -> ()
+    llvm.call @printNewline() : () -> ()
+    // CHECK: 1
+    llvm.return
+  }
+  llvm.func @entry() {
+    %0 = llvm.mlir.constant(2 : i64) : i64
+    llvm.call @printI64(%0) : (i64) -> ()
+    llvm.call @printNewline() : () -> ()
+    // CHECK: 2
+    llvm.return
+  }
+  llvm.func @dtor() {
+    %0 = llvm.mlir.constant(3 : i64) : i64
+    llvm.call @printI64(%0) : (i64) -> ()
+    llvm.call @printNewline() : () -> ()
+    // CHECK: 3
+    llvm.return
+  }
+}

Copy link
Contributor

@ingomueller-net ingomueller-net left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, but I don't feel competent enough to approve.

For completing my understanding: what is the mechanism that calls ctor and dtor? I believe that the initialize/deinitialize function calls that this patch adds are part of LLVM's Orc/LLJIT but I am missing the next link(s) until the ctor/dtor functions...

@fabianmcg
Copy link
Contributor Author

what is the mechanism that calls ctor and dtor? I believe that the initialize/deinitialize function calls that this patch adds are part of LLVM's Orc/LLJIT but I am missing the next link(s) until the ctor/dtor functions

The initialize function calls all the initializers in the JITDylib see LLJIT.cpp#L227 GenericLLVMIRPlatformSupport and LLJIT.cpp#L227 initialize. Now, in this case ctor is an initializer because it's marked as such:

llvm.mlir.global_ctors {ctors = [@ctor], priorities = [0 : i32]}

That operation translates to llvm.global_ctors, see LLVM Lang Ref for more information.

@fabianmcg fabianmcg merged commit 48e8cd8 into llvm:main Jan 15, 2024
@fabianmcg fabianmcg deleted the execution-engine branch January 15, 2024 02:53
@ingomueller-net
Copy link
Contributor

Oh, I overlooked those lines in the test case. Thanks for helping me see it!

c-rhodes added a commit that referenced this pull request Jan 15, 2024
…nd destructors" (#78164)

this is causing test failures on AArch64 linux, hitting the
following assert:

# | mlir-cpu-runner: /home/culrho01/llvm-project/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp:519: void llvm::RuntimeDyldELF::resolveAArch64Relocation(const SectionEntry &, uint64_t, uint64_t, uint32_t, int64_t): Assertion `isInt<33>(Result) && "overflow check failed for relocation"' failed.

Seeing the same in buildbot as well, e.g.

https://lab.llvm.org/buildbot/#/builders/179/builds/9094/steps/12/logs/FAIL__MLIR__sparse_codegen_dim_mlir

Reverts #78070
@c-rhodes
Copy link
Collaborator

Hi, I've reverted this (#78164) this since it's causing test failures on AArch64 linux, hitting the following assert:

# | mlir-cpu-runner: /home/culrho01/llvm-project/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp:519: void llvm::RuntimeDyldELF::resolveAArch64Relocation(const SectionEntry &, uint64_t, uint64_t, uint32_t, int64_t): Assertion `isInt<33>(Result) && "overflow check failed for relocation"' failed.
# | PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
# | Stack dump:
# | 0.  Program arguments: /home/culrho01/llvm-project/build/bin/mlir-cpu-runner -march=aarch64 -mattr=+sve,+sme -e entry -entry-point-result=void -shared-libs=/home/culrho01/llvm-project/build/lib/libmlir_runner_utils.so,/home/culrho01/llvm-project/build/lib/libmlir_c_runner_utils.so,/home/culrho01/llvm-project/build/lib/libmlir_arm_sme_abi_stubs.so

Seeing the same in buildbot as well, e.g.
https://lab.llvm.org/buildbot/#/builders/179/builds/9094/steps/12/logs/FAIL__MLIR__sparse_codegen_dim_mlir

This seems related to #71963 which there's an open PR #71968 for, I've tested that patch but it doesn't fix the issue.

@fabianmcg
Copy link
Contributor Author

Thank you for catching this @c-rhodes . I think I wasn't notified because the success rate of that bot has been 0 since 3 days ago.

@fabianmcg fabianmcg restored the execution-engine branch January 15, 2024 14:38
fabianmcg added a commit that referenced this pull request Jan 15, 2024
…d destructors #78070  (#78170)

This patch add support for executing global constructors and destructors
in the ExecutionEngine.
justinfargnoli pushed a commit to justinfargnoli/llvm-project that referenced this pull request Jan 28, 2024
…uctors (llvm#78070)

This patch add support for executing global constructors and destructors
in the `ExecutionEngine`.
justinfargnoli pushed a commit to justinfargnoli/llvm-project that referenced this pull request Jan 28, 2024
…nd destructors" (llvm#78164)

this is causing test failures on AArch64 linux, hitting the
following assert:

# | mlir-cpu-runner: /home/culrho01/llvm-project/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp:519: void llvm::RuntimeDyldELF::resolveAArch64Relocation(const SectionEntry &, uint64_t, uint64_t, uint32_t, int64_t): Assertion `isInt<33>(Result) && "overflow check failed for relocation"' failed.

Seeing the same in buildbot as well, e.g.

https://lab.llvm.org/buildbot/#/builders/179/builds/9094/steps/12/logs/FAIL__MLIR__sparse_codegen_dim_mlir

Reverts llvm#78070
justinfargnoli pushed a commit to justinfargnoli/llvm-project that referenced this pull request Jan 28, 2024
…d destructors llvm#78070  (llvm#78170)

This patch add support for executing global constructors and destructors
in the ExecutionEngine.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants