-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Description
In the following example we'd like the jit to produce the same (or very similar code) for both Fint
and Findex
:
using System;
class X
{
public static void Fint(Span<int> c)
{
for (int i = 1; i <= c.Length; i++)
{
c[c.Length - i] += 1;
}
}
public static void Findex(Span<int> c)
{
for (int i = 1; i <= c.Length; i++)
{
c[new Index(i, fromEnd: true)] += 1;
}
}
}
However currently the Index
ctor won't inline (see #11848) and the IL is not jit-friendly. If we revise it and then force it to inline, we still see some codegen deficiencies:
;; Fint
G_M7659_IG03:
mov r8d, edx
sub r8d, ecx
cmp r8d, edx
jae SHORT G_M7659_IG05
movsxd r8, r8d
lea r8, bword ptr [rax+4*r8]
inc dword ptr [r8]
inc ecx
cmp ecx, edx
jle SHORT G_M7659_IG03
;; Findex (with Index ctor changes)
G_M36427_IG03:
test ecx, ecx
jl SHORT G_M36427_IG08
G_M36427_IG04:
mov r8d, ecx
not r8d
test r8d, r8d
jl SHORT G_M36427_IG05
jmp SHORT G_M36427_IG06
G_M36427_IG05:
not r8d
mov r9d, edx
sub r9d, r8d
mov r8d, r9d
G_M36427_IG06:
cmp r8d, edx
jae SHORT G_M36427_IG09
movsxd r8, r8d
lea r8, bword ptr [rax+4*r8]
inc dword ptr [r8]
inc ecx
cmp ecx, edx
jle SHORT G_M36427_IG03
Root cause is that Index
uses an inverted (~negative) value to encode "from end" and the jit can't propagate this from construction down to use.
Range prop might be the right place to address this but it currently does not model not
. But doing that, opts would only kick in when Index
is used as an array index.
Tentatively putting this in 3.0,but may defer depending on urgency of removing overhead from use of Index
.
category:cq
theme:optimization
skill-level:expert
cost:medium