-
Notifications
You must be signed in to change notification settings - Fork 5.3k
JIT: extend VN to understand method table fetch from newobj #52476
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
Conversation
If we see a GT_IND whose base is JitNew, the value number of the IND is the same as the value number of the class handle for the new. Partial fix for dotnet#52370.
|
@EgorBo PTAL Results on the #52370 case are similar to Egor's fix. Would be nice to get rid of that frame. Also more changes in this mode are possible, eg new feeding a type test helper, or loading a field of a newly allocated object. IN0002: 000000 sub rsp, 40
G_M4678_IG02: ; offs=000004H, size=0005H, bbWeight=1 PerfScore 0.25, gcrefRegs=00000000 {}, byrefRegs=00000000 {}, byref
IN0001: 000004 mov eax, 3
G_M4678_IG03: ; offs=000009H, size=0005H, bbWeight=1 PerfScore 1.25, epilog, nogc, extend
IN0003: 000009 add rsp, 40
IN0004: 00000D ret Quite a few diffs in SPMI testing (which is a bit ragged still with missing info). Will summarize shortly. |
|
Nice, but will it work without JitNew? e.g.: using System.Runtime.CompilerServices;
using System.Threading;
public class Program
{
public static void Main()
{
// Promote Test to tier1 and collect some profile data
for (int i = 0; i < 100; i++)
{
Test();
Thread.Sleep(16);
}
}
[MethodImpl(MethodImplOptions.NoInlining)]
static B GetB() => new B(); // not inlineable, but returns sealed type
static A GetA() => GetB();
[MethodImpl(MethodImplOptions.NoInlining)]
static int Test()
{
return GetA().GetValue();
}
}
public class A
{
public virtual int GetValue() => 1;
}
public sealed class B : A
{
public override int GetValue() => 3;
} |
|
SPMI diffs Some large improvements in places, typically where the optimization leads to folding a branch. A few large regressions in test cases that do a lot of type testing, as we are now propagating a large literal method table value to many uses. We should consider either not propagating such a large constant, or CSEing it back later. asm.aspnet.run.windows.x64.checked Detail diffsasm.benchmarks.run.windows.x64.checked Detail diffsasm.libraries.crossgen.windows.x64.checked Detail diffsasm.libraries.pmi.windows.x64.checked Detail diffsasm.tests.pmi.windows.x64.checked Detail diffsasm.tests_libraries.pmi.windows.x64.checked Detail diffs |
No. Which is why you should go ahead with your proposed fix too. VN generally doesn't handle conditional facts. So say we learn the exact type of some ssa value because of a type test introduced by GDV. VN has no way of expressing this unless. Some compilers I've seen will introduce "fake" ssa defs in order to extend the power of analyses like VN, eg if (x == 3) S1; else S2;would become if (x == 3) { x = 3; S1; } else S2;Assertion prop can also operate on conditional facts like these; not sure if it handles this case. Worth investigating. |
|
Failure is a known issue (#52464). |
If we see a GT_IND whose base is JitNew, the value number of the IND
is the same as the value number of the class handle for the new.
Partial fix for #52370.