-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Inliner improvements in .NET 9.0 #93069
Comments
Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch Issue DetailsOverviewInliner is one of the most impactful optimization in terms of ouput code performance, primary because it unlocks many other optimizations. Recently, we've started to more actively utilize various generic abstractions, such as Generic Math/GVMs, to unify existing code and eliminate code duplications. For instance, this allowed us to consolidate Formatting and Parsing logic for both UTF16 and UTF8 strings. Also, we've finally enabled Dynamic PGO by default which makes inliner even more aggressive for hot blocks. Consequently, we've begun encountering the inliner’s limitations more frequently. For .NET 9.0, we are planning the following improvements: Enable inlining for shared generics requiring a runtime lookup**The simplest example is: bool Test<T>() => Callee<T>();
bool Callee<T>() => typeof(T) == typeof(int); Currently,
JanK proposed an algorithm on how we can enable it with not too much efforts: #81432 (comment) and I've already done initial preparations by moving runtime lookup expansion to a late phase in #81635 Re-think Inliner's time budgetOnce inliner runs out of its Time Budget it starts to even ignore
A good examples of the problem are #90090 and #81565 Enable inlining for methods with EH(Exception Handling)Currently, we unconditionally give up on EH inside the callee even if in fact we'll remove EH blocks as dead code/redundant. Async/await state machine have some good candidates to benefit from this. Also, some C# expression produce try-finally blocks which JIT can eliminate depending on code ( void Foo()
{
Bar();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
void Bar()
{
try
{
Console.WriteLine("Hello");
}
catch
{
}
} Produces:
Proposed work
cc @dotnet/jit-contrib @AndyAyersMS @JulieLeeMSFT
|
Closed as finished for .NET 9.0 |
Overview
Inliner is one of the most impactful optimizations in terms of output code performance, primarily because it unlocks many other optimizations. Recently, we've started to more actively utilize various generic abstractions, such as Generic Math/GVMs, to unify existing code and eliminate code duplication. For instance, this allowed us to consolidate Formatting and Parsing logic for both UTF16 and UTF8 strings. Also, we've finally enabled Dynamic PGO by default which makes inliner even more aggressive for hot blocks. Consequently, we've begun encountering the inliner’s limitations more frequently. For .NET 9.0, we are planning the following improvements:
Enable inlining for shared generics requiring a runtime lookup
The simplest example is:
Currently,
Test<_Canon>
never inlinesCallee<>
due to a runtime lookup needed (in fact, it will be eliminated). Another example that it's not allowed to castSpan<T>
toReadOnlySpan<T>
efficiently, etc. It should fix issues like:JanK proposed an algorithm for how we can enable it without too much effort: #81432 (comment) and I've already done initial preparations by moving runtime lookup expansion to a late phase in #81635
Re-think Inliner's time budget
Once inliner runs out of its Time Budget it starts to even ignore
[AggressiveInlining]
attributes which breaks user's assumptions and produces slower code. The idea is to re-think how it's calculated/checked and, possibly, redesign inliner to start from hot blocks first. The beneficiaries are:Good examples of the problem are #90090 and #81565
Enable inlining for methods with EH (Exception Handling)
Currently, we unconditionally give up on EH inside the callee even if in fact we'll remove EH blocks as dead code/redundant. Async/await state machine have some good candidates to benefit from this. Also, some C# expression produce try-finally blocks which JIT can eliminate depending on code (
lock
,foreach
). Example:Produces:
Proposed work
cc @dotnet/jit-contrib @AndyAyersMS @JulieLeeMSFT
The text was updated successfully, but these errors were encountered: