Skip to content

Commit

Permalink
Only R2R public methods, methods that override public methods, and in…
Browse files Browse the repository at this point in the history
…ternal methods that aren't always inlined (dotnet#75793)
  • Loading branch information
jkoritzinsky authored Nov 16, 2022
1 parent 0f412b1 commit 55d3027
Show file tree
Hide file tree
Showing 33 changed files with 627 additions and 84 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,13 @@
<Compile Include="..\..\Common\Compiler\CompilerTypeSystemContext.cs" Link="Compiler\CompilerTypeSystemContext.cs" />
<Compile Include="..\..\Common\Compiler\CompilerTypeSystemContext.Validation.cs" Link="Compiler\CompilerTypeSystemContext.Validation.cs" />
<Compile Include="..\..\Common\Compiler\NativeAotNameMangler.cs" Link="Compiler\NativeAotNameMangler.cs" />
<Compile Include="..\..\Common\Compiler\Dataflow\DynamicallyAccessedMembersBinder.cs" Link="Compiler\Dataflow\DynamicallyAccessedMembersBinder.cs" />
<Compile Include="..\..\Common\Compiler\Dataflow\EcmaExtensions.cs" Link="Compiler\Dataflow\EcmaExtensions.cs" />
<Compile Include="..\..\Common\Compiler\Dataflow\GenericParameterProxy.cs" Link="Compiler\Dataflow\GenericParameterProxy.cs" />
<Compile Include="..\..\Common\Compiler\Dataflow\MethodProxy.cs" Link="Compiler\Dataflow\MethodProxy.cs" />
<Compile Include="..\..\Common\Compiler\Dataflow\ParameterProxy.cs" Link="Compiler\Dataflow\ParameterProxy.cs" />
<Compile Include="..\..\Common\Compiler\Dataflow\TypeProxy.cs" Link="Compiler\Dataflow\TypeProxy.cs" />
<Compile Include="..\..\Common\Compiler\Dataflow\TypeExtensions.cs" Link="Compiler\Dataflow\TypeExtensions.cs" />
<Compile Include="..\..\Common\Compiler\DependencyAnalysis\AssemblyStubNode.cs" Link="Compiler\DependencyAnalysis\AssemblyStubNode.cs" />
<Compile Include="..\..\Common\Compiler\DependencyAnalysis\CompilerComparer.cs" Link="Compiler\DependencyAnalysis\CompilerComparer.cs" />
<Compile Include="..\..\Common\Compiler\DependencyAnalysis\EmbeddedDataContainerNode.cs" Link="Compiler\DependencyAnalysis\EmbeddedDataContainerNode.cs" />
Expand Down Expand Up @@ -303,23 +310,28 @@
<Compile Include="..\..\Common\Compiler\DependencyAnalysis\Target_X86\X86Emitter.cs" Link="Compiler\DependencyAnalysis\Target_X86\X86Emitter.cs" />
<Compile Include="..\..\Common\Compiler\DependencyTrackingLevel.cs" Link="Compiler\DependencyTrackingLevel.cs" />
<Compile Include="..\..\Common\Compiler\DevirtualizationManager.cs" Link="Compiler\DevirtualizationManager.cs" />
<Compile Include="..\..\Common\Compiler\FeatureSettings.cs" Link="Compiler\FeatureSettings.cs" />
<Compile Include="..\..\Common\Compiler\HardwareIntrinsicHelpers.cs" Link="Compiler\HardwareIntrinsicHelpers.cs" />
<Compile Include="..\..\Common\Compiler\ICompilationRootProvider.cs" Link="Compiler\ICompilationRootProvider.cs" />
<Compile Include="..\..\Common\Compiler\InstructionSetSupport.cs" Link="Compiler\InstructionSetSupport.cs" />
<Compile Include="..\..\Common\Compiler\Int128FieldLayoutAlgorithm.cs" Link="Compiler\Int128FieldLayoutAlgorithm.cs" />
<Compile Include="..\..\Common\Compiler\InternalCompilerErrorException.cs" Link="Compiler\InternalCompilerErrorException.cs" />
<Compile Include="..\..\Common\Compiler\MethodExtensions.cs" Link="Compiler\MethodExtensions.cs" />
<Compile Include="..\..\Common\Compiler\NameMangler.cs" Link="Compiler\NameMangler.cs" />
<Compile Include="..\..\Common\Compiler\ProcessLinkerXmlBase.cs" Link="Compiler\ProcessLinkerXmlBase.cs" />
<Compile Include="..\..\Common\Compiler\PropertyPseudoDesc.cs" Link="Compiler\PropertyPseudoDesc.cs" />
<Compile Include="..\..\Common\Compiler\EventPseudoDesc.cs" Link="Compiler\EventPseudoDesc.cs" />
<Compile Include="..\..\Common\Compiler\PseudoDescExtensions.cs" Link="Compiler\PseudoDescExtensions.cs" />
<Compile Include="..\..\Common\Compiler\SingleMethodRootProvider.cs" Link="Compiler\SingleMethodRootProvider.cs" />
<Compile Include="..\..\Common\Compiler\TypeExtensions.cs" Link="Compiler\TypeExtensions.cs" />
<Compile Include="..\..\Common\Compiler\TypePreserve.cs" Link="Compiler\TypePreserve.cs" />
<Compile Include="..\..\Common\Compiler\VectorFieldLayoutAlgorithm.cs" Link="Compiler\VectorFieldLayoutAlgorithm.cs" />

<Compile Include="Compiler\AnalysisBasedInteropStubManager.cs" />
<Compile Include="Compiler\AnalysisBasedMetadataManager.cs" />
<Compile Include="Compiler\BlockedInternalsBlockingPolicy.cs" />
<Compile Include="Compiler\BodySubstitution.cs" />
<Compile Include="Compiler\BodySubstitutionParser.cs" />
<Compile Include="Compiler\PseudoDescExtensions.cs" />
<Compile Include="Compiler\CompilationBuilder.Aot.cs" />
<Compile Include="Compiler\CompilationModuleGroup.Aot.cs" />
<Compile Include="Compiler\CompilerTypeSystemContext.Aot.cs" />
Expand All @@ -341,13 +353,10 @@
<Compile Include="Compiler\Dataflow\CompilerGeneratedState.cs" />
<Compile Include="Compiler\Dataflow\DiagnosticContext.cs" />
<Compile Include="Compiler\Dataflow\DiagnosticUtilities.cs" />
<Compile Include="Compiler\Dataflow\DynamicallyAccessedMembersBinder.cs" />
<Compile Include="Compiler\Dataflow\EcmaExtensions.cs" />
<Compile Include="Compiler\Dataflow\FieldReferenceValue.cs" />
<Compile Include="Compiler\Dataflow\FieldValue.cs" />
<Compile Include="Compiler\Dataflow\FlowAnnotations.cs" />
<Compile Include="Compiler\Dataflow\GenericArgumentDataFlow.cs" />
<Compile Include="Compiler\Dataflow\GenericParameterProxy.cs" />
<Compile Include="Compiler\Dataflow\GenericParameterValue.cs" />
<Compile Include="Compiler\Dataflow\HandleCallAction.cs" />
<Compile Include="Compiler\Dataflow\HoistedLocalKey.cs" />
Expand All @@ -356,10 +365,8 @@
<Compile Include="Compiler\Dataflow\LocalVariableReferenceValue.cs" />
<Compile Include="Compiler\Dataflow\MethodBodyScanner.cs" />
<Compile Include="Compiler\Dataflow\MethodParameterValue.cs" />
<Compile Include="Compiler\Dataflow\MethodProxy.cs" />
<Compile Include="Compiler\Dataflow\MethodReturnValue.cs" />
<Compile Include="Compiler\Dataflow\Origin.cs" />
<Compile Include="Compiler\Dataflow\ParameterProxy.cs" />
<Compile Include="Compiler\Dataflow\ParameterReferenceValue.cs" />
<Compile Include="Compiler\Dataflow\ReferenceValue.cs" />
<Compile Include="Compiler\Dataflow\ReflectionMethodBodyScanner.cs" />
Expand All @@ -369,8 +376,6 @@
<Compile Include="Compiler\Dataflow\TrimAnalysisAssignmentPattern.cs" />
<Compile Include="Compiler\Dataflow\TrimAnalysisMethodCallPattern.cs" />
<Compile Include="Compiler\Dataflow\TrimAnalysisPatternStore.cs" />
<Compile Include="Compiler\Dataflow\TypeExtensions.cs" />
<Compile Include="Compiler\Dataflow\TypeProxy.cs" />
<Compile Include="Compiler\Dataflow\ValueNode.cs" />
<Compile Include="Compiler\DebugInformationProvider.cs" />
<Compile Include="Compiler\DependencyAnalysis\CustomAttributeMetadataNode.cs" />
Expand Down Expand Up @@ -409,9 +414,7 @@
<Compile Include="Compiler\EmptyInteropStubManager.cs" />
<Compile Include="Compiler\DependencyAnalysis\ImportedNodeProvider.cs" />
<Compile Include="Compiler\ExpectedIsaFeaturesRootProvider.cs" />
<Compile Include="Compiler\EventPseudoDesc.cs" />
<Compile Include="Compiler\ExternSymbolMappedField.cs" />
<Compile Include="Compiler\FeatureSettings.cs" />
<Compile Include="Compiler\FeatureSwitchManager.cs" />
<Compile Include="Compiler\GeneratingMetadataManager.cs" />
<Compile Include="Compiler\GenericRootProvider.cs" />
Expand Down Expand Up @@ -569,7 +572,6 @@
<Compile Include="Compiler\NodeMangler.cs" />
<Compile Include="Compiler\ObjectDumper.cs" />
<Compile Include="Compiler\ExportsFileWriter.cs" />
<Compile Include="Compiler\ProcessLinkerXmlBase.cs" />
<Compile Include="Compiler\ProcessXmlBase.cs" />
<Compile Include="Compiler\RootingHelpers.cs" />
<Compile Include="Compiler\RootingServiceProvider.cs" />
Expand All @@ -578,10 +580,8 @@
<Compile Include="Compiler\SingleMethodCompilationModuleGroup.cs" />
<Compile Include="Compiler\ILAssemblyGeneratingMethodDebugInfoProvider.cs" />
<Compile Include="Compiler\StackTraceEmissionPolicy.cs" />
<Compile Include="Compiler\PropertyPseudoDesc.cs" />
<Compile Include="Compiler\PreinitializationManager.cs" />
<Compile Include="Compiler\TypePreinit.cs" />
<Compile Include="Compiler\TypePreserve.cs" />
<Compile Include="Compiler\UsageBasedInteropStubManager.cs" />
<Compile Include="Compiler\UsageBasedMetadataManager.cs" />
<Compile Include="Compiler\UserDefinedTypeDescriptor.cs" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Diagnostics;
using System.Reflection;
using Internal.TypeSystem;
using Internal.TypeSystem.Ecma;

namespace ILCompiler
{
public enum EffectiveVisibility
{
Private,
Public,
Family,
Assembly,
FamilyAndAssembly,
FamilyOrAssembly,
}

public static class EffectiveVisibilityExtensions
{
private static EffectiveVisibility ToEffectiveVisibility(this TypeAttributes typeAttributes)
{
return (typeAttributes & TypeAttributes.VisibilityMask) switch
{
TypeAttributes.Public or TypeAttributes.NestedPublic => EffectiveVisibility.Public,
TypeAttributes.NotPublic => EffectiveVisibility.Assembly,
TypeAttributes.NestedPrivate => EffectiveVisibility.Private,
TypeAttributes.NestedAssembly => EffectiveVisibility.Assembly,
TypeAttributes.NestedFamily => EffectiveVisibility.Family,
TypeAttributes.NestedFamANDAssem => EffectiveVisibility.FamilyAndAssembly,
TypeAttributes.NestedFamORAssem => EffectiveVisibility.FamilyOrAssembly,
_ => throw new UnreachableException()
};
}
private static EffectiveVisibility ToEffectiveVisibility(this MethodAttributes typeAttributes)
{
return (typeAttributes & MethodAttributes.MemberAccessMask) switch
{
// PrivateScope == Compiler-Controlled in the ECMA spec. A member with this accessibility
// is only accessible through a MemberDef, not a MemberRef.
// As a result, it's only accessible within the current assembly, which is effectively the same rules as
// Family for our case.
MethodAttributes.PrivateScope => EffectiveVisibility.Assembly,
MethodAttributes.Public => EffectiveVisibility.Public,
MethodAttributes.Private => EffectiveVisibility.Private,
MethodAttributes.Assembly => EffectiveVisibility.Assembly,
MethodAttributes.Family => EffectiveVisibility.Family,
MethodAttributes.FamANDAssem => EffectiveVisibility.FamilyAndAssembly,
MethodAttributes.FamORAssem => EffectiveVisibility.FamilyOrAssembly,
_ => throw new UnreachableException()
};
}

private static EffectiveVisibility ConstrainToVisibility(this EffectiveVisibility visibility, EffectiveVisibility enclosingVisibility)
{
return (visibility, enclosingVisibility) switch
{
(_, _) when visibility == enclosingVisibility => visibility,
(_, EffectiveVisibility.Private) => EffectiveVisibility.Private,
(EffectiveVisibility.Private, _) => EffectiveVisibility.Private,
(EffectiveVisibility.Public, _) => enclosingVisibility,
(_, EffectiveVisibility.Public) => visibility,
(EffectiveVisibility.FamilyOrAssembly, _) => enclosingVisibility,
(_, EffectiveVisibility.FamilyOrAssembly) => visibility,
(EffectiveVisibility.Family, EffectiveVisibility.Assembly) => EffectiveVisibility.FamilyAndAssembly,
(EffectiveVisibility.Family, EffectiveVisibility.FamilyAndAssembly) => EffectiveVisibility.FamilyAndAssembly,
(EffectiveVisibility.Assembly, EffectiveVisibility.Family) => EffectiveVisibility.FamilyAndAssembly,
(EffectiveVisibility.Assembly, EffectiveVisibility.FamilyAndAssembly) => EffectiveVisibility.FamilyAndAssembly,
(EffectiveVisibility.FamilyAndAssembly, EffectiveVisibility.Family) => EffectiveVisibility.FamilyAndAssembly,
(EffectiveVisibility.FamilyAndAssembly, EffectiveVisibility.Assembly) => EffectiveVisibility.FamilyAndAssembly,
_ => throw new UnreachableException(),
};
}

public static bool IsExposedOutsideOfThisAssembly(this EffectiveVisibility visibility, bool anyInternalsVisibleTo)
{
return visibility is EffectiveVisibility.Public or EffectiveVisibility.Family
|| (anyInternalsVisibleTo && visibility is EffectiveVisibility.Assembly or EffectiveVisibility.FamilyOrAssembly);
}

public static EffectiveVisibility GetEffectiveVisibility(this EcmaMethod method)
{
EffectiveVisibility visibility = method.Attributes.ToEffectiveVisibility();

for (EcmaType type = (EcmaType)method.OwningType; type is not null; type = (EcmaType)type.ContainingType)
{
visibility = visibility.ConstrainToVisibility(type.Attributes.ToEffectiveVisibility());
}
return visibility;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,92 +6,39 @@
using Internal.TypeSystem.Ecma;
using Internal.TypeSystem;
using Internal.JitInterface;
using System.Reflection.Metadata;

namespace ILCompiler
{
/// <summary>
/// Provides compilation group for a library that compiles everything in the input IL module.
/// Roots all methods in the input IL module.
/// </summary>
public class ReadyToRunRootProvider : ICompilationRootProvider
public class ReadyToRunLibraryRootProvider : ICompilationRootProvider
{
private EcmaModule _module;
private IEnumerable<MethodDesc> _profileData;
private readonly bool _profileDrivenPartialNGen;

public ReadyToRunRootProvider(EcmaModule module, ProfileDataManager profileDataManager, bool profileDrivenPartialNGen)
public ReadyToRunLibraryRootProvider(EcmaModule module)
{
_module = module;
_profileData = profileDataManager.GetMethodsForModuleDesc(module);
_profileDrivenPartialNGen = profileDrivenPartialNGen;
}

public void AddCompilationRoots(IRootingServiceProvider rootProvider)
{
foreach (var method in _profileData)
foreach (MetadataType type in _module.GetAllTypes())
{
try
MetadataType typeWithMethods = type;
if (type.HasInstantiation)
{
// Validate that this method is fully instantiated
if (method.OwningType.IsGenericDefinition || method.OwningType.ContainsSignatureVariables())
{
continue;
}

if (method.IsGenericMethodDefinition)
{
continue;
}

bool containsSignatureVariables = false;
foreach (TypeDesc t in method.Instantiation)
{
if (t.IsGenericDefinition)
{
containsSignatureVariables = true;
break;
}

if (t.ContainsSignatureVariables())
{
containsSignatureVariables = true;
break;
}
}
if (containsSignatureVariables)
typeWithMethods = InstantiateIfPossible(type);
if (typeWithMethods == null)
continue;

if (!CorInfoImpl.ShouldSkipCompilation(method))
{
CheckCanGenerateMethod(method);
rootProvider.AddCompilationRoot(method, rootMinimalDependencies: true, reason: "Profile triggered method");
}
}
catch (TypeSystemException)
{
// Individual methods can fail to load types referenced in their signatures.
// Skip them in library mode since they're not going to be callable.
continue;
}
}

if (!_profileDrivenPartialNGen)
{
foreach (MetadataType type in _module.GetAllTypes())
{
MetadataType typeWithMethods = type;
if (type.HasInstantiation)
{
typeWithMethods = InstantiateIfPossible(type);
if (typeWithMethods == null)
continue;
}

RootMethods(typeWithMethods, "Library module method", rootProvider);
}
RootMethods(typeWithMethods, "Library module method", rootProvider);
}
}

private void RootMethods(TypeDesc type, string reason, IRootingServiceProvider rootProvider)
private void RootMethods(MetadataType type, string reason, IRootingServiceProvider rootProvider)
{
foreach (MethodDesc method in type.GetAllMethods())
{
Expand Down Expand Up @@ -192,7 +139,7 @@ private static Instantiation GetInstantiationThatMeetsConstraints(Instantiation
return new Instantiation(args);
}

private static InstantiatedType InstantiateIfPossible(MetadataType type)
public static InstantiatedType InstantiateIfPossible(MetadataType type)
{
Instantiation inst = GetInstantiationThatMeetsConstraints(type.Instantiation);
if (inst.IsNull)
Expand All @@ -203,7 +150,7 @@ private static InstantiatedType InstantiateIfPossible(MetadataType type)
return type.MakeInstantiatedType(inst);
}

private static MethodDesc InstantiateIfPossible(MethodDesc method)
public static MethodDesc InstantiateIfPossible(MethodDesc method)
{
Instantiation inst = GetInstantiationThatMeetsConstraints(method.Instantiation);
if (inst.IsNull)
Expand Down
Loading

0 comments on commit 55d3027

Please sign in to comment.