Skip to content

Commit a79c62d

Browse files
lateralusXvargaz
andauthored
[Mono]: Reduce Mono AOT cross compiler x64 memory footprint. (#97096)
Building .net8 S.P.C using Mono AOT cross compiler in full AOT consumes a large amount of memory (up to 6 GB). This is mainly due to generated LLVM module not being optimized at all while kept in memory during full module generation. Mono x64 also lacks support for several intrinsics as well as Vector 256/512 that in turn leads to massive inlining of intrinsics functions generating a very large LLVM module, where majority of this code ends up as dead code due to IsSupported/IsHardwareAccelerated returning false. The follow commit adjusts several things that will bring down the memory usage, compiling .net8/.net9 Mono S.P.C on x64 Windows from 6 GB down to ~750 MB. * Use PSNE implementations on intrinsics not supported on Mono. * Add ILLinker substitutions for intrinsics not supported on Mono. Enables ILLinker to do dead code elimination, reduce code to AOT compile. * Prevent aggressive inlining for a couple of unsupported intrinsics types making sure we don't end up with excessive inlining, exploding code size. * Run a couple of LLVM optimization passes on each generated method doing early code simplification and dead code elimination during LLVM module generation. * Explicit SN_get_IsHardwareAccelerated/SN_get_IsSupported intrinsics implementation for all unsupported Mono x64 SIMD intrinsics. * Fixed numerous memory leaks in Mono AOT cross compiler code. * Fix a couple of sequence points free after use errors. * Fix an anonymous struct build warning triggering build error for LLVM enabled cross compiler on Windows. --------- Co-authored-by: Zoltan Varga <vargaz@gmail.com>
1 parent 3e9cce6 commit a79c62d

8 files changed

+182
-14
lines changed

src/libraries/System.Private.CoreLib/src/System.Private.CoreLib.Shared.projitems

+20-10
Original file line numberDiff line numberDiff line change
@@ -2576,17 +2576,26 @@
25762576
</ItemGroup>
25772577
<ItemGroup Condition="'$(SupportsX86Intrinsics)' == 'true'">
25782578
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Intrinsics\X86\Aes.cs" />
2579-
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Intrinsics\X86\Avx.cs" />
2580-
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Intrinsics\X86\Avx2.cs" />
2581-
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Intrinsics\X86\Avx512BW.cs" />
2582-
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Intrinsics\X86\Avx512CD.cs" />
2583-
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Intrinsics\X86\Avx512DQ.cs" />
2584-
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Intrinsics\X86\Avx512F.cs" />
2585-
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Intrinsics\X86\Avx512Vbmi.cs" />
2586-
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Intrinsics\X86\AvxVnni.cs" />
2579+
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Intrinsics\X86\Avx.cs" Condition="'$(FeatureMono)' != 'true'" />
2580+
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Intrinsics\X86\Avx.PlatformNotSupported.cs" Condition="'$(FeatureMono)' == 'true'" />
2581+
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Intrinsics\X86\Avx2.cs" Condition="'$(FeatureMono)' != 'true'" />
2582+
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Intrinsics\X86\Avx2.PlatformNotSupported.cs" Condition="'$(FeatureMono)' == 'true'" />
2583+
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Intrinsics\X86\Avx512BW.cs" Condition="'$(FeatureMono)' != 'true'" />
2584+
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Intrinsics\X86\Avx512BW.PlatformNotSupported.cs" Condition="'$(FeatureMono)' == 'true'" />
2585+
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Intrinsics\X86\Avx512CD.cs" Condition="'$(FeatureMono)' != 'true'" />
2586+
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Intrinsics\X86\Avx512CD.PlatformNotSupported.cs" Condition="'$(FeatureMono)' == 'true'" />
2587+
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Intrinsics\X86\Avx512DQ.cs" Condition="'$(FeatureMono)' != 'true'" />
2588+
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Intrinsics\X86\Avx512DQ.PlatformNotSupported.cs" Condition="'$(FeatureMono)' == 'true'" />
2589+
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Intrinsics\X86\Avx512F.cs" Condition="'$(FeatureMono)' != 'true'" />
2590+
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Intrinsics\X86\Avx512F.PlatformNotSupported.cs" Condition="'$(FeatureMono)' == 'true'" />
2591+
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Intrinsics\X86\Avx512Vbmi.cs" Condition="'$(FeatureMono)' != 'true'" />
2592+
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Intrinsics\X86\Avx512Vbmi.PlatformNotSupported.cs" Condition="'$(FeatureMono)' == 'true'" />
2593+
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Intrinsics\X86\AvxVnni.cs" Condition="'$(FeatureMono)' != 'true'" />
2594+
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Intrinsics\X86\AvxVnni.PlatformNotSupported.cs" Condition="'$(FeatureMono)' == 'true'" />
25872595
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Intrinsics\X86\Bmi1.cs" />
25882596
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Intrinsics\X86\Bmi2.cs" />
2589-
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Intrinsics\X86\Fma.cs" />
2597+
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Intrinsics\X86\Fma.cs" Condition="'$(FeatureMono)' != 'true'" />
2598+
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Intrinsics\X86\Fma.PlatformNotSupported.cs" Condition="'$(FeatureMono)' == 'true'" />
25902599
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Intrinsics\X86\Lzcnt.cs" />
25912600
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Intrinsics\X86\Pclmulqdq.cs" />
25922601
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Intrinsics\X86\Popcnt.cs" />
@@ -2597,7 +2606,8 @@
25972606
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Intrinsics\X86\Sse42.cs" />
25982607
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Intrinsics\X86\Ssse3.cs" />
25992608
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Intrinsics\X86\X86Base.cs" />
2600-
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Intrinsics\X86\X86Serialize.cs" />
2609+
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Intrinsics\X86\X86Serialize.cs" Condition="'$(FeatureMono)' != 'true'" />
2610+
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Intrinsics\X86\X86Serialize.PlatformNotSupported.cs" Condition="'$(FeatureMono)' == 'true'" />
26012611
</ItemGroup>
26022612
<ItemGroup Condition="'$(SupportsX86Intrinsics)' != 'true'">
26032613
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Intrinsics\X86\Aes.PlatformNotSupported.cs" />

src/mono/System.Private.CoreLib/System.Private.CoreLib.csproj

+2
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,8 @@
151151

152152
<ILLinkSubstitutionsXmls Include="$(ILLinkDirectory)ILLink.Substitutions.$(Platform).xml" Condition="Exists('$(ILLinkDirectory)ILLink.Substitutions.$(Platform).xml')" />
153153
<ILLinkSubstitutionsXmls Include="$(ILLinkDirectory)ILLink.Substitutions.iOS.xml" Condition="'$(TargetsiOS)' == 'true' or '$(TargetstvOS)' == 'true'" />
154+
<ILLinkSubstitutionsXmls Include="$(ILLinkDirectory)ILLink.Substitutions.Intrinsics.x86.xml" />
155+
<ILLinkSubstitutionsXmls Include="$(ILLinkDirectory)ILLink.Substitutions.Intrinsics.Vectors.xml" />
154156

155157
<ILLinkLinkAttributesXmls Include="$(ILLinkDirectory)ILLink.LinkAttributes.xml" />
156158
<ILLinkLinkAttributesXmls Include="$(ILLinkDirectory)ILLink.LinkAttributes.$(Platform).xml" Condition="Exists('$(ILLinkDirectory)ILLink.LinkAttributes.$(Platform).xml')" />
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<linker>
2+
<assembly fullname="System.Private.CoreLib">
3+
<type fullname="System.Runtime.Intrinsics.Vector256">
4+
<method signature="System.Boolean get_IsHardwareAccelerated()" body="stub" value="false" />
5+
</type>
6+
<type fullname="System.Runtime.Intrinsics.Vector512">
7+
<method signature="System.Boolean get_IsHardwareAccelerated()" body="stub" value="false" />
8+
</type>
9+
</assembly>
10+
</linker>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
<linker>
2+
<assembly fullname="System.Private.CoreLib">
3+
<type fullname="System.Runtime.Intrinsics.X86.Avx">
4+
<method signature="System.Boolean get_IsSupported()" body="stub" value="false" />
5+
</type>
6+
<type fullname="System.Runtime.Intrinsics.X86.Avx/X64">
7+
<method signature="System.Boolean get_IsSupported()" body="stub" value="false" />
8+
</type>
9+
<type fullname="System.Runtime.Intrinsics.X86.Avx2">
10+
<method signature="System.Boolean get_IsSupported()" body="stub" value="false" />
11+
</type>
12+
<type fullname="System.Runtime.Intrinsics.X86.Avx2/X64">
13+
<method signature="System.Boolean get_IsSupported()" body="stub" value="false" />
14+
</type>
15+
<type fullname="System.Runtime.Intrinsics.X86.Avx512BW">
16+
<method signature="System.Boolean get_IsSupported()" body="stub" value="false" />
17+
</type>
18+
<type fullname="System.Runtime.Intrinsics.X86.Avx512BW/VL">
19+
<method signature="System.Boolean get_IsSupported()" body="stub" value="false" />
20+
</type>
21+
<type fullname="System.Runtime.Intrinsics.X86.Avx512BW/X64">
22+
<method signature="System.Boolean get_IsSupported()" body="stub" value="false" />
23+
</type>
24+
<type fullname="System.Runtime.Intrinsics.X86.Avx512CD">
25+
<method signature="System.Boolean get_IsSupported()" body="stub" value="false" />
26+
</type>
27+
<type fullname="System.Runtime.Intrinsics.X86.Avx512CD/VL">
28+
<method signature="System.Boolean get_IsSupported()" body="stub" value="false" />
29+
</type>
30+
<type fullname="System.Runtime.Intrinsics.X86.Avx512CD/X64">
31+
<method signature="System.Boolean get_IsSupported()" body="stub" value="false" />
32+
</type>
33+
<type fullname="System.Runtime.Intrinsics.X86.Avx512DQ">
34+
<method signature="System.Boolean get_IsSupported()" body="stub" value="false" />
35+
</type>
36+
<type fullname="System.Runtime.Intrinsics.X86.Avx512DQ/VL">
37+
<method signature="System.Boolean get_IsSupported()" body="stub" value="false" />
38+
</type>
39+
<type fullname="System.Runtime.Intrinsics.X86.Avx512DQ/X64">
40+
<method signature="System.Boolean get_IsSupported()" body="stub" value="false" />
41+
</type>
42+
<type fullname="System.Runtime.Intrinsics.X86.Avx512F">
43+
<method signature="System.Boolean get_IsSupported()" body="stub" value="false" />
44+
</type>
45+
<type fullname="System.Runtime.Intrinsics.X86.Avx512F/VL">
46+
<method signature="System.Boolean get_IsSupported()" body="stub" value="false" />
47+
</type>
48+
<type fullname="System.Runtime.Intrinsics.X86.Avx512F/X64">
49+
<method signature="System.Boolean get_IsSupported()" body="stub" value="false" />
50+
</type>
51+
<type fullname="System.Runtime.Intrinsics.X86.Avx512Vbmi">
52+
<method signature="System.Boolean get_IsSupported()" body="stub" value="false" />
53+
</type>
54+
<type fullname="System.Runtime.Intrinsics.X86.Avx512Vbmi/VL">
55+
<method signature="System.Boolean get_IsSupported()" body="stub" value="false" />
56+
</type>
57+
<type fullname="System.Runtime.Intrinsics.X86.Avx512Vbmi/X64">
58+
<method signature="System.Boolean get_IsSupported()" body="stub" value="false" />
59+
</type>
60+
<type fullname="System.Runtime.Intrinsics.X86.AvxVnni">
61+
<method signature="System.Boolean get_IsSupported()" body="stub" value="false" />
62+
</type>
63+
<type fullname="System.Runtime.Intrinsics.X86.AvxVnni/X64">
64+
<method signature="System.Boolean get_IsSupported()" body="stub" value="false" />
65+
</type>
66+
<type fullname="System.Runtime.Intrinsics.X86.Fma">
67+
<method signature="System.Boolean get_IsSupported()" body="stub" value="false" />
68+
</type>
69+
<type fullname="System.Runtime.Intrinsics.X86.Fma/X64">
70+
<method signature="System.Boolean get_IsSupported()" body="stub" value="false" />
71+
</type>
72+
<type fullname="System.Runtime.Intrinsics.X86.X86Serialize">
73+
<method signature="System.Boolean get_IsSupported()" body="stub" value="false" />
74+
</type>
75+
<type fullname="System.Runtime.Intrinsics.X86.X86Serialize/X64">
76+
<method signature="System.Boolean get_IsSupported()" body="stub" value="false" />
77+
</type>
78+
</assembly>
79+
</linker>

src/mono/mono/mini/aot-compiler.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -14229,7 +14229,7 @@ static void
1422914229
acfg_free (MonoAotCompile *acfg)
1423014230
{
1423114231
#ifdef ENABLE_LLVM
14232-
if (acfg->aot_opts.llvm)
14232+
if (mono_use_llvm || acfg->aot_opts.llvm)
1423314233
mono_llvm_free_aot_module ();
1423414234
#endif
1423514235

src/mono/mono/mini/method-to-ir.c

+10-1
Original file line numberDiff line numberDiff line change
@@ -4746,6 +4746,15 @@ mini_inline_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *
47464746
return inline_method (cfg, cmethod, fsig, sp, ip, real_offset, inline_always, NULL);
47474747
}
47484748

4749+
static gboolean
4750+
aggressive_inline_method (MonoMethod *cmethod)
4751+
{
4752+
gboolean aggressive_inline = m_method_is_aggressive_inlining (cmethod);
4753+
if (aggressive_inline)
4754+
aggressive_inline = !mono_simd_unsupported_aggressive_inline_intrinsic_type (cmethod);
4755+
return aggressive_inline;
4756+
}
4757+
47494758
/*
47504759
* inline_method:
47514760
*
@@ -4871,7 +4880,7 @@ inline_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsig,
48714880
cfg->disable_inline = prev_disable_inline;
48724881
cfg->inline_depth --;
48734882

4874-
if ((costs >= 0 && costs < 60) || inline_always || (costs >= 0 && (cmethod->iflags & METHOD_IMPL_ATTRIBUTE_AGGRESSIVE_INLINING))) {
4883+
if ((costs >= 0 && costs < 60) || inline_always || (costs >= 0 && aggressive_inline_method (cmethod))) {
48754884
if (cfg->verbose_level > 2)
48764885
printf ("INLINE END %s -> %s\n", mono_method_full_name (cfg->method, TRUE), mono_method_full_name (cmethod, TRUE));
48774886

src/mono/mono/mini/mini.h

+1
Original file line numberDiff line numberDiff line change
@@ -2962,6 +2962,7 @@ MonoInst* mono_emit_common_intrinsics (MonoCompile *cfg, MonoMethod *cmethod,
29622962
MonoInst* mono_emit_simd_intrinsics (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsig, MonoInst **args);
29632963
MonoInst* mono_emit_simd_field_load (MonoCompile *cfg, MonoClassField *field, MonoInst *addr);
29642964
void mono_simd_intrinsics_init (void);
2965+
gboolean mono_simd_unsupported_aggressive_inline_intrinsic_type (MonoMethod *cmethod);
29652966

29662967
MonoMethod*
29672968
mini_method_to_shared (MonoMethod *method); // null if not shared

src/mono/mono/mini/simd-intrinsics.c

+59-2
Original file line numberDiff line numberDiff line change
@@ -1178,6 +1178,20 @@ create_class_instance (const char* name_space, const char *name, MonoType *param
11781178
return ivector_inst;
11791179
}
11801180

1181+
static gboolean
1182+
is_supported_vector_primitive_type (MonoType *type)
1183+
{
1184+
gboolean constrained_generic_param = (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR);
1185+
1186+
if (constrained_generic_param && type->data.generic_param->gshared_constraint && MONO_TYPE_IS_VECTOR_PRIMITIVE (type->data.generic_param->gshared_constraint))
1187+
return TRUE;
1188+
1189+
if (MONO_TYPE_IS_VECTOR_PRIMITIVE (type))
1190+
return TRUE;
1191+
1192+
return FALSE;
1193+
}
1194+
11811195
static guint16 sri_vector_methods [] = {
11821196
SN_Abs,
11831197
SN_Add,
@@ -1423,8 +1437,8 @@ emit_sri_vector (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsi
14231437
return NULL;
14241438

14251439
if (vector_size == 256 || vector_size == 512)
1426-
return NULL;
1427-
1440+
return NULL;
1441+
14281442
// FIXME: This limitation could be removed once everything here are supported by mini JIT on arm64
14291443
#ifdef TARGET_ARM64
14301444
if (!COMPILE_LLVM (cfg)) {
@@ -2477,6 +2491,12 @@ emit_sri_vector_t (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *f
24772491
g_free (name);
24782492
}
24792493

2494+
if (id == SN_get_IsSupported) {
2495+
MonoInst *ins;
2496+
EMIT_NEW_ICONST (cfg, ins, is_supported_vector_primitive_type (etype) ? 1 : 0);
2497+
return ins;
2498+
}
2499+
24802500
// Apart from filtering out non-primitive types this also filters out shared generic instance types like: T_BYTE which cannot be intrinsified
24812501
if (!MONO_TYPE_IS_VECTOR_PRIMITIVE (etype)) {
24822502
// Happens often in gshared code
@@ -3199,6 +3219,11 @@ emit_sys_numerics_vector_t (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSig
31993219
type = m_class_get_byval_arg (klass);
32003220
etype = mono_class_get_context (klass)->class_inst->type_argv [0];
32013221

3222+
if (id == SN_get_IsSupported) {
3223+
EMIT_NEW_ICONST (cfg, ins, is_supported_vector_primitive_type (etype) ? 1 : 0);
3224+
return ins;
3225+
}
3226+
32023227
if (!MONO_TYPE_IS_VECTOR_PRIMITIVE (etype))
32033228
return NULL;
32043229

@@ -6118,11 +6143,37 @@ mono_simd_decompose_intrinsic (MonoCompile *cfg, MonoBasicBlock *bb, MonoInst *i
61186143
decompose_vtype_opt_store_arg (cfg, bb, ins, &(ins->dreg));
61196144
}
61206145
}
6146+
6147+
gboolean
6148+
mono_simd_unsupported_aggressive_inline_intrinsic_type (MonoMethod *cmethod)
6149+
{
6150+
/*
6151+
* If a method has been marked with aggressive inlining, check if we support
6152+
* aggressive inlining of the intrinsics type, if not, ignore aggressive inlining
6153+
* since it could end up inlining a large amount of code that most likely will end
6154+
* up as dead code.
6155+
*/
6156+
if (!strcmp (m_class_get_name_space (cmethod->klass), "System.Runtime.Intrinsics")) {
6157+
if (!strncmp(m_class_get_name (cmethod->klass), "Vector", 6)) {
6158+
const char *vector_type = m_class_get_name (cmethod->klass) + 6;
6159+
if (!strcmp(vector_type, "256`1") || !strcmp(vector_type, "512`1"))
6160+
return TRUE;
6161+
}
6162+
}
6163+
return FALSE;
6164+
}
61216165
#else
61226166
void
61236167
mono_simd_decompose_intrinsic (MonoCompile *cfg, MonoBasicBlock *bb, MonoInst *ins)
61246168
{
61256169
}
6170+
6171+
gboolean
6172+
mono_simd_unsupported_aggressive_inline_intrinsic_type (MonoMethod* cmethod)
6173+
{
6174+
return FALSE;
6175+
}
6176+
61266177
#endif /*defined(TARGET_WIN32) && defined(TARGET_AMD64)*/
61276178

61286179
#endif /* DISABLE_JIT */
@@ -6157,6 +6208,12 @@ mono_simd_decompose_intrinsic (MonoCompile *cfg, MonoBasicBlock *bb, MonoInst *i
61576208
{
61586209
}
61596210

6211+
gboolean
6212+
mono_simd_unsupported_aggressive_inline_intrinsic_type (MonoMethod* cmethod)
6213+
{
6214+
return FALSE;
6215+
}
6216+
61606217
#endif /* MONO_ARCH_SIMD_INTRINSICS */
61616218

61626219
#if defined(TARGET_AMD64)

0 commit comments

Comments
 (0)