Skip to content
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] Enable dedup by default for iOS #81319

Merged
merged 28 commits into from
Feb 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
8576ca8
Enable dedup in HelloiOS app
kotlarmilos Jan 28, 2023
f4ffee1
Enable dedup in HelloiOS app
kotlarmilos Jan 28, 2023
eab1dbb
Disable direct call transformation when dedup for TARGET_APPLE_MOBILE
kotlarmilos Jan 31, 2023
5af578a
Enable dedup for all configurations in HelloiOS app
kotlarmilos Jan 31, 2023
d0f97f5
Fix build warnings
kotlarmilos Feb 1, 2023
84f8a2c
Enable dedup by default for ioslike targets
kotlarmilos Feb 1, 2023
0671c4c
Disable direct call transformation when dedup for TARGET_MACCAT
kotlarmilos Feb 2, 2023
2ef8ebd
Disable dedup for maccatalyst
kotlarmilos Feb 2, 2023
46ec344
Disable TARGET_MACCAT when dedup
kotlarmilos Feb 2, 2023
b9cdd48
Merge branch 'dotnet:main' into improvement/dedup-ios
kotlarmilos Feb 2, 2023
2816e7b
Allow dedup_skip_methods ifndef TARGET_APPLE_MOBILE
kotlarmilos Feb 2, 2023
84fe588
Merge branch 'improvement/dedup-ios' of github.com:kotlarmilos/runtim…
kotlarmilos Feb 2, 2023
2dadd01
Enable dedup for iOS only
kotlarmilos Feb 3, 2023
6552718
Merge branch 'dotnet:main' into improvement/dedup-ios
kotlarmilos Feb 13, 2023
fbc0a92
Disable dedup for tvOS
kotlarmilos Feb 13, 2023
26258b7
Move iOSLikeDedup to AppleApp.props
kotlarmilos Feb 13, 2023
cc5819c
Add comments and update directives
kotlarmilos Feb 15, 2023
af43e01
Merge branch 'dotnet:main' into improvement/dedup-ios
kotlarmilos Feb 15, 2023
8ebc6a3
Disable call transformation for MONO_PATCH_INFO_METHOD as some callee…
kotlarmilos Feb 16, 2023
5d4bf27
Merge branch 'improvement/dedup-ios' of github.com:kotlarmilos/runtim…
kotlarmilos Feb 16, 2023
49fc88d
Merge branch 'dotnet:main' into improvement/dedup-ios
kotlarmilos Feb 16, 2023
063cdc2
Test CI jobs
kotlarmilos Feb 16, 2023
9b313fe
Merge branch 'improvement/dedup-ios' of github.com:kotlarmilos/runtim…
kotlarmilos Feb 16, 2023
9d90655
Add comment inside of directive
kotlarmilos Feb 16, 2023
c2b0cc5
Fix _iOSLikeDedupAssembly path to match /publish directory
kotlarmilos Feb 17, 2023
ad32810
Fix _iOSLikeDedupAssembly path to match AppleAppDir
kotlarmilos Feb 17, 2023
35e9493
Avoid duplicate dedup assemblies during AOT compilation
kotlarmilos Feb 17, 2023
9ae4957
Include dedup assembly in AOT compilation
kotlarmilos Feb 17, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions src/mono/mono/mini/aot-compiler.c
Original file line number Diff line number Diff line change
Expand Up @@ -6589,6 +6589,8 @@ emit_and_reloc_code (MonoAotCompile *acfg, MonoMethod *method, guint8 *code, gui
direct_call_target = symbol;
patch_info->type = MONO_PATCH_INFO_NONE;
} else if ((m_class_get_image (patch_info->data.method->klass) == acfg->image) && !got_only && is_direct_callable (acfg, method, patch_info)) {
ivanpovazan marked this conversation as resolved.
Show resolved Hide resolved
#if 0
// FIXME: Currently not used. It fails as some callees require initialization.
MonoCompile *callee_cfg = (MonoCompile *)g_hash_table_lookup (acfg->method_to_cfg, cmethod);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that emit_and_reloc_code () is never used on wasm, so this shouldn't be neccessary.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, disabled for now. I've added a tracking issue for it as additional size savings might be achieved - #82224


// Don't compile inflated methods if we're doing dedup
Expand All @@ -6602,6 +6604,7 @@ emit_and_reloc_code (MonoAotCompile *acfg, MonoMethod *method, guint8 *code, gui
patch_info->type = MONO_PATCH_INFO_NONE;
acfg->stats.direct_calls ++;
}
#endif
}

acfg->stats.all_calls ++;
Expand Down Expand Up @@ -14891,9 +14894,12 @@ aot_assembly (MonoAssembly *ass, guint32 jit_opts, MonoAotOptions *aot_options)
TV_GETTIME (btv);

acfg->stats.jit_time = GINT64_TO_INT (TV_ELAPSED (atv, btv));

// Current implementation uses dedup_methods hash table for storing extra methods which are emitted in a dedup AOT image.
// Previously, cfg->skip flag in dedup_skip_methods is used for indicating if a method should be emitted in an AOT image.
// Method dedup_skip_methods is used only for wasm.
#ifdef TARGET_WASM
dedup_skip_methods (acfg);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this skipped ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dedup_skip_methods was used in previous implementation where cfg->skip flag was set for a dedup method. Current implementation uses hash table dedup_methods. With this function enabled, it might skip methods not added to dedup_methods and thus not emitting them in the dedup AOT image.


#endif
if (acfg->dedup_collect_only) {
/* We only collected methods from this assembly */
acfg_free (acfg);
Expand Down
7 changes: 6 additions & 1 deletion src/mono/mono/mini/aot-runtime.c
Original file line number Diff line number Diff line change
Expand Up @@ -4492,11 +4492,16 @@ inst_is_private (MonoGenericInst *inst)
gboolean
mono_aot_can_dedup (MonoMethod *method)
{
#ifdef TARGET_WASM
// Dedup enabled for wasm and iOS
#if defined(TARGET_WASM) || defined(TARGET_IOS)
/* Use a set of wrappers/instances which work and useful */
switch (method->wrapper_type) {
case MONO_WRAPPER_RUNTIME_INVOKE:
#ifdef TARGET_WASM
return TRUE;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this skipped ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Current implementation dedup methods based on a set of predefined rules. During the compilation, shared methods are emitted in corresponding AOT image while inflated instances are emitted in dedup AOT image. During the runtime, the shared method can't be retrieved as it was searched in the dedup AOT image.

Here is an example. During the compilation, the following runtime invoke wrappers are emitted in the dedup AOT image, while generic wrapper (wrapper runtime-invoke) void object:runtime_invoke_dynamic (intptr,intptr,intptr,intptr) is emitted in a corresponding AOT image.

(wrapper runtime-invoke) object <Module>:runtime_invoke_byte__this___int (object,intptr,intptr,intptr)
(wrapper runtime-invoke) object <Module>:runtime_invoke_void__this___int_byte (object,intptr,intptr,intptr)
(wrapper runtime-invoke) object <Module>:runtime_invoke_int__this___int (object,intptr,intptr,intptr)
(wrapper runtime-invoke) object <Module>:runtime_invoke_void__this___int_int (object,intptr,intptr,intptr)
(wrapper runtime-invoke) object <Module>:runtime_invoke_int__this___int_int (object,intptr,intptr,intptr)
(wrapper runtime-invoke) object <Module>:runtime_invoke_void__this___int_int_int (object,intptr,intptr,intptr)
(wrapper runtime-invoke) object <Module>:runtime_invoke_uint16__this___int (object,intptr,intptr,intptr)
(wrapper runtime-invoke) object <Module>:runtime_invoke_void__this___int_uint16 (object,intptr,intptr,intptr)
(wrapper runtime-invoke) object <Module>:runtime_invoke_bool__this___int (object,intptr,intptr,intptr)
(wrapper runtime-invoke) object <Module>:runtime_invoke_void__this___int_byte (object,intptr,intptr,intptr)
(wrapper runtime-invoke) object <Module>:runtime_invoke_sbyte__this___int (object,intptr,intptr,intptr)
(wrapper runtime-invoke) object <Module>:runtime_invoke_void__this___int_sbyte (object,intptr,intptr,intptr)
(wrapper runtime-invoke) object <Module>:runtime_invoke_char__this___int (object,intptr,intptr,intptr)
(wrapper runtime-invoke) object <Module>:runtime_invoke_void__this___int_uint16 (object,intptr,intptr,intptr)
(wrapper runtime-invoke) object <Module>:runtime_invoke_int16__this___int (object,intptr,intptr,intptr)
(wrapper runtime-invoke) object <Module>:runtime_invoke_void__this___int_int16 (object,intptr,intptr,intptr)
(wrapper runtime-invoke) object <Module>:runtime_invoke_uint__this___int (object,intptr,intptr,intptr)
(wrapper runtime-invoke) object <Module>:runtime_invoke_void__this___int_uint (object,intptr,intptr,intptr)
(wrapper runtime-invoke) object <Module>:runtime_invoke_long__this___int (object,intptr,intptr,intptr)
(wrapper runtime-invoke) object <Module>:runtime_invoke_void__this___int_long (object,intptr,intptr,intptr)
(wrapper runtime-invoke) object <Module>:runtime_invoke_ulong__this___int (object,intptr,intptr,intptr)
(wrapper runtime-invoke) object <Module>:runtime_invoke_void__this___int_long (object,intptr,intptr,intptr)
(wrapper runtime-invoke) object <Module>:runtime_invoke_intptr__this___int (object,intptr,intptr,intptr)
(wrapper runtime-invoke) object <Module>:runtime_invoke_void__this___int_intptr (object,intptr,intptr,intptr)
(wrapper runtime-invoke) object <Module>:runtime_invoke_uintptr__this___int (object,intptr,intptr,intptr)
(wrapper runtime-invoke) object <Module>:runtime_invoke_void__this___int_intptr (object,intptr,intptr,intptr)
(wrapper runtime-invoke) object <Module>:runtime_invoke_single__this___int (object,intptr,intptr,intptr)
(wrapper runtime-invoke) object <Module>:runtime_invoke_void__this___int_single (object,intptr,intptr,intptr)
(wrapper runtime-invoke) object <Module>:runtime_invoke_double__this___int (object,intptr,intptr,intptr)
(wrapper runtime-invoke) object <Module>:runtime_invoke_void__this___int_double (object,intptr,intptr,intptr)

During the runtime, (wrapper runtime-invoke) void object:runtime_invoke_dynamic (intptr,intptr,intptr,intptr) was searched in the dedup AOT image as it is RUNTIME_INVOKE_WRAPPER, but not emitted in the dedup AOT image.

#else
return FALSE;
#endif
break;
case MONO_WRAPPER_OTHER: {
WrapperInfo *info = mono_marshal_get_wrapper_info (method);
Expand Down
1 change: 1 addition & 0 deletions src/mono/msbuild/apple/build/AppleApp.props
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<!-- iOS/tvOS device + arm64 simulators need to AOT -->
<PropertyGroup Condition="'$(TargetOS)' == 'ios' or '$(TargetOS)' == 'tvos' or (('$(TargetOS)' == 'iossimulator' or '$(TargetOS)' == 'tvossimulator') And '$(TargetArchitecture)' == 'arm64')">
<RunAOTCompilation Condition="'$(RunAOTCompilation)' == ''">true</RunAOTCompilation>
<iOSLikeDedup Condition="'$(RunAOTCompilation)' == 'true' and '$(TargetOS)' == 'ios'">true</iOSLikeDedup>
</PropertyGroup>

<!-- iOS/tvOS arm64 simulators do not support JIT, so force interpreter fallback, devices should FullAOT -->
Expand Down
20 changes: 20 additions & 0 deletions src/mono/msbuild/apple/build/AppleApp.targets
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,25 @@

<MakeDir Directories="$(_MobileIntermediateOutputPath)" />

<PropertyGroup Condition="'$(iOSLikeDedup)' == 'true'">
<_iOSLikeDedupAssembly>$(AppleAppDir)\aot-instances.dll</_iOSLikeDedupAssembly>
</PropertyGroup>
<WriteLinesToFile Condition="'$(iOSLikeDedup)' == 'true'" File="$(_MobileIntermediateOutputPath)/aot-instances.cs" Overwrite="true" Lines="" WriteOnlyWhenDifferent="true" />
<Csc Condition="'$(iOSLikeDedup)' == 'true'"
Sources="$(_MobileIntermediateOutputPath)\aot-instances.cs"
OutputAssembly="$(_iOSLikeDedupAssembly)"
TargetType="library"
Deterministic="true"
References="@(ReferencePath)"
ToolExe="$(CscToolExe)"
ToolPath="$(CscToolPath)" />
<ItemGroup Condition="'$(iOSLikeDedup)' == 'true'">
<_AotInputAssemblies Include="$(_iOSLikeDedupAssembly)">
<AotArguments>@(MonoAOTCompilerDefaultAotArguments, ';')</AotArguments>
<ProcessArguments>@(MonoAOTCompilerDefaultProcessArguments, ';')</ProcessArguments>
</_AotInputAssemblies>
</ItemGroup>

<MonoAOTCompiler Condition="'$(RunAOTCompilation)' == 'true'"
CompilerBinaryPath="@(MonoAotCrossCompiler->WithMetadataValue('RuntimeIdentifier','$(TargetOS)-$(TargetArchitecture.ToLowerInvariant())'))"
OutputDir="$(_MobileIntermediateOutputPath)"
Expand All @@ -98,6 +117,7 @@
AotModulesTableLanguage="ObjC"
UseLLVM="$(MonoEnableLLVM)"
LLVMPath="$(MonoAotCrossDir)"
DedupAssembly="$(_iOSLikeDedupAssembly)"
IntermediateOutputPath="$(_MobileIntermediateOutputPath)">
<Output TaskParameter="CompiledAssemblies" ItemName="_AppleAssembliesInternal" />
</MonoAOTCompiler>
Expand Down
15 changes: 15 additions & 0 deletions src/mono/sample/iOS/Program.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
<TargetOS Condition="'$(TargetOS)' == ''">ios</TargetOS>
<TargetOS Condition="'$(TargetsiOSSimulator)' == 'true'">iossimulator</TargetOS>
<DeployAndRun Condition="'$(DeployAndRun)' == ''">true</DeployAndRun>
<iOSLikeDedup Condition="'$(TargetOS)' == 'ios'">true</iOSLikeDedup>
<RuntimeIdentifier>$(TargetOS)-$(TargetArchitecture)</RuntimeIdentifier>
<DefineConstants Condition="'$(ArchiveTests)' == 'true'">$(DefineConstants);CI_TEST</DefineConstants>
<AppName>HelloiOS</AppName>
Expand Down Expand Up @@ -42,6 +43,19 @@

<RemoveDir Directories="$(AppDir)" />

<PropertyGroup Condition="'$(iOSLikeDedup)' == 'true'">
<_iOSLikeDedupAssembly>$(MSBuildThisFileDirectory)$(PublishDir)\aot-instances.dll</_iOSLikeDedupAssembly>
</PropertyGroup>
<WriteLinesToFile Condition="'$(iOSLikeDedup)' == 'true'" File="$(MSBuildThisFileDirectory)$(PublishDir)/aot-instances.cs" Overwrite="true" Lines="" WriteOnlyWhenDifferent="true" />
<Csc Condition="'$(iOSLikeDedup)' == 'true'"
Sources="$(MSBuildThisFileDirectory)$(PublishDir)\aot-instances.cs"
OutputAssembly="$(_iOSLikeDedupAssembly)"
TargetType="library"
Deterministic="true"
References="@(ReferencePath)"
ToolExe="$(CscToolExe)"
ToolPath="$(CscToolPath)" />

<ItemGroup>
<BundleAssemblies Condition="'$(RunAOTCompilation)' != 'true'" Include="$(MSBuildThisFileDirectory)$(PublishDir)\*.dll" />
<AotInputAssemblies Condition="'$(RunAOTCompilation)' == 'true'" Include="$(MSBuildThisFileDirectory)$(PublishDir)\*.dll">
Expand All @@ -62,6 +76,7 @@
Mode="$(AOTMode)"
OutputType="AsmOnly"
Assemblies="@(AotInputAssemblies)"
DedupAssembly="$(_iOSLikeDedupAssembly)"
AotModulesTablePath="$(AppDir)\modules.m"
AotModulesTableLanguage="ObjC"
OutputDir="$(PublishDir)"
Expand Down