Repository: dotnet/runtime
File: src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs (C#)

Code before:
                        logger.Writer.WriteLine($"Info: Method `{MethodBeingCompiled}` was not compiled because it always throws an exception");
                    return;
                }

                if (FunctionHasNonReferenceableTypedILCatchClause(methodIL, _compilation.NodeFactory.CompilationModuleGroup))
                {
                    if (logger.IsVerbose)
                        logger.Writer.WriteLine($"Info: Method `{MethodBeingCompiled}` was not compiled because it has a non referenceable catch clause");
                    return;
                }

                if (MethodBeingCompiled.IsAsyncThunk())
                {
                    // The synthetic async thunks require references to methods/types that may not have existing methodRef entries in the version bubble.
                    // These references need to be added to the mutable module if they don't exist.
                    var requiredMutableModuleReferences = MethodBeingCompiled.IsAsyncVariant() ?
                        AsyncThunkILEmitter.GetRequiredReferencesForAsyncThunk(((AsyncMethodVariant)MethodBeingCompiled).Target)
                        : AsyncThunkILEmitter.GetRequiredReferencesForTaskReturningThunk(MethodBeingCompiled);
                    foreach (var entity in requiredMutableModuleReferences)
                    {
                        // If we have a reference to the method/type already, we're okay.
                        if (_compilation.NodeFactory.ManifestMetadataTable._mutableModule.TryGetExistingEntityHandle(entity) is null)
                        {
                            if (logger.IsVerbose)
                                logger.Writer.WriteLine($"Info: Method `{MethodBeingCompiled}` triggered recompilation.");
                            _compilation.PrepareForCompilationRetry(_methodCodeNode, null, requiredMutableModuleReferences);
                            codeGotPublished = true;
                            return;
                        }
                    }
                }

                if (MethodBeingCompiled.GetTypicalMethodDefinition() is EcmaMethod ecmaMethod)
                {
                    if ((methodIL.GetMethodILScopeDefinition() is IEcmaMethodIL && _compilation.SymbolNodeFactory.VerifyTypeAndFieldLayout && ecmaMethod.Module == ecmaMethod.Context.SystemModule) ||
                        (!_compilation.NodeFactory.CompilationModuleGroup.VersionsWithMethodBody(MethodBeingCompiled) &&
                            _compilation.NodeFactory.CompilationModuleGroup.CrossModuleInlineable(MethodBeingCompiled)))
                    {
                        ISymbolNode ilBodyNode = _compilation.SymbolNodeFactory.CheckILBodyFixupSignature((EcmaMethod)MethodBeingCompiled.GetTypicalMethodDefinition());
                        AddPrecodeFixup(ilBodyNode);
                    }

                    // Harvest the method being compiled for the purpose of populating the type resolver
                    var resolver = _compilation.NodeFactory.Resolver;
                    if (_compilation.CompilationModuleGroup.VersionsWithModule(ecmaMethod.Module))
                    {
                        resolver.AddModuleTokenForMethod(MethodBeingCompiled, new ModuleToken(ecmaMethod.Module, ecmaMethod.Handle));
                    }
                    else
                    {
                        // Cross module optimization scenario. If we aren't able to come up with a token for the method being compiled, then force it to be

Review comment (refactor):
Why do we need this retry logic? I would expect that we can encode the managed helpers as needed, potentially only after everything is compiled, we should not need to retry the compilation to encode them.

Code after:
                        logger.Writer.WriteLine($"Info: Method `{MethodBeingCompiled}` was not compiled because IL code could not be found for the method.");
                    return;
                }

                if (FunctionJustThrows(methodIL))
                {
                    if (logger.IsVerbose)
                        logger.Writer.WriteLine($"Info: Method `{MethodBeingCompiled}` was not compiled because it always throws an exception");
                    return;
                }

                if (FunctionHasNonReferenceableTypedILCatchClause(methodIL, _compilation.NodeFactory.CompilationModuleGroup))
                {
                    if (logger.IsVerbose)
                        logger.Writer.WriteLine($"Info: Method `{MethodBeingCompiled}` was not compiled because it has a non referenceable catch clause");
                    return;
                }

                if (MethodBeingCompiled.GetTypicalMethodDefinition() is EcmaMethod ecmaMethod)
                {
                    if ((methodIL.GetMethodILScopeDefinition() is IEcmaMethodIL && _compilation.SymbolNodeFactory.VerifyTypeAndFieldLayout && ecmaMethod.Module == ecmaMethod.Context.SystemModule) ||
                        (!_compilation.NodeFactory.CompilationModuleGroup.VersionsWithMethodBody(MethodBeingCompiled) &&
                            _compilation.NodeFactory.CompilationModuleGroup.CrossModuleInlineable(MethodBeingCompiled)))
                    {
                        ISymbolNode ilBodyNode = _compilation.SymbolNodeFactory.CheckILBodyFixupSignature((EcmaMethod)MethodBeingCompiled.GetTypicalMethodDefinition());
                        AddPrecodeFixup(ilBodyNode);
                    }

                    // Harvest the method being compiled for the purpose of populating the type resolver
                    var resolver = _compilation.NodeFactory.Resolver;
                    if (_compilation.CompilationModuleGroup.VersionsWithModule(ecmaMethod.Module))
                    {
                        resolver.AddModuleTokenForMethod(MethodBeingCompiled, new ModuleToken(ecmaMethod.Module, ecmaMethod.Handle));
                    }
                    else
                    {
                        // Cross module optimization scenario. If we aren't able to come up with a token for the method being compiled, then force it to be
                        // computed.
                        // NOTE: Technically, we could arrange to require only the set of tokens necessary to describe the type that owns this method
                        // as well as the parameters and return value to the method. The token for the actual method is not required.
                        EntityHandle? handle = _compilation.NodeFactory.ManifestMetadataTable._mutableModule.TryGetExistingEntityHandle(ecmaMethod);
                        if (handle.HasValue)
                        {
                            resolver.AddModuleTokenForMethod(MethodBeingCompiled, new ModuleToken(_compilation.NodeFactory.ManifestMetadataTable._mutableModule, handle.Value));
                        }
                        else
                        {
                            _ilBodiesNeeded = _ilBodiesNeeded ?? new List<EcmaMethod>();
                            _ilBodiesNeeded.Add(ecmaMethod);
                        }
                    }