This is an experiment of using NativeAOT dependency analysis scanner (ILC_DA
mode) to work with Mono system module - System.Private.CoreLib
.
To goal of the experiment is to use NativeAOT to output all the methods that need to be AOT compiled with Mono,
into a file (in .mibc format). This file would be used as an input to the MonoAOT compiler when performing fullAOT compilation
to compile only what is required for the app to run (similar to the PGO optimization).
The experiment should consist of two stages:
- Optimize generics - The first stage of this experiment is to assist MonoAOT compilation with compilation of generics i.e. providing a list of generic instances needed during runtime.
- Optimize full program - The later stage would be to expand this feature for all types.
- Builds ILCompiler from this directory execute:
../../../../build.sh clr.tools+clr.jit -c release
NOTE: This will build ILCompiler for the host platform - eg: osx-arm64
- Builds Mono to target iOS platforms:
../../../../build.sh mono+libs -c release -os ios -arch arm64
-
To build and run the sample application with MonoAOT in fullAOT mode
make rundev MONO_CONFIG=Release DEPLOY_AND_RUN=false
-
To build and run the sample application with MonoAOT in fullAOT mode without GSHAREDVTs (current sample will fail at runtime if GSHAREDVTs aren't generated)
make rundev MONO_CONFIG=Release DEPLOY_AND_RUN=false NO_GSHVT=true
-
To build and run the sample application with MonoAOT in fullAOT mode without GSHAREDVTs with NativeAOT dependency analysis guided compilation
make rundev MONO_CONFIG=Release DEPLOY_AND_RUN=false NO_GSHVT=true ILC_DA=true
-
To measure size do not use any provisioning profile:
export DevTeamProvisioning=-
NOTE: It is also possible to pass LOG=true
when invoking main to enable runtime logging
- To filter collected methods by the DAGO adjust the
Program.csproj
file.- For example to include generic methods from all assemblies, the setup should look like:
<ReproResponseLines Include="#--scanmibcforassembly:$(AssemblyName)" /> <ReproResponseLines Include="--scanmibcforallgenerics" /> <ReproResponseLines Include="#--scanmibclogdump" />
- For more information about available switches run ilc with
--help
- For example to include generic methods from all assemblies, the setup should look like:
Mode | Size (bytes) | Size (MB) | Saving |
---|---|---|---|
GSHAREDVT | 27980822 | 27,98 | N/A |
noGSHAREDVT | 26412238 | 26,41 | -5,61% |
ILC-DA | 26734318 | 26,73 | -4,45% |
- Make sure we do not generate anything extra when compiling instances that came from the mibc profile (basically avoid Mono's dependency analysis on them)
- it is possible we still include something extra that is not required
- Try disabling
cfg->prefer_instances
in theILC_DA
mode as we should have everything necessary for the runtime in the mibc profile - Try more complex apps - MAUI template, and measure size/perf
- Try using generics with reflection to see if that is something
ILC_DA
would be able to detect as required - Figure out why creating mibc profile throws a warning about method count not being the same as in the assembly
- Go through all the ILC changes and iron them out (understand/document why they are needed and what is the effect)
- Test GSHAREDVT tests with
ILC_DA
- Experiment:
- AOT compile only methods from the DAGO profile
- Track down and measure the percentage of methods being AOT compiler (if MonoAOT compiled everything from the profile - or more)
- Run the sample - for which and how many cases/methods do JIT or interpreter get triggered
- Size of the final output compared to fullAOT output