Add ILLink/ILCompiler support for feature checks#99267
Conversation
|
Tagging subscribers to this area: @agocke, @sbomer, @vitek-karas Issue DetailsThis will substitute static boolean properties with The "feature" of unreferenced code, represented by Additionally, a feature is considered disabled if the type has We don't want this kicking in when trimming in library mode, so this adds an ILLink option to disable the optimization. XML substitutions take precedence over this behavior. Includes a few tweaks and cleanup to the analyzer logic added in #94944. See #94625 for notes on the design.
|
|
I will update this to match the approved API shape once #99340 is merged. |
|
This is ready for review. |
src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/FeatureGuardAttributeDataFlow.cs
Show resolved
Hide resolved
src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/FeatureGuardAttributeDataFlow.cs
Outdated
Show resolved
Hide resolved
src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/FeatureGuardAttributeDataFlow.cs
Show resolved
Hide resolved
MichalStrehovsky
left a comment
There was a problem hiding this comment.
Native AOT side LGTM modulo the questions. Thanks!
|
|
||
| foreach (var featureGuardAttribute in property.GetDecodedCustomAttributes("System.Diagnostics.CodeAnalysis", "FeatureGuardAttribute")) | ||
| { | ||
| if (featureGuardAttribute.FixedArguments is not [CustomAttributeTypedArgument<TypeDesc> { Value: EcmaType featureType }]) |
There was a problem hiding this comment.
Just double checking that we don't allow feature types to be generic/arrays/pointers (non-definition type will never be EcmaType).
There was a problem hiding this comment.
The feature types aren't restricted in any way, but everything will be a no-op except for RequiresUnreferencedCodeAttribute, RequiresDynamicCodeAttribute, and RequiresAssemblyFilesAttribute. A third-party analyzer could theoretically add support for other types (including generics) so we don't block other types.
| if (_hashtable._switchValues.TryGetValue( | ||
| "System.Runtime.CompilerServices.RuntimeFeature.IsDynamicCodeSupported", | ||
| out bool isDynamicCodeSupported) | ||
| && !isDynamicCodeSupported) | ||
| return true; |
There was a problem hiding this comment.
Do we need this? IsDynamicCodeSupported/Compiled is hardcoded to false in native AOT corelib.
There was a problem hiding this comment.
I did this to match the behavior of some substitutions I noticed for System.Linq, that only kick in when the feature is explicitly passed on the command-line. It's kind of a moot point unless somebody tries to set DynamicCodeSupport to true in an AOT app.
There was a problem hiding this comment.
This will substitute static boolean properties with
falsewhen decorated with[FeatureGuard(typeof(SomeFeature))], whereSomeFeatureis known to be disabled.The "feature" of unreferenced code, represented by
RequiresUnreferencedCodeAttribute, is always considered disabled. For ILC,RequiresDynamicCodeAttributeandRequiresAssemblyFilesAttributeare also disabled. ILLink also respects the feature switch forIsDynamicCodeSupportedto disable theRequiresDynamicCodeAttributefeature.We don't want this kicking in when trimming in library mode, so this adds an ILLink option to disable the optimization.
Additionally, a property is substituted if it has
[FeatureSwitchDefinition("SomeFeatureName")]and"SomeFeatureName"is set in the command-line arguments.XML substitutions take precedence over this behavior.
Includes a few tweaks and cleanup to the analyzer logic added in #94944.
See #94625 for notes on the design.
See #96859 for the API proposal.