In order to be able to declare unrolling rules in pure C# the way it was proposed in #64821 for strings we need to be able to fold this in JIT:
T SecondChar<T>(ReadOnlySpan<T> span) => span[1];
T GetLength<T>(ReadOnlySpan<T> span) => span.Length;
char Test1() => SecondChar<char>("hello"); // => 'e'
int Test2() => GetLength<char>("hello"); // => 5
Both Test1 and Test2 has to be folded to constants.
Ideally we should be able to also handle spans of bytes (utf8)
Also, fold constant accesses to RVA data (from #64612). Example:
static ReadOnlySpan<byte> data => new byte[] { 1, 2, 3, 4, 5 };
byte Test() => data[3];
Current codegen:
; Method Prog:Test():ubyte:this
48B8A32BAD36FD010000 mov rax, 0x1FD36AD2BA3
0FB600 movzx rax, byte ptr [rax]
C3 ret
; Total bytes of code: 14
Expected codegen:
; Method Prog:Test():ubyte:this
B804000000 mov eax, 4
C3 ret
; Total bytes of code: 6
NOTES:
- JIT is already able to do it for string literals e.g.
"hello"[2] (see fgMorphArrayIndex)
- C# should soon get a support for
ROS<any primitive> = RVA, not just byte/bool as it is currently
- We probably can't do it for RVAs in C++/CLI/CX which are mutable (check for mixed-mode)
- This task most likely needs a new JIT-EE API or maybe the existing
getArrayInitializationData is enough
In order to be able to declare unrolling rules in pure C# the way it was proposed in #64821 for strings we need to be able to fold this in JIT:
Both
Test1andTest2has to be folded to constants.Ideally we should be able to also handle spans of bytes (utf8)
Also, fold constant accesses to RVA data (from #64612). Example:
Current codegen:
Expected codegen:
NOTES:
"hello"[2](seefgMorphArrayIndex)ROS<any primitive> = RVA, not justbyte/boolas it is currentlygetArrayInitializationDatais enough