JIT: Handle some "field offset computation" patterns (#81998)
authorJakob Botsch Nielsen <Jakob.botsch.nielsen@gmail.com>
Tue, 4 Apr 2023 22:26:03 +0000 (00:26 +0200)
committerGitHub <noreply@github.com>
Tue, 4 Apr 2023 22:26:03 +0000 (00:26 +0200)
commit337999d51dd96ee156c5fb9bac22e36b2ee8ae85
tree626c2e81ab6daff8a51444cc35afffb1a6845dc1
parente0c94f84b47fdd48435a625446123f89268b9c20
JIT: Handle some "field offset computation" patterns (#81998)

Both during local morph and during VN.

Fix #40021

Saves 3 KB on BasicMinimalApi after #84095 (there's 1111 __GetFieldHelper functions). About 0.04%. There's still a null check kept for each offset computation, which we cannot really get rid of, but NAOT could maybe emit the IL such that there is a dominating null check so that only one is emitted.

Example:
Base:
```
.managed:0000000140347CC0 loc_140347CC0:                          ; CODE XREF: S_P_CoreLib_System_Collections_Generic_KeyValuePair_2_System_Net_Security_System_Net_Security_SslSessionsCache_SslCredKey__System___Canon_____GetFieldHelper+23↑j
.managed:0000000140347CC0                                         ; DATA XREF: .rdata:__readonlydata_S_P_CoreLib_System_Collections_Generic_KeyValuePair_2_System_Net_Security_System_Net_Security_SslSessionsCache_SslCredKey__System___Canon_____GetFieldHelper↓o
.managed:0000000140347CC0                 lea     rax, ??_7Boxed_System_Net_Security_System_Net_Security_SslSessionsCache_SslCredKey@@6B@ ; jumptable 0000000140347CB3 case 0
.managed:0000000140347CC7                 mov     [r9], rax
.managed:0000000140347CCA                 cmp     [rcx], cl
.managed:0000000140347CCC                 lea     rax, [rcx+8]
.managed:0000000140347CD0                 sub     rax, rcx
.managed:0000000140347CD3                 add     rsp, 8
.managed:0000000140347CD7                 retn
```
Diff:

```
.managed:0000000140347AA0 loc_140347AA0:                          ; CODE XREF: S_P_CoreLib_System_Collections_Generic_KeyValuePair_2_System_Net_Security_System_Net_Security_SslSessionsCache_SslCredKey__System___Canon_____GetFieldHelper+23↑j
.managed:0000000140347AA0                                         ; DATA XREF: .rdata:__readonlydata_S_P_CoreLib_System_Collections_Generic_KeyValuePair_2_System_Net_Security_System_Net_Security_SslSessionsCache_SslCredKey__System___Canon_____GetFieldHelper↓o
.managed:0000000140347AA0                 lea     rax, ??_7Boxed_System_Net_Security_System_Net_Security_SslSessionsCache_SslCredKey@@6B@ ; jumptable 0000000140347A93 case 0
.managed:0000000140347AA7                 mov     [r9], rax
.managed:0000000140347AAA                 cmp     [rcx], cl
.managed:0000000140347AAC                 mov     eax, 8
.managed:0000000140347AB1                 add     rsp, 8
.managed:0000000140347AB5                 retn
```

Local morph changes handle the pattern for local structs -- VN changes handle the pattern for classes (and more complicated struct cases, like storing them in locals, which there are a few examples of in #40021).
src/coreclr/jit/lclmorph.cpp
src/coreclr/jit/valuenum.cpp