-
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
Calls to Interlocked.CompareExchange<T> prevents inlining #8662
Comments
Inlining isn't blocked by CompareExchange but by runtime dictionary lookup that's needed in the generic code. |
I would have never expect a dictionary lookup underlying |
It is exactly when For example, if you change your code to not be generic you get the following code for G_M2434_IG01:
56 push rsi
4883EC20 sub rsp, 32
G_M2434_IG02:
4883C108 add rcx, 8
488B31 mov rsi, gword ptr [rcx]
4885F6 test rsi, rsi
740F je SHORT G_M2434_IG03
4C8BC6 mov r8, rsi
33D2 xor rdx, rdx
E8C5B1505F call System.Threading.Interlocked:CompareExchange(byref,ref,ref):ref
483BC6 cmp rax, rsi
7404 je SHORT G_M2434_IG04
G_M2434_IG03:
33C0 xor rax, rax
EB03 jmp SHORT G_M2434_IG05
G_M2434_IG04:
488BC6 mov rax, rsi
G_M2434_IG05:
4883C420 add rsp, 32
5E pop rsi
C3 ret |
The inlines done are:
You often can't inline from one shared generic class into another, so Making the inner class non-generic or instantiating the outer class over a value type (eg via the struct wrapped ref class trick if you really wanted a ref class all along) would likely unblock this case. From the second inline you can see that interlocked compare exchange is inlineable (and there's already a magic transformation to call the non-generic version thanks to IL intrinsics). The inlined version calls into native code so there's nothing more the jit can do here. Even if all the inlines were unblocked you would still see a call to do the compare exchange. I haven't verified this, and my understanding of this part of the runtime is sketchy, but the fact that |
Tried, same result. |
No luck either. |
This is a runtime restriction so not much the jit can do here until there is runtime support. @davidwrighton has prototyped some changes that would unblock such cases (#31833). |
Nothing much has changed here. @EgorBo weren't you working on some changes to remove the shared-shared inlining restrictions? |
Perhaps, for .NET 9.0 🙂 |
This is the smaller code that showcase the issue. This code is working very hard to avoid cache issues but still have to pay for the call because it refuses to inline in CoreCLR 1.1 and CoreCLR 2.0 (1w old build).
I may be missing something, but dont see any reason why it shouldn't inline.
cc @AndyAyersMS
category:cq
theme:inlining
skill-level:expert
cost:medium
The text was updated successfully, but these errors were encountered: