-
Notifications
You must be signed in to change notification settings - Fork 1k
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
Champion "Compiler intrinsics (calli, ldftn, etc)" #191
Comments
What are the advantages of compiler intrinsics for specific IL-opcodes instead of directly supporting inline-IL? |
@Unknown6656 you don't have to modify the parser, only the emitter, so you get to reuse type checking. |
At least for |
Need more motivation to prioritize this |
@MadsTorgersen What kind of motivation? I can buy beers to anyone who implements it if they need to motivate that way. There's plenty of use cases for this - see all the people referencing the issue at dotnet/roslyn#11475. Could implementing this be an up for grabs issue in the Roslyn repo? |
@MichalStrehovsky @MadsTorgersen |
Unlikely. We are still uncertain this is the design we want to take. I personally have a lot of reservations about the approach. |
@jaredpar |
IL as a language feature is a little bit of a cop-out I think. |
@4creators the LDM notes capture most of the push back. Mostly though it's a feature that essentially lets you write IL in C#. If we want that as a feature I'd rather just support inline IL than almost IL for a few small cases. But more importantly the main use cases for these features can be done with firstn class language features which are already under consideration. Would rather support |
I would also think that these would be more useful as a general API (exposed in CoreFX and powered by CoreCLR, just like the hardware intrinsics), rather than as a language specific feature. Being able to write IL code that isn't supported by the language in a easy to use/performant manner isn't just limited to C#. |
IIRC, the LDM approved the feature as proposed in dotnet/roslyn#11475. |
@jaredpar If this has LDM approval, can we mark this as up for grabs? I also remember it being LDM approved from hallway conversations. The LDM meeting notes discussing this stop mid sentence, unfortunately. |
I don't remember that we approved it directly. Instead we wanted to see if other features were going to get done and then come back to this if not. It's been a while since we discussed this and possible I'm misremembering.
The process for contributing language features is described here: Developing a Language Feature. In summary though language features are done with oversight / in conjunction with the compiler team. They are sufficiently complex, and must update so many parts of the language experience, that it's not realistic to have an "up for grabs model". |
@gafter @MadsTorgersen who might recall the LDM meeting. |
As I understand it, the main point of this proposal is to support IL opcodes that can't be reasonably expressed as library methods. Specifically, how do you imagine the API for |
Like this: Static Delegates Seems the point is that rather than providing awkward facilities to access the specific IL opcodes directly that the use cases for those opcodes would be determined and proper language features offered instead. That largely makes sense, although there will likely always be weird edge cases that couldn't be handled. Not to mention the burden would be on the team to identify those cases and design APIs around them. |
It would effectively have the same signature as however C# would expose it if it had an intrinsic for it. |
But yes, for the relatively few keywords C# doesn't support, I would personally prefer language features ( And for We can currently emit IL dynamically, but it is expensive and (AFAIK) can't readily be used inline with existing methods. Having an API where the JIT sees an API call and interprets it as the equivalent |
I assumed that the interpreting and replacement would be done by the compiler? Why put the onus onto the JIT to identify, validate and replace IL intrinsics? |
In the same vein, why put any burden on the compiler to implement this when the corresponding language proposals to expose the functionality would likely be better. I think this would be better as a runtime feature because:
That being said, I think there are better investments for the runtime as well and that this wouldn't be very high on the priority list (if it wasn't rejected right away anyways) |
Maybe. I think it depends a great deal on the feature, especially since unless the API is shaped very specifically following CLS it would be up in the air as to whether or not other CLR-based languages could exploit it anyway. And even then it might not feel natural in those languages. I think that approach makes significantly more sense when dealing with instrinsics specific to machine language for specific architectures and less with IL. As a compiler feature it skips an unnecessary step and could have better integration and validation within the language. |
C# already has several of these "IL intrinsics" that are not part of the official language, but are there for people who need them for advanced scenarios. Think We keep coming back to the "let's make this a JIT feature instead", but that would require JIT to pattern match delegate creation sequence with the intrinsic (for the addrof scenario) and those things are not great (e.g. it took several attempts to get |
Agreed. We have discussed all the options and their pros and cons presented on this thread already at the said LDM and decided that the proposal dotnet/roslyn#11475 is the optimal in terms of complexity (low) and amount of impact (no impact) on the rest of the stack (IDE, analyzers, tools, JIT, runtime) etc. Any feature that requires runtime changes will take very long time to get implemented in all relevant runtimes -- Desktop .NET, Core CLR, Mono, LLVM, etc. and it will take even longer for a significant amount of customers to upgrade to the new versions of these runtimes. Besides not all the intrinsics are covered by proper language/runtime features like static delegates so the tools that need these intrinsics will need them even if static delegates are implemented everywhere. |
|
your link (1) only says the function pointer aspect has been merged (that would mean I think there were other discussions for function pointers, maybe linking here was just a mistake |
The following code defintily works: public unsafe static class Program
{
static delegate*<int> pointer = &Main;
public static int Main() {
return 0;
}
} and it correctly outputs: .class public auto ansi abstract sealed beforefieldinit Program extends [System.Private.CoreLib]System.Object
{
.field private static method int32 *() pointer
.method public hidebysig static int32 Main () cil managed
{
.maxstack 8
ldc.i4.0
ret
}
.method private hidebysig specialname rtspecialname static void .cctor () cil managed
{
.maxstack 8
ldftn int32 Program::Main()
stsfld method int32 *() Program::pointer
ret
}
} |
@Unknown6656 yes but that wasn't the question, nor is that what was described in this proposal. There were other proposals for function pointers that got implemented as you described them. net effect:
|
Fair point, I only mentioned it for completeness sake - not really as an answering comment. |
The feature function pointers is now merged into the main branch but remains under preview. The plan is to ship it with C# 9. This issue is separate from function pointers but has significant overlap. My expectation is that when we ship function pointers we will resolve this issue at the same time we close down function pointers. There are a few items, like |
It is not. |
Please help me get this to the right place. I am experiencing a bug with function pointers. Steps to repro:
Run. Result: I am guessing this has something to do with Extractor uhoh being a member of Host, and also using Host as an argument for it's function pointer? Love the new feature otherwise :D. Is full documentation in the works? |
I don't believe that has anything to do with function pointers, it looks like dotnet/runtime#6924. |
@333fred It's very likely that that is my bug. Thank you. |
In my code I have something like this in a very hot path: interface IFoo { int DoSomething(args); }
class FooGroup
{
private readonly ImmutableArray<IFoo> _foos;
public int HotMethod(args)
{
int local = 0;
foreach (var foo in _foos)
{
local += foo.DoSomething(args)
}
return local
}
} The IFoo's are all distinct types, so I guess the JIT can't do much with respect to guarded devirtualization Every time HotMethod gets called, callvirt is used to invoke each of the DoSomething's implementations. If the function pointer could be assigned an instance method, I could then cache those pointers in FooGroup's constructor and HotMethod would use them instead of a virtual call. Is there any plans to support this (function pointer to instance/interface methods)? |
As Jared indicated, I'm closing this out. |
@333fred function pointers are only a small subset of possible use cases proposed here. |
Yes, I'm aware. As Jared said, if there is significant need we can track those as separate issues/discussions. As of right now, there is no LDM champion for future intrinsics work. |
I personally viewed the other aspects of this proposal as add-ons. The primary motivation of the proposal was function pointers and the suggestion was il-intrinsics as a solution. If we chose to go that route then it made sense to consider a few other intrinsics as they were essentially incremental cost that point. The team would already be doing the heavy lifting to expose a few of the instructions, it made sense to take a bigger view and grab the other missing pieces. I didn't view them as standing on their own here. I'm more than happy to help review a proposal for the work that didn't get done here and the motivations for adding them in. But I do think it should be tracked as a new issue. |
Static Delegates link has changed. |
See also
The text was updated successfully, but these errors were encountered: