-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
Mono AOT full program analyses and interprocedural optimizations #80942
Comments
Tagging subscribers to 'os-ios': @steveisok, @akoeplinger Issue DetailsDescriptionFor target platforms which do not support dynamic code generation (e.g., iOS), programs are compiled in the full AOT mode. Currently, Mono AOT compiler compiles such programs by compiling managed assemblies one by one. One of the biggest advantages of this approach is that it is not necessary to recompile the whole application if there is a change in a single assembly. On the other hand, the compiler does not have any knowledge about cross-assembly references and heavily relies on the passes performed by the ILLinker, the tool performing full program analysis in the AOT pipeline. This prevents the compiler to do a better job at removing the unreachable code and to perform better inter-procedural optimizations. This experiment checks if inter-procedural optimizations can be achieved when all assemblies are compiled together. Tasks
/cc: @SamMonoRT
|
I thought that in the end for the iOS case you mentioned it will be a set of static files (per assembly) which will be linked all together (presumably, with LTO?) into a single binary? Also, I assume that Mono does inline methods from external assemblies if they're small, doesn't it? |
@EgorBo good point! Currently, Mono AOT for iOS produces a set of static files (per assembly) that are then linked all together by a native linker into a single binary. It means that assemblies are passed into the AOT compiler separately. By passing them together into the AOT compiler (somewhat similar to dedup feature in #80419) we want to check if the ILLinker "pre-pass" will bring inter-procedural optimizations.
Not sure about that, maybe @vargaz or @ivanpovazan can confirm. Ideas or feedback on how it can be improved are more than welcome :) |
Well, I assume generally if you combine the whole thing in one piece of LLVM IR - LLVM will be able to perform cross-managed-assembly inlining by its own so it should be a good for perf anyway? 🙂 |
You might find this prototype we did to add IPA to crossgen 2 interesting (note it was never merged): https://github.com/erozenfeld/runtime/commits/Crossgen2WPO |
Good, we will figure it out.
Thanks for sharing it. I see changes in ILCompiler that might be aligned with #80941. |
With the assumption that during wasm's AOT compilation all the assemblies are passed to the compiler in the same time to produce a single output file I've started investigating how this works in order to do something similar for iOS. Here's the outcome: Steps:
After inspecting the binlog I've noticed that all assemblies are passed separately to the AOT compiler, which means that it's the same principle on how it's done for iOS. For example:
Question : Could it be there another flag which can be set in order to enable passing all assemblies in the same time? Proposal for next step: Try changing how mono_aot_assemblies() works. Currently, this function is calling aot_assembly() for every assembly and is also emitting the AOT image of it. Instead of this, we can emit only one AOT image for all the assemblies in mono_aot_assemblies() after all the assemblies have been compiled. We can split the AOT compilation in 3 phases:
One concern with this strategy would be how are duplicates handled before emitting the AOT image, will llvm-linkonce take care of those? |
This will require a large amount of changes. Both the aot compiler, and the aot runtime expects a one-to-one mapping between assemblies and aot images. |
@LeVladIonescu good progress!
I agree that it would require a large amount of changes and would be hard to test properly. What we want to achieve by having a single output file is a full program analyses by LLVM. It might not necessarily mean that the code should be emitted in single AOT image. It might be possible to collect methods from all assemblies and provide them during the LLVM compilation but to emit only a subset from a corresponding assembly. |
After offline sync we agreed to change the strategy. Now, the next step is to try to not allow the AOT compiler add methods into |
Obsolete, lower priority compared to other tasks. |
Description
For target platforms which do not support dynamic code generation (e.g., iOS), programs are compiled in the full AOT mode. Currently, Mono AOT compiler compiles such programs by compiling managed assemblies one by one. One of the biggest advantages of this approach is that it is not necessary to recompile the whole application if there is a change in a single assembly.
On the other hand, the compiler does not have any knowledge about cross-assembly references and heavily relies on the passes performed by the ILLinker, the tool performing full program analysis in the AOT pipeline. This prevents the compiler to do a better job at removing the unreachable code and to perform better inter-procedural optimizations.
This experiment checks if inter-procedural optimizations can be achieved when all assemblies are compiled together.
Tasks
/cc: @SamMonoRT
The text was updated successfully, but these errors were encountered: