Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
18 changes: 18 additions & 0 deletions docs/website/optimizations.md
Original file line number Diff line number Diff line change
Expand Up @@ -737,3 +737,21 @@ disabled until the correct linker annotations (e.g.

The default behavior can be overridden by passing
`--optimize=[+|-]cctor-beforefieldinit` to `mtouch` or `mmp`.

## Custom Attributes Removal

This optimization requires the linker to be enabled and is applied globally
on all assemblies inside the application.

This optimization removes a number of, rarely used, custom attributes from
assemblies. In turn this allows the linker to later remove the associated
code from the base class libraries (BCL). This help reduce both the
metadata and code size for your application.

This optimization is enabled, by default, on both Xamarin.iOS and
Xamarin.Mac. If some of the removed custom attributes are required for
your application you can disable this optimization, without totally
disabling the managed linker.

The default behavior can be overridden by passing
`--optimize=[+|-]custom-attributes-removal` to `mtouch` or `mmp`.
2 changes: 1 addition & 1 deletion tests/mmptest/src/MMPTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -646,7 +646,7 @@ public void MM0132 (string opt)
"<LinkMode>Full</LinkMode>",
};
var rv = TI.TestUnifiedExecutable (test, shouldFail: false);
rv.Messages.AssertWarning (132, $"Unknown optimization: '{opt}'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size, blockliteral-setupblock, register-protocols, inline-dynamic-registration-supported, static-block-to-delegate-lookup, trim-architectures, inline-is-arm64-calling-convention, cctor-beforefieldinit.");
rv.Messages.AssertWarning (132, $"Unknown optimization: '{opt}'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size, blockliteral-setupblock, register-protocols, inline-dynamic-registration-supported, static-block-to-delegate-lookup, trim-architectures, inline-is-arm64-calling-convention, cctor-beforefieldinit, custom-attributes-removal.");
rv.Messages.AssertErrorCount (0);
});
}
Expand Down
5 changes: 3 additions & 2 deletions tests/mtouch/MTouch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1752,7 +1752,7 @@ public void MT0132 ()
mtouch.Linker = MTouchLinker.LinkSdk;
mtouch.Optimize = new string [] { "foo" };
mtouch.AssertExecute (MTouchAction.BuildSim, "build");
mtouch.AssertWarning (132, "Unknown optimization: 'foo'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size, inline-runtime-arch, blockliteral-setupblock, register-protocols, inline-dynamic-registration-supported, static-block-to-delegate-lookup, remove-dynamic-registrar, remove-unsupported-il-for-bitcode, inline-is-arm64-calling-convention, seal-and-devirtualize, cctor-beforefieldinit.");
mtouch.AssertWarning (132, "Unknown optimization: 'foo'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size, inline-runtime-arch, blockliteral-setupblock, register-protocols, inline-dynamic-registration-supported, static-block-to-delegate-lookup, remove-dynamic-registrar, remove-unsupported-il-for-bitcode, inline-is-arm64-calling-convention, seal-and-devirtualize, cctor-beforefieldinit, custom-attributes-removal.");
}
}

Expand Down Expand Up @@ -3575,7 +3575,8 @@ public void MT2003 ()
mtouch.AssertWarning (2003, "Option '--optimize=inline-is-arm64-calling-convention' will be ignored since linking is disabled");
mtouch.AssertWarning (2003, "Option '--optimize=seal-and-devirtualize' will be ignored since linking is disabled");
mtouch.AssertWarning (2003, "Option '--optimize=cctor-beforefieldinit' will be ignored since linking is disabled");
mtouch.AssertWarningCount (13);
mtouch.AssertWarning (2003, "Option '--optimize=custom-attributes-removal' will be ignored since linking is disabled");
mtouch.AssertWarningCount (14);
}

using (var mtouch = new MTouchTool ()) {
Expand Down
11 changes: 11 additions & 0 deletions tools/common/Optimizations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ public class Optimizations
"", // dummy value to make indices match up between XM and XI
#endif
"cctor-beforefieldinit",
"custom-attributes-removal",
};

enum Opt
Expand All @@ -60,6 +61,7 @@ enum Opt
InlineIsARM64CallingConvention,
SealAndDevirtualize,
StaticConstructorBeforeFieldInit,
CustomAttributesRemoval,
}

bool? all;
Expand Down Expand Up @@ -138,6 +140,11 @@ public bool? StaticConstructorBeforeFieldInit {
set { values [(int) Opt.StaticConstructorBeforeFieldInit] = value; }
}

public bool? CustomAttributesRemoval {
get { return values [(int) Opt.CustomAttributesRemoval]; }
set { values [(int) Opt.CustomAttributesRemoval] = value; }
}

public Optimizations ()
{
values = new bool? [opt_names.Length];
Expand Down Expand Up @@ -294,6 +301,10 @@ public void Initialize (Application app)
if (!StaticConstructorBeforeFieldInit.HasValue)
StaticConstructorBeforeFieldInit = true;

// by default we remove rarely used custom attributes
if (!CustomAttributesRemoval.HasValue)
CustomAttributesRemoval = true;

if (Driver.Verbosity > 3)
Driver.Log (4, "Enabled optimizations: {0}", string.Join (", ", values.Select ((v, idx) => v == true ? opt_names [idx] : string.Empty).Where ((v) => !string.IsNullOrEmpty (v))));
}
Expand Down
35 changes: 22 additions & 13 deletions tools/mmp/Tuning.cs
Original file line number Diff line number Diff line change
Expand Up @@ -160,19 +160,7 @@ static Pipeline CreatePipeline (LinkerOptions options)
if (options.LinkMode != LinkMode.None) {
pipeline.AppendStep (new CoreTypeMapStep ());

var subdispatcher = new SubStepDispatcher {
new ApplyPreserveAttribute (),
new OptimizeGeneratedCodeSubStep (options),
new RemoveUserResourcesSubStep (),
new CoreRemoveAttributes (),
new CoreHttpMessageHandler (options),
new MarkNSObjects (),
};
// CoreRemoveSecurity can modify non-linked assemblies
// but the conditions for this cannot happen if only the platform assembly is linked
if (options.LinkMode != LinkMode.Platform)
subdispatcher.Add (new CoreRemoveSecurity ());
pipeline.AppendStep (subdispatcher);
pipeline.AppendStep (GetSubSteps (options));

pipeline.AppendStep (new MonoMacPreserveCode (options));
pipeline.AppendStep (new PreserveCrypto ());
Expand Down Expand Up @@ -200,6 +188,27 @@ static Pipeline CreatePipeline (LinkerOptions options)
return pipeline;
}

static SubStepDispatcher GetSubSteps (LinkerOptions options)
{
SubStepDispatcher sub = new SubStepDispatcher ();
sub.Add (new ApplyPreserveAttribute ());
sub.Add (new OptimizeGeneratedCodeSubStep (options));
sub.Add (new RemoveUserResourcesSubStep ());
// OptimizeGeneratedCodeSubStep and RemoveUserResourcesSubStep needs [GeneratedCode] so it must occurs before RemoveAttributes
if (options.Application.Optimizations.CustomAttributesRemoval == true)
sub.Add (new CoreRemoveAttributes ());

sub.Add (new CoreHttpMessageHandler (options));
sub.Add (new MarkNSObjects ());

// CoreRemoveSecurity can modify non-linked assemblies
// but the conditions for this cannot happen if only the platform assembly is linked
if (options.LinkMode != LinkMode.Platform)
sub.Add (new CoreRemoveSecurity ());

return sub;
}

static List<string> ListAssemblies (LinkContext context)
{
var list = new List<string> ();
Expand Down
4 changes: 2 additions & 2 deletions tools/mtouch/Tuning.cs
Original file line number Diff line number Diff line change
Expand Up @@ -150,8 +150,8 @@ static SubStepDispatcher GetSubSteps (LinkerOptions options)
sub.Add (new CoreRemoveSecurity ());
sub.Add (new OptimizeGeneratedCodeSubStep (options));
sub.Add (new RemoveUserResourcesSubStep (options));
// OptimizeGeneratedCodeSubStep and RemoveUserResourcesSubStep needs [GeneratedCode] so it must occurs before RemoveAttributes
sub.Add (new RemoveAttributes ());
if (options.Application.Optimizations.CustomAttributesRemoval == true)
sub.Add (new RemoveAttributes ());
// http://bugzilla.xamarin.com/show_bug.cgi?id=1408
if (options.LinkAway)
sub.Add (new RemoveCode (options));
Expand Down