- 
                Notifications
    You must be signed in to change notification settings 
- Fork 5.2k
Optimize GDV checks for objects with known type #84661
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
| 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 71Now: ; 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 <[email protected]>
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_classGDV's guards if we can get the exact type ofobj. This is needed for #84659Codegen improvement example:
Was:
Now: