Skip to content

Compile runtime async versions of synchronous task-returning methods - #128384

Merged
jakobbotsch merged 126 commits into
dotnet:mainfrom
jakobbotsch:runtime-async-versions
Jun 22, 2026
Merged

Compile runtime async versions of synchronous task-returning methods#128384
jakobbotsch merged 126 commits into
dotnet:mainfrom
jakobbotsch:runtime-async-versions

Conversation

@jakobbotsch

@jakobbotschjakobbotsch commented May 19, 2026

Copy link
Copy Markdown
Member

Instead of delegating from runtime async callable thunks to the original task returning methods this PR compiles a fully separate runtime async version. The JIT gets passed the IL of the synchronous task-returning method and is then responsible for adapting that to fit with the async variant. It does so by adding a (guaranteed) optimization to make tail calls in the synchronous task-returning methods into runtime async calls, and by otherwise introducing an async call to AsyncHelpers.TransparentAwaitWithResult around the task that would have otherwise been returned.

Fix#115771

CopilotAI review requested due to automatic review settings May 19, 2026 20:00
@github-actionsgithub-actionsBot added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label May 19, 2026

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR extends the JIT↔EE async infrastructure so the JIT can compile a dedicated “runtime async version” of synchronous Task/ValueTask-returning methods, including a tail-position optimization that turns eligible tail calls/returns into runtime-async awaits.

Changes:

  • Adds a new JIT↔EE interface API (getAwaitReturnCall) and plumbs it through SuperPMI and generated wrappers/shims.
  • Updates CoreCLR async thunk IL generation and AsyncHelpers to separate “suspend” helpers from typed TransparentAwait(...) helpers used by the JIT.
  • Updates the JIT importer to recognize “async-version tail await” patterns and to wrap async-version returns in an await via the new EE callback.

Reviewed changes

Copilot reviewed 33 out of 33 changed files in this pull request and generated 7 comments.

Show a summary per file
FileDescription
src/tests/async/reflection/reflection.csDisables several assertions related to reflection/stack behavior for await-on-task-returning paths.
src/coreclr/vm/prestub.cppAdjusts IL header retrieval logic for async variant methods.
src/coreclr/vm/method.hppChanges IL-header eligibility rules for async/thunk/return-dropping methods; exposes GetAsyncThunkResultTypeSig.
src/coreclr/vm/metasig.hAdds metasig entries for Task/ValueTask TransparentAwait helper signatures.
src/coreclr/vm/jitinterface.hAdds helper declarations related to runtime lookup computation for new await-return support.
src/coreclr/vm/jitinterface.cppImplements getAwaitReturnCall and runtime-lookup computation for generic await helpers; sets CORINFO_ASYNC_VERSION for applicable methods.
src/coreclr/vm/corelib.hAdds/updates CoreLibBinder entries for new suspend/await AsyncHelpers methods with proper signatures.
src/coreclr/vm/asyncthunks.cppSwitches thunk-emitted calls from TransparentAwait* to TransparentSuspendFor* helpers.
src/coreclr/tools/superpmi/superpmi/icorjitinfo.cppRecords/replays the new getAwaitReturnCall API for SuperPMI.
src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo_generated.cppForwards the new API in the simple shim.
src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo_generated.cppCounts/forwards the new API in the counter shim.
src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cppRecords the new API in the collector shim.
src/coreclr/tools/superpmi/superpmi-shared/spmirecordhelper.hMakes lookup restore helpers take const& and updates corresponding implementations.
src/coreclr/tools/superpmi/superpmi-shared/methodcontext.hAdds recording/replay plumbing for getAwaitReturnCall.
src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cppImplements record/dump/replay for getAwaitReturnCall.
src/coreclr/tools/superpmi/superpmi-shared/lwmlist.hRegisters the new lightweight-map packet for GetAwaitReturnCall.
src/coreclr/tools/superpmi/superpmi-shared/agnostic.hAdds agnostic structs for CORINFO_LOOKUP* and the await-return result payload.
src/coreclr/tools/Common/TypeSystem/IL/Stubs/AsyncThunks.csUpdates IL stub emitter to use TransparentSuspendFor* helper names.
src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txtAdds the new interface method to thunk generation input.
src/coreclr/tools/Common/JitInterface/CorInfoImpl.csAdds a stub managed implementation of getAwaitReturnCall for the managed JIT interface.
src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.csAdds unmanaged callback plumbing for getAwaitReturnCall.
src/coreclr/tools/aot/jitinterface/jitinterface_generated.hAdds the new callback and wrapper method to the AOT jitinterface wrapper.
src/coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/AsyncHelpers.CoreCLR.csRenames “suspend” helpers and adds typed TransparentAwait(...) overloads used by the JIT.
src/coreclr/jit/importercalls.cppAdds tail-await handling for async-version tail-await prefix and blocks inlining of async-version callees.
src/coreclr/jit/importer.cppAdds async-version tail-call recognition, wraps async-version returns in an await via getAwaitReturnCall, and introduces impWrapTopOfStackInAwait.
src/coreclr/jit/ICorJitInfo_wrapper_generated.hppAdds wrapper forwarding for getAwaitReturnCall.
src/coreclr/jit/ICorJitInfo_names_generated.hAdds name entry for getAwaitReturnCall.
src/coreclr/jit/fginline.cppMinor whitespace change near async flag handling for inlinee compilation.
src/coreclr/jit/compiler.hIntroduces PREFIX_IS_ASYNC_VERSION_TAIL_AWAIT, impWrapTopOfStackInAwait, and compIsAsyncVersion().
src/coreclr/jit/compiler.cppAdds verbose printing when compiling an async-version method.
src/coreclr/inc/jiteeversionguid.hUpdates JIT↔EE version GUID due to interface change.
src/coreclr/inc/icorjitinfoimpl_generated.hAdds getAwaitReturnCall override to the generated ICorJitInfo impl header.
src/coreclr/inc/corinfo.hAdds CORINFO_ASYNC_VERSION and the new ICorStaticInfo::getAwaitReturnCall method.

Comment threadsrc/tests/async/reflection/reflection.cs
Comment threadsrc/tests/async/reflection/reflection.cs
Comment threadsrc/tests/async/reflection/reflection.cs
Comment threadsrc/coreclr/vm/jitinterface.cpp Outdated
Comment threadsrc/coreclr/jit/importer.cpp Outdated
Comment threadsrc/coreclr/inc/corinfo.h
Comment threadsrc/coreclr/jit/importer.cpp
CopilotAI review requested due to automatic review settings May 20, 2026 10:46

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 32 out of 32 changed files in this pull request and generated 6 comments.

Comment threadsrc/coreclr/jit/importer.cpp Outdated
Comment threadsrc/coreclr/jit/importer.cpp
Comment threadsrc/tests/async/reflection/reflection.cs
Comment threadsrc/coreclr/inc/corinfo.h Outdated
Comment threadsrc/coreclr/vm/jitinterface.cpp Outdated
Comment threadsrc/coreclr/vm/asyncthunks.cpp Outdated
@jakobbotsch

Copy link
Copy Markdown
MemberAuthor

Another pattern we may want to recognize:

publicstaticValueTask<TSource?>MaxAsync<TSource>(
thisIAsyncEnumerable<TSource>source,
IComparer<TSource>?comparer=null,
CancellationTokencancellationToken=default)
{
ArgumentNullException.ThrowIfNull(source);
comparer??=Comparer<TSource>.Default;
// Special-case float/double/float?/double? to maintain compatibility
// with System.Linq.Enumerable implementations.
#pragma warning disable CA2012// Use ValueTasks correctly
if(typeof(TSource)==typeof(float)&&comparer==Comparer<TSource>.Default)
{
return(ValueTask<TSource?>)(object)MaxAsync((IAsyncEnumerable<float>)(object)source,cancellationToken);

CopilotAI review requested due to automatic review settings May 20, 2026 11:47

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 32 out of 32 changed files in this pull request and generated 3 comments.

Comment threadsrc/tests/async/reflection/reflection.cs
Comment threadsrc/coreclr/vm/asyncthunks.cpp Outdated
Comment threadsrc/coreclr/tools/Common/JitInterface/CorInfoImpl.cs
CopilotAI review requested due to automatic review settings May 20, 2026 14:18

@AndyAyersMSAndyAyersMS left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JIT parts LGTM

@VSadovVSadov left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

VM changes LGTM. Thanks!

@jakobbotsch

Copy link
Copy Markdown
MemberAuthor

/ba-g Timeout

CopilotAI review requested due to automatic review settings June 22, 2026 02:51

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 50 out of 50 changed files in this pull request and generated 1 comment.

Comment threadsrc/coreclr/tools/Common/Compiler/MethodExtensions.cs Outdated
@jakobbotsch

Copy link
Copy Markdown
MemberAuthor

Need a reapproval from someone after resolving the conflict and some copilot feedback.

@jakobbotsch

Copy link
Copy Markdown
MemberAuthor

/ba-g Failures are MIBC merge failures being fixed by #129706

@jakobbotsch
jakobbotsch merged commit b426fdf into dotnet:mainJun 22, 2026
122 of 130 checks passed
@jakobbotsch
jakobbotsch deleted the runtime-async-versions branch June 22, 2026 21:47
@dotnet-milestone-botdotnet-milestone-botBot removed this from the 11.0.0 milestone Jun 23, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMIruntime-async

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[runtime-async] Optimize synchronous Task-returning wrappers used in async context

12 participants

@jakobbotsch@tommcdon@VSadov@jkotas@MichalStrehovsky@BrzVlad@AndyAyersMS@AaronRobinsonMSFT@jtschuster@am11@JulieLeeMSFT