-
Notifications
You must be signed in to change notification settings - Fork 5k
JIT: extend indirect virtual stub optimization to arrays #116771
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
base: main
Are you sure you want to change the base?
JIT: extend indirect virtual stub optimization to arrays #116771
Conversation
Add support for array interface methods invoked via indirect virtual stubs. Trim out a layer of temps in the importer. Remember the base method handle and use that for detecting the GetEnumerator pattern and for array interface method devirtualization. Mark the SZGenericArrayEnumerator ctor as aggressively inlined; when inlined we can often prove the enumerator (conditionally) doesn't escape. Part of dotnet#108913
Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch |
@EgorBot -intel -arm64 using System.Collections.Generic;
using System.Runtime.CompilerServices;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
[GenericTypeArguments(typeof(string))]
[MemoryDiagnoser]
public class A<T>
{
private IEnumerable<T> _ienumerable;
[GlobalSetup(Target = nameof(IEnumerable))]
public void SetupIEnumerable() => _ienumerable = new string[512] as IEnumerable<T>;
[Benchmark]
public T IEnumerable() => Get(_ienumerable);
[MethodImpl(MethodImplOptions.NoInlining)]
private T Get(IEnumerable<T> collection)
{
T result = default;
foreach (var item in collection)
result = item;
return result;
}
private IEnumerable<string> _ienumerable_str;
[GlobalSetup(Target = nameof(IEnumerable_str))]
public void SetupIEnumerable_str() => _ienumerable_str = new string[512];
[Benchmark]
public string IEnumerable_str() => Get_str(_ienumerable_str);
[MethodImpl(MethodImplOptions.NoInlining)]
private string Get_str(IEnumerable<string> collection)
{
string result = default;
foreach (var item in collection)
result = item;
return result;
}
} |
Two failures that I spotted in scanning: Unexpected NREs
A runtime assert
|
For the assert (here looking at the span Indexer test) we have this tree:
We try late devirt, and need the type of The devirt is to an instantiating stub, so we end up producing
and this context is the wrong type. So we do the wrong instantiation...(?) and blow up later trying to invoke Maybe in array interface cases if the object (array) type is inexact we need to just bail out on devirtualization... let me see how messy that ends up being. |
Add support for array interface methods invoked via indirect virtual stubs. Trim out a layer of temps in the importer. Remember the base method handle and use that for detecting the GetEnumerator pattern and for array interface method devirtualization. Mark the SZGenericArrayEnumerator ctor as aggressively inlined; when inlined we can often prove the enumerator (conditionally) doesn't escape.
Part of #108913