-
Notifications
You must be signed in to change notification settings - Fork 3.8k
[llvm] Fix LLVM JIT when used with multiple AppDomains. #18824
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
Conversation
We currently reuse LLVM's command line parsing system to configure and enable passes. When using the default code generator pass configuration, the `ImplicitNullChecks` and `X86CallFrameOptimization` passes can only be enabled or disabled via the command line argument parser: the `cl::opt`s controlling these (and many other) passes are private to their translation units, and `TargetPassConfig`/`X86PassConfig` read from these `cl::opt`s with no other means to override these values. Unfortunately, some LLVM command line options have restrictions on the number of times they may be set, and running the LLVM command line argument parser more than once can fail, because the 'number of occurrences' counter is stored in each global `cl::opt`. This causes several tests to fail--one such test is unhandled-exception-7.cs. This change: - removes the lazy LLVM JIT initialization logic and instead runs this initialization once during `mini_init`, - moves some stray JIT-only code from mini-llvm.c to llvm-jit.cpp, - wraps the declarations in domain-internals.h with a `MONO_BEGIN_DECLS`/`MONO_END_DECLS` pair, so that they avoid name mangling when included in C++ source, and - removes `exception_cb` and `emitted_cb`: neither were actually used by live code.
|
This will break the loaded llvm support, which is needed because a runtime with a statically linked llvm will take 100ms longer to start up even if llvm is not used. |
Agreed, but someone should fix that 100ms. |
Loaded LLVM should still work: I updated mini-llvm-loaded.c and ran mono with loaded LLVM locally against some of the tests in mono/tests. The extra startup cost of LLVM, in a loaded LLVM mono, will continue to be paid exactly when
An argument in favor of preserving lazy initialization (with the necessary flag/test/lock/fence to ensure that it really does only execute once) is that, if we ever support a tiered JIT, this would allow us to avoid paying the LLVM JIT initialization cost on program runs that never have any functions advance to the LLVM tier. If that's preferable, I could do that instead. |
|
@monojenkins build failed |
llvm-jit.h is included in both C++ and C code.
|
RE loaded LLVM; just to verify, in a quick and dirty way, that I didn't make things worse, I just ran |
|
I can't reproduce the slowdown either any more, 10ms is ok. If this is the case, we could remove the whole loaded llvm mess as well. |
|
@monojenkins build failed |
|
@monojenkins build Linux i386 |
Should fix mono#19115. This bug was introduced in mono#18824, which conditionally initalized an LLVM JIT-related TLS slot while preserving unconditonal stores to that same slot. The value stored in this TLS slot should only be used during JIT compilation, so set/reset it in `mono_llvm_compile_method` instead of during IR construction in `mono_llvm_emit_method`. No non-JIT code should depend on the existence or presence of this TLS variable, so remove `mono_llvm_jit_set_tls_cfg`.
Should fix mono/mono#19115. This bug was introduced in mono/mono#18824, which conditionally initalized an LLVM JIT-related TLS slot while preserving unconditonal stores to that same slot. The value stored in this TLS slot should only be used during JIT compilation, so set/reset it in `mono_llvm_compile_method` instead of during IR construction in `mono_llvm_emit_method`. No non-JIT code should depend on the existence or presence of this TLS variable, so remove `mono_llvm_jit_set_tls_cfg`.
Should fix #19115. This bug was introduced in #18824, which conditionally initalized an LLVM JIT-related TLS slot while preserving unconditonal stores to that same slot. The value stored in this TLS slot should only be used during JIT compilation, so set/reset it in `mono_llvm_compile_method` instead of during IR construction in `mono_llvm_emit_method`. No non-JIT code should depend on the existence or presence of this TLS variable, so remove `mono_llvm_jit_set_tls_cfg`.
Should fix mono/mono#19115. This bug was introduced in mono/mono#18824, which conditionally initalized an LLVM JIT-related TLS slot while preserving unconditonal stores to that same slot. The value stored in this TLS slot should only be used during JIT compilation, so set/reset it in `mono_llvm_compile_method` instead of during IR construction in `mono_llvm_emit_method`. No non-JIT code should depend on the existence or presence of this TLS variable, so remove `mono_llvm_jit_set_tls_cfg`. Co-authored-by: imhameed <[email protected]>
We currently reuse LLVM's command line parsing system to configure and
enable passes. When using the default code generator pass configuration,
the
ImplicitNullChecksandX86CallFrameOptimizationpasses can onlybe enabled or disabled via the command line argument parser: the
cl::opts controlling these (and many other) passes are private totheir translation units, and
TargetPassConfig/X86PassConfigreadfrom these
cl::opts with no other means to override these values.Unfortunately, some LLVM command line options have restrictions on the
number of times they may be set, and running the LLVM command line
argument parser more than once can fail, because the 'number of
occurrences' counter is stored in each global
cl::opt. This causesseveral tests to fail--one such test is unhandled-exception-7.cs.
This change:
removes the lazy LLVM JIT initialization logic and instead
runs this initialization once during
mini_init,moves some stray JIT-only code from mini-llvm.c to llvm-jit.cpp,
wraps the declarations in domain-internals.h with a
G_BEGIN_DECLS/G_END_DECLSpair, so that they avoid namemangling when included in C++ source, and
removes
exception_cbandemitted_cb: neither were actually usedby live code.