Skip to content
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

JIT: Compile every generic specialization separately for all types #32879

Open
artelk opened this issue Feb 26, 2020 · 7 comments
Open

JIT: Compile every generic specialization separately for all types #32879

artelk opened this issue Feb 26, 2020 · 7 comments

Comments

@artelk
Copy link

artelk commented Feb 26, 2020

Currently it only works for struct type parameters.
The proposal is to extend that behavior to include reference types as well.

There could be a setting in the config file to switch it off if needed.

@Dotnet-GitSync-Bot Dotnet-GitSync-Bot added the untriaged New issue has not been triaged by the area owner label Feb 26, 2020
@jeffschwMSFT jeffschwMSFT added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Feb 26, 2020
@AndyAyersMS AndyAyersMS added area-VM-coreclr and removed area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI labels Feb 27, 2020
@AndyAyersMS
Copy link
Member

The runtime determines which instantiations are shared, so relabelling.

My understanding is that some sharing is required, otherwise there is an explosion in the number of instantations.

@mangod9 mangod9 removed the untriaged New issue has not been triaged by the area owner label Apr 10, 2020
@mangod9 mangod9 added this to the Future milestone Apr 10, 2020
@tannergooding
Copy link
Member

@AndyAyersMS, do we know how complicated it would be to support this via say some attribute for specific reference types?

I imagine that while we generally want to share when possible, their are likely explicit cases where we know it would be beneficial to specialize (at an opt-in, per method basis).
For example, string is fairly common as are cases like ICollection<T> or T[] for various performance oriented gains/optimizations.

@AndyAyersMS
Copy link
Member

See also #9682.

From what I know of the runtime it might not be too bad, though I suspect the assumption that ref class instantiations are always shared has crept in a (few?) places, and there's nothing to keep things honest.

Maybe @davidwrighton can comment -- I think he has mentioned perhaps enabling "unshared" ref class instantiation driven by profile feedback.

@tannergooding
Copy link
Member

See also #9682.

I see I asked basically the same question 2 years ago and forgot about it 😄

@davidwrighton
Copy link
Member

There are quite a lot of assumptions in our runtime that reference instantiations are shared. Some years ago we had an ifdef which disabled all sharing, which wouldn't be all that hard to bring back, but wouldn't be that great as we know most instantiations work better when shared. An alternative thought which would likely fit better with our current runtime and direction of investment, would be to have extra versions of the code which are specialized. The runtime already has the ability to have multiple copies of a particular method's code, so perhaps we could have a copy of say... Dictionary<__Canon, __Canon>.TryGetValue, where we just happen to know that the first type parameter is actually string. I'd been thinking this could be something we could drive based on some sort of profile driven feedback, but I had mentally placed this sort of work into a post .NET 6 world.

@tannergooding
Copy link
Member

tannergooding commented Feb 5, 2021

One of the reasons I asked was it came up in API review where we had discussed not wanting to expose additional overloads for things like say LINQ but at the same time, we know there is a cost to all of the various if(source is ICollection<TSource>) checks and friends.

For value types we don't really have this concern, since it is all specialized (just different concerns, like crossgen bloat); but for reference types we either need new overloads or are stuck with runtime checks, so we can't easily specialize for the common case (say string, array, or ICollection).

Hence my thought on some opt-in way to do this so you could theoretically say [SpecializeFor(typeof(string))] or [SpecializeFor(typeof(string), typeof(object))] (effectively "partial specialization on the first parameter, but not the latter).

CC. @stephentoub

@davidwrighton
Copy link
Member

This is really another ask for efficient typeswitch, for which we already have a basic design, we just haven't implemented it. I hasn't met the bar for implementation for either 3.0, 5.0, or 6.0, but if there is interest for this outside of the language team it would be good to know.

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

No branches or pull requests

7 participants