Skip to content
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

JIT: Fold type checks with GDV #52370

Closed
Tracked by #64659
EgorBo opened this issue May 6, 2021 · 8 comments
Closed
Tracked by #64659

JIT: Fold type checks with GDV #52370

EgorBo opened this issue May 6, 2021 · 8 comments
Assignees
Labels
area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI tenet-performance Performance related issue
Milestone

Comments

@EgorBo
Copy link
Member

EgorBo commented May 6, 2021

static A GetAObj() => new C();

[MethodImpl(MethodImplOptions.NoInlining)]
static int Test() => GetAObj().GetValue();


public class A
{
    public virtual int GetValue() => 1;
}

public sealed class C : A
{
    public override int GetValue() => 3;
}

Current codegen for Test (PGO, GDV):

G_M58954_IG01:    
       4883EC28             sub      rsp, 40
G_M58954_IG02:            
       48B9C084615BFE7F0000 mov      rcx, 0x7FFE5B6184C0
       E85DCB545F           call     CORINFO_HELP_NEWSFAST
       488BC8               mov      rcx, rax
       48B8C084615BFE7F0000 mov      rax, 0x7FFE5B6184C0
       483901               cmp      qword ptr [rcx], rax ;; this check should be folded and fallback is removed
       750A                 jne      SHORT G_M58954_IG04
       B803000000           mov      eax, 3
G_M58954_IG03:      
       4883C428             add      rsp, 40
       C3                   ret      
G_M58954_IG04:         
       FF157B301700         call     [C:GetValue():int:this]
       EBF3                 jmp      SHORT G_M58954_IG03

After inlining we know the exact type of the GetAObj, so we should fold this:

***** BB01
STMT00009 (IL 0x000...  ???)
N005 ( 16, 16) [000029] -AC-----R---              *  ASG       ref   
N004 (  1,  1) [000028] D------N----              +--*  LCL_VAR   ref    V04 tmp4         d:1
N003 ( 16, 16) [000027] --C---------              \--*  CALL help ref    HELPER.CORINFO_HELP_NEWSFAST
N002 (  2, 10) [000026] H----------- arg0 in rcx     \--*  CNS_INT(h) long   0x7ffe5b628668 method

***** BB01
STMT00001 (IL   ???...  ???)
N003 (  1,  3) [000004] -A------R---              *  ASG       ref   
N002 (  1,  1) [000003] D------N----              +--*  LCL_VAR   ref    V01 tmp1         d:1
N001 (  1,  1) [000032] ------------              \--*  LCL_VAR   ref    V04 tmp4         u:1

***** BB01
STMT00004 (IL   ???...  ???)
N005 (  8, 15) [000013] ---X--------              *  JTRUE     void  
N004 (  6, 13) [000012] J--X---N----              \--*  NE        int   
N002 (  3,  2) [000010] #--X--------                 +--*  IND       long  
N001 (  1,  1) [000009] ------------                 |  \--*  LCL_VAR   ref    V04 tmp4         u:1 (last use)
N003 (  2, 10) [000011] H-----------                 \--*  CNS_INT(h) long   0x7ffe5b628668 class

We assign the exact class (B) to tmp4 which is then copied to tmp1 and checked is B (which is always true).

/cc @AndyAyersMS

@EgorBo EgorBo added the tenet-performance Performance related issue label May 6, 2021
@dotnet-issue-labeler dotnet-issue-labeler bot added area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI untriaged New issue has not been triaged by the area owner labels May 6, 2021
@EgorBo EgorBo self-assigned this May 6, 2021
@EgorBo EgorBo added this to the Future milestone May 6, 2021
@EgorBo
Copy link
Member Author

EgorBo commented May 6, 2021

Ah, actually it should be pretty simple to implement in morph:

image

New codegen:

G_M58954_IG01:              ;; offset=0000H
       4883EC28             sub      rsp, 40
						;; bbWeight=1    PerfScore 0.25
G_M58954_IG02:              ;; offset=0004H
       B803000000           mov      eax, 3
						;; bbWeight=1    PerfScore 0.25
G_M58954_IG03:              ;; offset=0009H
       4883C428             add      rsp, 40
       C3                   ret      
						;; bbWeight=1    PerfScore 1.25

So I'm going to mark it as 6.0 and will file a PR later once I finish active PRs.

@EgorBo EgorBo modified the milestones: Future, 6.0.0 May 6, 2021
@AndyAyersMS
Copy link
Member

I wonder if we can catch this in GDV itself, re-checking the type of the this.

Also curious why existing opts can't clean this up.

@AndyAyersMS
Copy link
Member

I wonder if we can catch this in GDV itself, re-checking the type of the this.

Not in this case, as the GDV expansion happens before inlining.

Also curious why existing opts can't clean this up.

Assertion prop doesn't propagate exact typeness for newobj. Seems like it should...?

VN can't recover the vtable identity from an indir fed by a newobj. Seems like it could...? (also maybe non-nullness...?)

***** BB01, STMT00009(before)
N005 ( 16, 16) [000029] -AC-----R---              *  ASG       ref   
N004 (  1,  1) [000028] D------N----              +--*  LCL_VAR   ref    V04 tmp4         d:1
N003 ( 16, 16) [000027] --C---------              \--*  CALL help ref    HELPER.CORINFO_HELP_NEWSFAST
N002 (  2, 10) [000026] H----------- arg0 in rcx     \--*  CNS_INT(h) long   0x7ffba176b058 method

N001 [000042]   ARGPLACE  => $c0 {c0}
N002 [000026]   CNS_INT(h) 0x7ffba176b058 method => $100 {Hnd const: 0x00007FFBA176B058}
VN of ARGPLACE tree [000042] updated to $100 {Hnd const: 0x00007FFBA176B058}
N003 [000027]   CALL help => $180 {JitNew($100, $140)}
N004 [000028]   LCL_VAR   V04 tmp4         d:1 => $180 {JitNew($100, $140)}
N005 [000029]   ASG       => $180 {JitNew($100, $140)}

...

***** BB01, STMT00004(before)
N005 (  8, 15) [000013] ---X--------              *  JTRUE     void  
N004 (  6, 13) [000012] J--X---N----              \--*  NE        int   
N002 (  3,  2) [000010] #--X--------                 +--*  IND       long  
N001 (  1,  1) [000009] ------------                 |  \--*  LCL_VAR   ref    V04 tmp4         u:1 (last use)
N003 (  2, 10) [000011] H-----------                 \--*  CNS_INT(h) long   0x7ffba176b058 class

N001 [000009]   LCL_VAR   V04 tmp4         u:1 (last use) => $180 {JitNew($100, $140)}
    VNForMapSelect($2, $180):ref returns $181 {$VN.ReadOnlyHeap[$180]}
    VNForMapSelect($2, $180):ref returns $181 {$VN.ReadOnlyHeap[$180]}
N002 [000010]   IND       => $183 {norm=$181 {$VN.ReadOnlyHeap[$180]}, exc=$182 {NullPtrExc($180)}}
N003 [000011]   CNS_INT(h) 0x7ffba176b058 class => $101 {Hnd const: 0x00007FFBA176B058}
N004 [000012]   NE        => $1c1 {norm=$1c0 {NE($181, $101)}, exc=$182 {NullPtrExc($180)}}

@AndyAyersMS
Copy link
Member

AndyAyersMS commented May 7, 2021

Have a fix for this in AP value numbering ... looking at diffs.

AndyAyersMS added a commit to AndyAyersMS/runtime that referenced this issue May 7, 2021
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.
@AndyAyersMS AndyAyersMS removed the untriaged New issue has not been triaged by the area owner label May 9, 2021
@AndyAyersMS
Copy link
Member

As I noted over in #52476 you should go ahead with a fix in morph too. The earlier we can clean up control flow, the better.

@EgorBo
Copy link
Member Author

EgorBo commented May 9, 2021

As I noted over in #52476 you should go ahead with a fix in morph too. The earlier we can clean up control flow, the better.

Sure, will try once your PR is merged!

AndyAyersMS added a commit that referenced this issue May 9, 2021
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.
@ghost ghost added the in-pr There is an active PR which will close this issue when it is merged label Jul 12, 2021
@EgorBo
Copy link
Member Author

EgorBo commented Jul 28, 2021

#55124 found only just a few cases in real-world app and since it's just an opt - I'm moving it to 7.0

@EgorBo EgorBo modified the milestones: 6.0.0, 7.0.0 Jul 28, 2021
@ghost ghost removed the in-pr There is an active PR which will close this issue when it is merged label Jul 28, 2021
@ghost ghost added the in-pr There is an active PR which will close this issue when it is merged label Mar 13, 2022
@ghost ghost removed the in-pr There is an active PR which will close this issue when it is merged label Mar 16, 2022
@EgorBo
Copy link
Member Author

EgorBo commented May 30, 2022

Fix: #66711 but since there were no hits I am closing this as non-actionable

@EgorBo EgorBo closed this as completed May 30, 2022
@ghost ghost locked as resolved and limited conversation to collaborators Jun 29, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI tenet-performance Performance related issue
Projects
Archived in project
2 participants