-
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
Optimize GDV checks for objects with known type #84661
Conversation
Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch, @kunalspathak Issue DetailsOptimize Codegen improvement example: string Test(byte[] data) => Encoding.UTF8.GetString(data); Was: ; Assembly listing for method Prog:Test(ubyte[]):System.String:this
; Tier-1 compilation
; 1 inlinees with PGO data; 1 single block inlinees; 0 inlinees without PGO data
sub rsp, 40
mov rcx, 0x1C4C0C009F0 ; const ptr
mov rcx, gword ptr [rcx]
mov rax, 0x7FFE3DD8A348 ; System.Text.UTF8Encoding+UTF8EncodingSealed
cmp qword ptr [rcx], rax ;;; <---- redundant check, obj is already of UTF8EncodingSealed
jne SHORT G_M52604_IG07
test rdx, rdx
je SHORT G_M52604_IG04
cmp dword ptr [rdx+08H], 32
jg SHORT G_M52604_IG04
call [System.Text.UTF8Encoding+UTF8EncodingSealed:GetStringForSmallInput(ubyte[]):System.String:this]
jmp SHORT G_M52604_IG05
G_M52604_IG04:
call [System.Text.Encoding:GetString(ubyte[]):System.String:this]
G_M52604_IG05:
nop
add rsp, 40
ret
G_M52604_IG07:
call [System.Text.UTF8Encoding+UTF8EncodingSealed:GetString(ubyte[]):System.String:this]
jmp SHORT G_M52604_IG05
; Total bytes of code 71 Now: ; Assembly listing for method Prog:Test(ubyte[]):System.String:this
; Tier-1 compilation
; optimized code
; 1 inlinees with PGO data; 1 single block inlinees; 0 inlinees without PGO data
sub rsp, 40
mov rcx, 0x1B4148009F0
mov rcx, gword ptr [rcx]
test rdx, rdx
je SHORT G_M52604_IG04
cmp dword ptr [rdx+08H], 32
jg SHORT G_M52604_IG04
call [System.Text.UTF8Encoding+UTF8EncodingSealed:GetStringForSmallInput(ubyte[]):System.String:this]
jmp SHORT G_M52604_IG05
G_M52604_IG04:
call [System.Text.Encoding:GetString(ubyte[]):System.String:this]
G_M52604_IG05:
nop
add rsp, 40
ret
; Total bytes of code 48
|
PTAL @AndyAyersMS - I wanted to land this fix in the past and gave up but now I found a real use-case |
Seems like something we already should have been able to clean up. What is it we know when we do this new type compare fold that we don't know later on (say in value numbering)? |
I don't think we have anything like that in VN, you probably confuse it with your #72136 which is different. I could move this opt to VN as well but all the cases I found looked like can be handled earlier in Morph. Essentially, it happens when we have something like this:
when we look at If you want to repro it locally: public class ClassA
{
public virtual int GetVal() => 42;
}
public sealed class ClassB : ClassA
{
public override int GetVal() => 43;
}
class Prog
{
static readonly ClassB s_default = new ClassB();
static ClassA Default => s_default;
static void Main()
{
for (int i = 0; i < 100; i++)
{
Test();
Thread.Sleep(16);
}
}
[MethodImpl(MethodImplOptions.NoInlining)]
static int Test() => Default.GetVal();
} Run with
It simulates a similar pattern I found in |
With your changes is this firing in
Is what you're saying is that VN doesn't know how to handle method table loads from these "const ptrs"? I'm ok fixing it in morph but remember that morph is purely local and if a known value arrives at the comparison via some data flow morph will never see it. So consider fixing it in VN as well. |
@AndyAyersMS I've just merged VN impl 🙂 It turned out VN knew it only if it could find |
It seems it found quite a few cases for my app running locally with PGO. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, but I am ok also having it checked earlier too, like you were doing.
Usually, the earlier the better for these things.
Some nice diffs in Although, it seems that NativeAOT is not happy. Perhaps, it's not legal to represent types as constants there? |
I just redid the ASP.NET collection but maybe another GUID change came in that I missed. Will start it going again. |
/azp list |
This comment was marked as off-topic.
This comment was marked as off-topic.
/azp run runtime-coreclr pgo, runtime-coreclr libraries-pgo |
Azure Pipelines successfully started running 2 pipeline(s). |
The new collection just uploaded. |
Thanks! |
/azp run runtime-extra-platforms |
/azp run runtime-coreclr pgo, runtime-coreclr libraries-pgo |
Azure Pipelines successfully started running 2 pipeline(s). |
src/coreclr/jit/valuenum.cpp
Outdated
void* embedClsHnd = (void*)info.compCompHnd->embedClassHandle(handle, &pEmbedClsHnd); | ||
if (pEmbedClsHnd == nullptr) | ||
{ | ||
// Skip indirect handles for now since this path is mostly for PGO scenarios |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note: indirect handles could be handled by essentially switching out the address for the indirection to be pEmbedClsHnd
.
Co-authored-by: Jan Kotas <jkotas@microsoft.com>
c0bdf20
to
beb3ab9
Compare
I'm struggling with a NativeAOT assert (happens when ILC compiles crossgen2 project) - it happens inside where the values in the assert are:
@MichalStrehovsky @jkotas does it tell you anything, Am I even allowed to use shared types at all in that API? I've inserted |
The assert is complaining about directly embedding type handle that requires dictionary lookup. It is not right in any configs. The types that require dictionary lookup should be never embedded directly. You can try to check |
Thanks, that makes perfect sense |
/azp run runtime-coreclr pgo, runtime-coreclr libraries-pgo |
Azure Pipelines successfully started running 2 pipeline(s). |
The check has fixed the assert and the diffs are back to normal: https://dev.azure.com/dnceng-public/public/_build/results?buildId=248263&view=ms.vss-build-web.run-extensions-tab |
all CI jobs passed except license/CLA 😢 |
Optimize
*obj == const_class
GDV's guards if we can get the exact type ofobj
. This is needed for #84659Codegen improvement example:
Was:
Now: