Skip to content

Comments

JIT: Enable inlining of runtime async methods without awaits#124183

Merged
jakobbotsch merged 6 commits intodotnet:mainfrom
jakobbotsch:async-inlining
Feb 10, 2026
Merged

JIT: Enable inlining of runtime async methods without awaits#124183
jakobbotsch merged 6 commits intodotnet:mainfrom
jakobbotsch:async-inlining

Conversation

@jakobbotsch
Copy link
Member

While inlining runtime async methods in general is tricky, it is relatively simple to allow inlining async methods that do not have any awaits in them, and I suspect this is a large fraction of them.

While inlining runtime async methods in general is tricky, it is
relatively simple to allow inlining async methods that do not have any
awaits in them, and I suspect this is a large fraction of them.
Copilot AI review requested due to automatic review settings February 9, 2026 16:47
@github-actions github-actions bot added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Feb 9, 2026
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Enables inlining of “runtime async” methods in the JIT when the async method body has no awaits, by rejecting inline candidates that require async call setup while adjusting async-context save/restore and EH sizing behavior.

Changes:

  • Add a new fatal inline observation for detecting awaits during inlinee import.
  • Abort inlining when async call setup is encountered while importing an inlinee.
  • Adjust EH table sizing and async-context save/restore behavior to support the new inlining scenario.

Reviewed changes

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

File Description
src/coreclr/jit/inline.def Adds callee “await” observation; removes callsite continuation-handling observation.
src/coreclr/jit/importercalls.cpp Marks inlinees as non-inlineable when async call setup is detected; removes prior callsite continuation-handling inline ban.
src/coreclr/jit/fgbasic.cpp Accounts for an extra EH clause when async context save/restore is enabled.
src/coreclr/jit/async.cpp Tweaks async-context logic for inlining mode (resumed computation, arg injection, return merging).

@jakobbotsch jakobbotsch marked this pull request as ready for review February 10, 2026 15:52
Copilot AI review requested due to automatic review settings February 10, 2026 15:52
@jakobbotsch
Copy link
Member Author

cc @dotnet/jit-contrib PTAL @AndyAyersMS

One thing this doesn't handle is multi-level inlinees where we eventually end up with no awaits. Not sure if that generalization would be simple, however.

Copy link
Contributor

Copilot AI left a comment

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 4 out of 4 changed files in this pull request and generated 1 comment.

Copy link
Member

@AndyAyersMS AndyAyersMS left a comment

Choose a reason for hiding this comment

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

Didn't see anything other than what copilot saw.

Copilot AI review requested due to automatic review settings February 10, 2026 16:44
Copy link
Contributor

Copilot AI left a comment

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 4 out of 4 changed files in this pull request and generated no new comments.

@jakobbotsch jakobbotsch merged commit 0b91113 into dotnet:main Feb 10, 2026
124 of 132 checks passed
@jakobbotsch jakobbotsch deleted the async-inlining branch February 10, 2026 22:22
@drieseng
Copy link
Contributor

@jakobbotsch, why do you think a "large fraction" of async methods do not have an await? Such methods would result in a CS1998 warning: "This async method lacks 'await' operators and will run synchronously."

Do you want to optimise for "bad" code? If the cost of this optimization is negligible, then this doesn't matter of course.

@jakobbotsch
Copy link
Member Author

@jakobbotsch, why do you think a "large fraction" of async methods do not have an await? Such methods would result in a CS1998 warning: "This async method lacks 'await' operators and will run synchronously."

Do you want to optimise for "bad" code? If the cost of this optimization is negligible, then this doesn't matter of course.

I suspect that a large fraction of async functions that we would inline do not have await. Generally successful inlinees are smaller and more likely to be leaf methods than other methods. But yes, @stephentoub pointed CS1998 out too (although we are removing this warning) and it is very possible it means my intuition about inlinees does not carry over to async methods.

@drieseng
Copy link
Contributor

What is the rationale behind removing CS1998? Just curious.

@jakobbotsch
Copy link
Member Author

What is the rationale behind removing CS1998? Just curious.

You can see the related discussion in dotnet/roslyn#77001. From a runtime async perspective it is no longer more expensive to have these methods be async, and in fact will often be a deoptimization to not make them async since the alternatives like Task.FromResult can be more expensive than runtime async. Also see #115771.

@stephentoub
Copy link
Member

What is the rationale behind removing CS1998? Just curious.

You can see the related discussion in dotnet/roslyn#77001. From a runtime async perspective it is no longer more expensive to have these methods be async, and in fact will often be a deoptimization to not make them async since the alternatives like Task.FromResult can be more expensive than runtime async. Also see #115771.

From a language perspective, the cure was worse than the disease. Even before runtime async, folks would get the warning and then bend over backwards to try to avoid it, often making things words, when the right answer was just generally just to use async.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants