| File: Compiler\DependencyAnalysis\DataflowAnalyzedMethodNode.cs | Web Access |
| Project: src\runtime\src\coreclr\tools\aot\ILCompiler.Compiler\ILCompiler.Compiler.csproj (ILCompiler.Compiler) |
// 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.Collections.Generic; using System.Diagnostics; using Internal.TypeSystem; using Internal.IL; using ILCompiler.Dataflow; using ILCompiler.DependencyAnalysisFramework; namespace ILCompiler.DependencyAnalysis { /// <summary> /// Node that performs dataflow analysis to find dynamic dependencies (e.g. reflection use) of the given method. /// </summary> public class DataflowAnalyzedMethodNode : DependencyNodeCore<NodeFactory> { private readonly MethodIL _methodIL; private List<(MethodDesc OwningMethod, INodeWithRuntimeDeterminedDependencies Dependency)> _runtimeDependencies; public DataflowAnalyzedMethodNode(MethodIL methodIL) { Debug.Assert(methodIL.OwningMethod.IsTypicalMethodDefinition); Debug.Assert(!CompilerGeneratedState.IsNestedFunctionOrStateMachineMember(methodIL.OwningMethod)); _methodIL = methodIL; } public override IEnumerable<DependencyListEntry> GetStaticDependencies(NodeFactory factory) { var mdManager = (UsageBasedMetadataManager)factory.MetadataManager; try { return Dataflow.ReflectionMethodBodyScanner.ScanAndProcessReturnValue(factory, mdManager.FlowAnnotations, mdManager.Logger, _methodIL, out _runtimeDependencies); } catch (TypeSystemException) { // Something wrong with the input - missing references, etc. // The method body likely won't compile either, so we don't care. _runtimeDependencies = new List<(MethodDesc, INodeWithRuntimeDeterminedDependencies)>(); return Array.Empty<DependencyListEntry>(); } } public override IEnumerable<CombinedDependencyListEntry> SearchDynamicDependencies(List<DependencyNodeCore<NodeFactory>> markedNodes, int firstNode, NodeFactory factory) { // Look for any generic specialization of this method or its compiler-generated callees (local methods, lambdas). // If any are found, specialize the dataflow dependencies that originated from that method. for (int i = firstNode; i < markedNodes.Count; i++) { if (markedNodes[i] is not IMethodBodyNode methodBody) continue; MethodDesc method = methodBody.Method; MethodDesc typicalMethod = method.GetTypicalMethodDefinition(); // Instantiate runtime dependencies whose owning method matches this method body's typical definition foreach (var n in _runtimeDependencies) { if (n.OwningMethod != typicalMethod) continue; foreach (var d in n.Dependency.InstantiateDependencies(factory, method.OwningType.Instantiation, method.Instantiation, isConcreteInstantiation: !method.IsSharedByGenericInstantiations)) { yield return new CombinedDependencyListEntry(d.Node, null, d.Reason); } } } } protected override string GetName(NodeFactory factory) { return "Dataflow analysis for " + _methodIL.OwningMethod.ToString(); } public override bool InterestingForDynamicDependencyAnalysis => false; public override bool HasDynamicDependencies => _runtimeDependencies.Count > 0; public override bool HasConditionalStaticDependencies => false; public override bool StaticDependenciesAreComputed => true; public override IEnumerable<CombinedDependencyListEntry> GetConditionalStaticDependencies(NodeFactory context) => null; } }