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: Handle enums in box-unbox optimization #70167

Merged
merged 1 commit into from
Jun 8, 2022

Conversation

EgorBo
Copy link
Member

@EgorBo EgorBo commented Jun 2, 2022

Closes #55355

When we box a enum and unbox it as integer (and vice versa) JIT should be able to optimize it as no-op. E.g. https://sharplab.io/#v2:EYLgxg9gTgpgtADwGwBYA0AXEBDAzgWwB8ABABgAJiBGAOgCUBXAOwwEt8YaBhCfAB1YAbGFADKIgG6swMXAG4AsACgy5UQAtsUPgBlsweszYdFS5cQBMlKgHZlAb2Xln5ANoApVhgDiMJiOkACgwATz4YCAAzQIBRJgZ8KgBKJIBdZwB6DPImCAwnF1cAWRgMdQgAEwBJfkFAkrLKmr5BAHk+NggmXBoAQQBzfthcXFYJGCqmQVYmGf60gudiAGZrJHJgCAhBcgAJPAAxQWx+gB4AFQA+QPPyCWxBBhg0clvI4/nF8kclFz/KGzkQKBGYYJKBCDAABWMDAYPujxg5AAZEDQeDITC4Ul3ickuQALwEtEsDHQ2Fg3H9Ux/AC+ynpZhUqz8CXIcQSVG+5F6LwAQuRaUA==

New codegen:

; Program.HasFlag
       and      ecx, edx
       xor      eax, eax
       cmp      ecx, edx
       sete     al
       ret      
; Total bytes of code: 10

The change is small, the verbosity is due to JIT-EE update, I had to add a flag to compareTypesForEquality because in some places it's still expected to be more conservative around enums vs integers.

@dotnet-issue-labeler dotnet-issue-labeler bot added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Jun 2, 2022
@ghost ghost assigned EgorBo Jun 2, 2022
@ghost
Copy link

ghost commented Jun 2, 2022

Tagging subscribers to this area: @JulieLeeMSFT
See info in area-owners.md if you want to be subscribed.

Issue Details

Closes #55355

When we box a enum and unbox it as integer (and vice versa) JIT should be able to optimize it as no-op. E.g. https://sharplab.io/#v2:EYLgxg9gTgpgtADwGwBYA0AXEBDAzgWwB8ABABgAJiBGAOgCUBXAOwwEt8YaBhCfAB1YAbGFADKIgG6swMXAG4AsACgy5UQAtsUPgBlsweszYdFS5cQBMlKgHZlAb2Xln5ANoApVhgDiMJiOkACgwATz4YCAAzQIBRJgZ8KgBKJIBdZwB6DPImCAwnF1cAWRgMdQgAEwBJfkFAkrLKmr5BAHk+NggmXBoAQQBzfthcXFYJGCqmQVYmGf60gudiAGZrJHJgCAhBcgAJPAAxQWx+gB4AFQA+QPPyCWxBBhg0clvI4/nF8kclFz/KGzkQKBGYYJKBCDAABWMDAYPujxg5AAZEDQeDITC4Ul3ickuQALwEtEsDHQ2Fg3H9Ux/AC+ynpZhUqz8CXIcQSVG+5F6LwAQuRaUA==

New codegen:

; Program.HasFlag
       and      ecx, edx
       xor      eax, eax
       cmp      ecx, edx
       sete     al
       ret      
; Total bytes of code: 10

The change is small, the verbosity is due to JIT-EE update, I had to add a flag to compareTypesForEquality because in some places it's still expected to be more conservative around enums vs integers.

Author: EgorBo
Assignees: -
Labels:

area-CodeGen-coreclr

Milestone: -

@jakobbotsch
Copy link
Member

Can you please take care of #69900 too since you are changing JIT-EE GUID?

@EgorBo
Copy link
Member Author

EgorBo commented Jun 2, 2022

Can you please take care of #69900 too since you are changing JIT-EE GUID?

Done

@EgorBo
Copy link
Member Author

EgorBo commented Jun 2, 2022

@dotnet/jit-contrib PTAL, small change (actual change)

@@ -7455,7 +7455,7 @@ int Compiler::impBoxPatternMatch(CORINFO_RESOLVED_TOKEN* pResolvedToken,

// See if the resolved tokens describe types that are equal.
const TypeCompareState compare =
info.compCompHnd->compareTypesForEquality(unboxResolvedToken.hClass, pResolvedToken->hClass);
info.compCompHnd->compareTypesForEquality(unboxResolvedToken.hClass, pResolvedToken->hClass, false);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we could just call getTypeForPrimitiveValueClass on the classes here. I guess it's not the exact same logic but maybe it is ok?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great idea! addressed 🙂

Comment on lines 2643 to 2644
type1 = type1.IsEnum ? type1.UnderlyingType : type1;
type2 = type2.IsEnum ? type2.UnderlyingType : type2;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

UnderlyingType returns this if the type is not an enum.

Suggested change
type1 = type1.IsEnum ? type1.UnderlyingType : type1;
type2 = type2.IsEnum ? type2.UnderlyingType : type2;
type1 = type1.UnderlyingType;
type2 = type2.UnderlyingType;

@EgorBo EgorBo merged commit 585bc30 into dotnet:main Jun 8, 2022
@ghost ghost locked as resolved and limited conversation to collaborators Jul 9, 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
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Inefficient codegen for enum -> object -> int casts
3 participants