-
Notifications
You must be signed in to change notification settings - Fork 3.8k
[runtime] Default llvm to self-init+direct native calls #13312
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
999049c to
738fe65
Compare
738fe65 to
ebfb035
Compare
Locally this is passing the corlib tests while doing the direct call fixups for my synthetic benchmark. Exciting. |
7f550ff to
7fc43a3
Compare
mono/mini/mini-llvm.c
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need that?
Feel free to discard the review whenever the question is answered, this is not requested changes but merely a question for documentation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was seeing a lot of weird behavior in the corlib tests that suggested a few edge cases to consider. I think that enabling inlining for the majority of methods is a good idea, but that fitting that into this PR would make it hard to reason about.
In the past, we weren’t inlining any methods because we were obfuscating all of the call sites. This preserves that behavior.
Also not sure how letting LLVM do inlining impacts things like non-C++ EH. There are a number of correctness hurdles there.
Adding a comment to the source to that effect.
As for the reason to disable this on llvmonly, it's clear that this is currently working on llvmonly without it (because this is already the default on llvmonly). I didn't want to change any of the behavior in this PR besides the intended change. I'm pretty sure that things should build on bitcode without that conditional. It shouldn't result in any optimization losses, but I figured I'd wait until I took on inlining in general to look into that.
7fc43a3 to
90a2ca5
Compare
|
Seeing failures that do not reproduce: |
|
Ah, they repro with |
|
Oh, interesting. These are all tests that don't run on bitcode. |
|
c6390c5 to
121a556
Compare
|
Example: Note:
|
d790d8f to
3113cc8
Compare
|
Hmm, since I am using the managed wrapper, maybe I should drop the nmethods change |
|
Very nice to be calling functions not via pointers. |
mono/metadata/marshal.h
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
does this comment add value?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it seems obvious that the below field is used as a primary key, I can remove the comment. The data definition seemed pretty far away from the actual usage to me, hence the comment.
mono/mini/mini-llvm.c
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this comment seems to belong to LLVMSetInstructionCallConv (). move it there. the comment above belongs to set_call_preserveall_cc ()
mono/mini/mini-runtime.h
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the option name already contains a negation, so this is hard to read imho. could you rephrase it to if the flag is set, then [...]. if the flag isn't set then [...]? maybe use bullet points.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Github doesn't show this as out of date, but this one is
mono/mini/llvmonly-runtime.c
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how can this code be reached? shouldn't this method only be called if mono_llvm_only is set?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This method is going to be pretty hot code for all LLVM-using JIT modes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Every single method will do a self-init through this function. If that init fails, we will throw here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok. that was not obvious to me because of the filename (llvmonly-runtime.c) and function name (init_llvmonly_method ()), but it makes sense due to the nature of this change. we should change that, but can be done later in order to avoid noise in this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, these should be moved somewhere else later, they were only used by llvmonly previously.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I renamed these functions. Let me know if you'd like for me to move them.
Now the init code is behind llvm_plt_init. Setting --aot=llvm-plt will bring back the legacy llvm+plt behavior
We emitted all of the lazy checks and init around a specific static method, but still were initializing it when we initialized methods that access it. This made static cctors run before they were supposed to. The problem was that the call site here has method == NULL, because we don't compute it. That's expected, as we don't compute the method along this path. This initial "&&" looks like it was supposed to avoid calling the method on a null MonoMethod reference. This preserves that, while fixing the control flow issues.
b6d56fa to
e90639c
Compare
* [runtime] Default llvm to self-init Now the init code is behind llvm_plt_init. Setting --aot=llvm-plt will bring back the legacy llvm+plt behavior * [llvm] Mark managed methods no-inline by llvm * [runtime] Clean up self-disabling machinery * [llvm] Skip self-init on cctors * [runtime] Always make ctors call their cctors * [runtime] Improve mono_print_unwind_info, add cases * [runtime] Fix too-early eager calling of cctors We emitted all of the lazy checks and init around a specific static method, but still were initializing it when we initialized methods that access it. This made static cctors run before they were supposed to. The problem was that the call site here has method == NULL, because we don't compute it. That's expected, as we don't compute the method along this path. This initial "&&" looks like it was supposed to avoid calling the method on a null MonoMethod reference. This preserves that, while fixing the control flow issues. * [runtime] Associate init_method native code with MonoMethod * [runtime] Future-proof against aot init wrapper subtype mixups * [runtime] Fix goto in AOT-init change for c++ * [runtime] Move docs for llvm-disable-self-init into runtime * [runtime] Fix bitcode, remove unneeded wrapper around init icall * [llvm] Include global prefix in init name * [comment] Describe debugging usage of llvm self-init disable flag * [aot] Consolidate mangler string append lines * [llvm] Make self-init documentation changes * [llvm] Rename self-init funcs, mini_llvmonly_ to mini_llvm_ * [runtime] Enable inlining for methods without init
|
Perf differences for this are captured in new benchmark run this weekend: #13104 (comment) |
|
@alexanderkyte could you summarize the impact of this PR? it's not exactly obvious when looking at the raw benchmark results 🙂 |
In order to improve the generation of call sites on LLVM, this PR moves us away from using a PLT call and to doing direct calls of the methods. In order to make sure that our lazy init still works, we need to emit init checks into methods that need them.
This PR does that, and puts a disable option behind MONO_DEBUG.