Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Refactor integer cast codegen#19296

Merged
CarolEidt merged 7 commits into
dotnet:masterfrom
mikedn:cast-cg
Sep 7, 2018
Merged

Refactor integer cast codegen#19296
CarolEidt merged 7 commits into
dotnet:masterfrom
mikedn:cast-cg

Conversation

@mikedn
Copy link
Copy Markdown

@mikedn mikedn commented Aug 5, 2018

The ARM version of CodeGen::genIntToIntCast is completely different from the XARCH version, even though GT_CAST behaves identically on both architectures and both ISAs have very similar instructions (e.g. movsx eax, al and sxtb w0, w0). This difference can cause arch specific bugs (e.g. #18063) and makes it more difficult to improve the codegen (e.g. #12676).

Lowering::getCastDescription attempts to put some of the cast handling logic in a common place but it is only used by ARM codegen and anyway falls short of its goal - it provides a bunch of booleans that codegen has to figure out how to use properly (e.g. else if (castInfo.unsignedSource || castInfo.unsignedDest)).

It also turns out that the overflow checking logic is unnecessarily complicated due to a mix of test and cmp instructions when most of the time just cmp will suffice. This is especially bad on ARM32 where this translates into more complicated register requirements.

This PR started as a bit of refactoring of genIntToIntCast but it turned into a complete rewrite. In the end the ARM and XARCH versions ended up being so similar that I reintroduced a form of "getCastDescription" that I initially removed. The net result is that the list of individual commits and the diff itself is kind of useless, the only thing that's probably worth looking at is the final result. Hopefully this will be compensated by the fact that the rather hairy cast handling logic is in one place and the actual codegen code has become trivial.

@mikedn
Copy link
Copy Markdown
Author

mikedn commented Aug 17, 2018

x64 crossgen diffs:

Total bytes of diff: -401 (0.00% of base)
    diff is an improvement.
Top file improvements by size (bytes):
        -106 : System.Private.CoreLib.dasm (0.00% of base)
         -80 : System.Private.Xml.dasm (0.00% of base)
         -50 : System.Memory.dasm (-0.05% of base)
         -39 : Microsoft.VisualBasic.dasm (-0.02% of base)
         -22 : System.Linq.Expressions.dasm (0.00% of base)
29 total files with size differences (29 improved, 0 regressed), 101 unchanged.
Top method improvements by size (bytes):
         -15 : Microsoft.VisualBasic.dasm - Conversions:ToSByte(ref):byte (2 methods)
         -14 : System.Linq.Expressions.dasm - Checked:ConvertUInt64(long):ref:this
          -7 : System.Linq.Expressions.dasm - Checked:ConvertInt64(long):ref:this
          -7 : System.Private.Uri.dasm - Uri:UnescapeOnly(long,int,byref,ushort,ushort,ushort)
          -6 : System.Memory.dasm - Utf8Formatter:TryFormat(int,struct,byref,struct):bool (2 methods)
231 total methods with size differences (231 improved, 0 regressed), 142693 unchanged.

x86 crossgen diffs:

Total bytes of diff: -73 (0.00% of base)
    diff is an improvement.
Top file improvements by size (bytes):
         -58 : System.Private.CoreLib.dasm (0.00% of base)
          -9 : Microsoft.VisualBasic.dasm (-0.01% of base)
          -6 : System.IO.MemoryMappedFiles.dasm (-0.06% of base)
3 total files with size differences (3 improved, 0 regressed), 127 unchanged.
Top method improvements by size (bytes):
         -22 : System.Private.CoreLib.dasm - StreamWriter:WriteLine(struct):this
         -18 : System.Private.CoreLib.dasm - StreamWriter:Write(struct):this
         -11 : System.Private.CoreLib.dasm - StreamWriter:WriteFormatHelper(ref,struct,bool):this
          -9 : Microsoft.VisualBasic.dasm - Conversions:ToSByte(ref):byte (2 methods)
          -6 : System.IO.MemoryMappedFiles.dasm - MemoryMappedView:CreateView(ref,int,long,long):ref
9 total methods with size differences (9 improved, 0 regressed), 142839 unchanged.

arm64 crossgen diffs:

Total bytes of diff: -280 (0.00% of base)
    diff is an improvement.
Top file improvements by size (bytes):
        -192 : Microsoft.VisualBasic.dasm (-0.03% of base)
         -56 : System.Linq.Expressions.dasm (0.00% of base)
         -16 : System.Data.Common.dasm (0.00% of base)
          -8 : System.Private.CoreLib.dasm (0.00% of base)
          -8 : System.Runtime.Numerics.dasm (0.00% of base)
5 total files with size differences (5 improved, 0 regressed), 125 unchanged.
Top method improvements by size (bytes):
         -48 : Microsoft.VisualBasic.dasm - Conversions:ToShort(ref):short (4 methods)
         -32 : Microsoft.VisualBasic.dasm - Operators:NegateObject(ref):ref (2 methods)
          -8 : Microsoft.VisualBasic.dasm - Operators:NegateBoolean(bool):ref (2 methods)
          -8 : Microsoft.VisualBasic.dasm - Operators:NegateByte(ubyte):ref (2 methods)
          -8 : Microsoft.VisualBasic.dasm - Operators:NegateInt16(short):ref (2 methods)
27 total methods with size differences (27 improved, 0 regressed), 142520 unchanged.

arm32 crossgen diffs:

Total bytes of diff: -1372 (0.00% of base)
    diff is an improvement.
Top file improvements by size (bytes):
        -592 : Microsoft.VisualBasic.dasm (-0.12% of base)
        -368 : System.Collections.Immutable.dasm (-0.05% of base)
        -196 : System.Linq.Expressions.dasm (-0.01% of base)
         -48 : System.Private.CoreLib.dasm (0.00% of base)
         -40 : System.Security.Principal.Windows.dasm (-0.04% of base)
12 total files with size differences (12 improved, 0 regressed), 118 unchanged.
Top method improvements by size (bytes):
        -120 : Microsoft.VisualBasic.dasm - Conversions:ToUShort(ref):ushort (4 methods)
        -112 : System.Collections.Immutable.dasm - SortedInt32KeyNode`1:.ctor(int,struct,ref,ref,bool):this (28 methods)
        -112 : System.Collections.Immutable.dasm - SortedInt32KeyNode`1:Mutate(ref,ref):ref:this (28 methods)
         -88 : Microsoft.VisualBasic.dasm - Conversions:ToByte(ref):ubyte (4 methods)
         -60 : Microsoft.VisualBasic.dasm - Operators:ModObject(ref,ref):ref (2 methods)
69 total methods with size differences (69 improved, 0 regressed), 142404 unchanged.

@mikedn
Copy link
Copy Markdown
Author

mikedn commented Aug 21, 2018

I wasn't after CQ improvements with this but there are a couple of small ones.

There is a trivial change that affects x64 - 64-to-32 bit narrowing casts were generating 64 bit MOVs when 32 bit would be sufficient. 32 bit MOVs do not need a REX prefix an that accounts for most of the 401 bytes improvement seen on x64.

Then there are the overflow check codegen changes. test/tst instructions are now used only when they provide some benefit, otherwise cmp is used.

Indiscriminate use of test was just making things worse, especially on ARM32:

-            movw    r2, 0xd1ff
-            movt    r2, 0xd1ff
-            tst     r1, r2
+            cmp     r1, 0x10000

On ARM some max values required for overflow checking of small int type casts (32767 and 65535) cannot be encoded in the immediate operand but fortunately they can be replaced with power of 2 values (32768 and 65536) that can be encoded due to ARM's fancy imm shifting facility.

This changes apply to xarch as well but there they don't have much of an impact on codesize due immediate operand encoding being far less restrictive.

@mikedn mikedn changed the title [WIP] Refactor integer cast codegen Refactor integer cast codegen Aug 21, 2018
@BruceForstall
Copy link
Copy Markdown

@mikedn Are you ready to have this reviewed?

cc @dotnet/jit-contrib

@mikedn
Copy link
Copy Markdown
Author

mikedn commented Sep 5, 2018

@BruceForstall Hmm, looks like I was, until it conflicted.

@mikedn
Copy link
Copy Markdown
Author

mikedn commented Sep 6, 2018

@BruceForstall Conflict fixed

@CarolEidt CarolEidt self-requested a review September 6, 2018 21:57
Copy link
Copy Markdown

@CarolEidt CarolEidt left a comment

Choose a reason for hiding this comment

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

This LGTM. Very nice refactoring.
Could we get another review @dotnet/jit-contrib ?

Copy link
Copy Markdown
Member

@AndyAyersMS AndyAyersMS left a comment

Choose a reason for hiding this comment

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

Agree, looks good.

@CarolEidt CarolEidt merged commit 748b5a0 into dotnet:master Sep 7, 2018
@mikedn mikedn deleted the cast-cg branch September 28, 2019 19:12
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants