Repository navigation
[RyuJit] Stackspace reservation is for pre-optimized code #7279
Copy link
Copy link
Closed
Labels
area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMICLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMIenhancementProduct code improvement that does NOT require public API changes/additionsProduct code improvement that does NOT require public API changes/additionsoptimizationtenet-performancePerformance related issuePerformance related issue
Milestone
Description
Optimized code reserves stack space for pre-optimized stack
(See also https://github.com/dotnet/coreclr/issues/9068 which I imagine should produce identical output; but produces very different output)
e.g. The following code reserves 1000 bytes of stack even though it only uses registers
; Lcl frame size = 1000
G_M27581_IG01:
4881ECE8030000 sub rsp, 0x3E8 // 1000 bytes
Code
[MethodImpl(MethodImplOptions.NoInlining)]
private static byte OneSpan(byte[] array)
{
var span = new Span<byte>(array);
span = span.Slice(1);
span = span.Slice(1);
span = span.Slice(1);
span = span.Slice(1);
span = span.Slice(1);
span = span.Slice(1);
span = span.Slice(1);
span = span.Slice(1);
span = span.Slice(1);
span = span.Slice(1);
span = span.Slice(1);
span = span.Slice(1);
span = span.Slice(1);
span = span.Slice(1);
span = span.Slice(1);
span = span.Slice(1);
span = span.Slice(1);
span = span.Slice(1);
span = span.Slice(1);
span = span.Slice(1);
span = span.Slice(1);
span = span.Slice(1);
span = span.Slice(1);
span = span.Slice(1);
span = span.Slice(1);
span = span.Slice(1);
span = span.Slice(1);
span = span.Slice(1);
span = span.Slice(1);
span = span.Slice(1);
return span[0];
}Asm produced
;
; Lcl frame size = 1000
G_M27581_IG01:
4881ECE8030000 sub rsp, 0x3E8
G_M27581_IG02:
4885C9 test rcx, rcx
0F8468010000 je G_M27581_IG36
G_M27581_IG03:
8B4108 mov eax, dword ptr [rcx+8]
83F801 cmp eax, 1
0F8263010000 jb G_M27581_IG37
G_M27581_IG04:
FFC8 dec eax
83F801 cmp eax, 1
0F8262010000 jb G_M27581_IG38
G_M27581_IG05:
FFC8 dec eax
83F801 cmp eax, 1
0F8261010000 jb G_M27581_IG39
G_M27581_IG06:
FFC8 dec eax
83F801 cmp eax, 1
0F8260010000 jb G_M27581_IG40
G_M27581_IG07:
FFC8 dec eax
83F801 cmp eax, 1
0F825F010000 jb G_M27581_IG41
G_M27581_IG08:
FFC8 dec eax
83F801 cmp eax, 1
0F825E010000 jb G_M27581_IG42
G_M27581_IG09:
FFC8 dec eax
83F801 cmp eax, 1
0F825D010000 jb G_M27581_IG43
G_M27581_IG10:
FFC8 dec eax
83F801 cmp eax, 1
0F825C010000 jb G_M27581_IG44
G_M27581_IG11:
FFC8 dec eax
83F801 cmp eax, 1
0F825B010000 jb G_M27581_IG45
G_M27581_IG12:
FFC8 dec eax
83F801 cmp eax, 1
0F825A010000 jb G_M27581_IG46
G_M27581_IG13:
FFC8 dec eax
83F801 cmp eax, 1
0F8259010000 jb G_M27581_IG47
G_M27581_IG14:
FFC8 dec eax
83F801 cmp eax, 1
0F8258010000 jb G_M27581_IG48
G_M27581_IG15:
FFC8 dec eax
83F801 cmp eax, 1
0F8257010000 jb G_M27581_IG49
G_M27581_IG16:
FFC8 dec eax
83F801 cmp eax, 1
0F8256010000 jb G_M27581_IG50
G_M27581_IG17:
FFC8 dec eax
83F801 cmp eax, 1
0F8255010000 jb G_M27581_IG51
G_M27581_IG18:
FFC8 dec eax
83F801 cmp eax, 1
0F8254010000 jb G_M27581_IG52
G_M27581_IG19:
FFC8 dec eax
83F801 cmp eax, 1
0F8253010000 jb G_M27581_IG53
G_M27581_IG20:
FFC8 dec eax
83F801 cmp eax, 1
0F8252010000 jb G_M27581_IG54
G_M27581_IG21:
FFC8 dec eax
83F801 cmp eax, 1
0F8251010000 jb G_M27581_IG55
G_M27581_IG22:
FFC8 dec eax
83F801 cmp eax, 1
0F8250010000 jb G_M27581_IG56
G_M27581_IG23:
FFC8 dec eax
83F801 cmp eax, 1
0F824F010000 jb G_M27581_IG57
G_M27581_IG24:
FFC8 dec eax
83F801 cmp eax, 1
0F824E010000 jb G_M27581_IG58
G_M27581_IG25:
FFC8 dec eax
83F801 cmp eax, 1
0F824D010000 jb G_M27581_IG59
G_M27581_IG26:
FFC8 dec eax
83F801 cmp eax, 1
0F824C010000 jb G_M27581_IG60
G_M27581_IG27:
FFC8 dec eax
83F801 cmp eax, 1
0F824B010000 jb G_M27581_IG61
G_M27581_IG28:
FFC8 dec eax
83F801 cmp eax, 1
0F824A010000 jb G_M27581_IG62
G_M27581_IG29:
FFC8 dec eax
83F801 cmp eax, 1
0F8249010000 jb G_M27581_IG63
G_M27581_IG30:
FFC8 dec eax
83F801 cmp eax, 1
0F8248010000 jb G_M27581_IG64
G_M27581_IG31:
FFC8 dec eax
83F801 cmp eax, 1
0F8247010000 jb G_M27581_IG65
G_M27581_IG32:
FFC8 dec eax
83F801 cmp eax, 1
0F8246010000 jb G_M27581_IG66
G_M27581_IG33:
FFC8 dec eax
85C0 test eax, eax
0F8646010000 jbe G_M27581_IG67
G_M27581_IG34:
488D4108 lea rax, bword ptr [rcx+8]
4883C026 add rax, 38
0FB600 movzx rax, byte ptr [rax]
G_M27581_IG35:
4881C4E8030000 add rsp, 0x3E8
C3 ret
G_M27581_IG36:
33C9 xor ecx, ecx
E871F0FFFF call ThrowHelper:ThrowArgumentNullException(int)
G_M27581_IG37:
B902000000 mov ecx, 2
E8B7F0FFFF call ThrowHelper:ThrowArgumentOutOfRangeException(int)
G_M27581_IG38:
B902000000 mov ecx, 2
E8ADF0FFFF call ThrowHelper:ThrowArgumentOutOfRangeException(int)
G_M27581_IG39:
B902000000 mov ecx, 2
E8A3F0FFFF call ThrowHelper:ThrowArgumentOutOfRangeException(int)
G_M27581_IG40:
B902000000 mov ecx, 2
E899F0FFFF call ThrowHelper:ThrowArgumentOutOfRangeException(int)
G_M27581_IG41:
B902000000 mov ecx, 2
E88FF0FFFF call ThrowHelper:ThrowArgumentOutOfRangeException(int)
G_M27581_IG42:
B902000000 mov ecx, 2
E885F0FFFF call ThrowHelper:ThrowArgumentOutOfRangeException(int)
G_M27581_IG43:
B902000000 mov ecx, 2
E87BF0FFFF call ThrowHelper:ThrowArgumentOutOfRangeException(int)
G_M27581_IG44:
B902000000 mov ecx, 2
E871F0FFFF call ThrowHelper:ThrowArgumentOutOfRangeException(int)
G_M27581_IG45:
B902000000 mov ecx, 2
E867F0FFFF call ThrowHelper:ThrowArgumentOutOfRangeException(int)
G_M27581_IG46:
B902000000 mov ecx, 2
E85DF0FFFF call ThrowHelper:ThrowArgumentOutOfRangeException(int)
G_M27581_IG47:
B902000000 mov ecx, 2
E853F0FFFF call ThrowHelper:ThrowArgumentOutOfRangeException(int)
G_M27581_IG48:
B902000000 mov ecx, 2
E849F0FFFF call ThrowHelper:ThrowArgumentOutOfRangeException(int)
G_M27581_IG49:
B902000000 mov ecx, 2
E83FF0FFFF call ThrowHelper:ThrowArgumentOutOfRangeException(int)
G_M27581_IG50:
B902000000 mov ecx, 2
E835F0FFFF call ThrowHelper:ThrowArgumentOutOfRangeException(int)
G_M27581_IG51:
B902000000 mov ecx, 2
E82BF0FFFF call ThrowHelper:ThrowArgumentOutOfRangeException(int)
G_M27581_IG52:
B902000000 mov ecx, 2
E821F0FFFF call ThrowHelper:ThrowArgumentOutOfRangeException(int)
G_M27581_IG53:
B902000000 mov ecx, 2
E817F0FFFF call ThrowHelper:ThrowArgumentOutOfRangeException(int)
G_M27581_IG54:
B902000000 mov ecx, 2
E80DF0FFFF call ThrowHelper:ThrowArgumentOutOfRangeException(int)
G_M27581_IG55:
B902000000 mov ecx, 2
E803F0FFFF call ThrowHelper:ThrowArgumentOutOfRangeException(int)
G_M27581_IG56:
B902000000 mov ecx, 2
E8F9EFFFFF call ThrowHelper:ThrowArgumentOutOfRangeException(int)
G_M27581_IG57:
B902000000 mov ecx, 2
E8EFEFFFFF call ThrowHelper:ThrowArgumentOutOfRangeException(int)
G_M27581_IG58:
B902000000 mov ecx, 2
E8E5EFFFFF call ThrowHelper:ThrowArgumentOutOfRangeException(int)
G_M27581_IG59:
B902000000 mov ecx, 2
E8DBEFFFFF call ThrowHelper:ThrowArgumentOutOfRangeException(int)
G_M27581_IG60:
B902000000 mov ecx, 2
E8D1EFFFFF call ThrowHelper:ThrowArgumentOutOfRangeException(int)
G_M27581_IG61:
B902000000 mov ecx, 2
E8C7EFFFFF call ThrowHelper:ThrowArgumentOutOfRangeException(int)
G_M27581_IG62:
B902000000 mov ecx, 2
E8BDEFFFFF call ThrowHelper:ThrowArgumentOutOfRangeException(int)
G_M27581_IG63:
B902000000 mov ecx, 2
E8B3EFFFFF call ThrowHelper:ThrowArgumentOutOfRangeException(int)
G_M27581_IG64:
B902000000 mov ecx, 2
E8A9EFFFFF call ThrowHelper:ThrowArgumentOutOfRangeException(int)
G_M27581_IG65:
B902000000 mov ecx, 2
E89FEFFFFF call ThrowHelper:ThrowArgumentOutOfRangeException(int)
G_M27581_IG66:
B902000000 mov ecx, 2
E895EFFFFF call ThrowHelper:ThrowArgumentOutOfRangeException(int)
G_M27581_IG67:
E880EFFFFF call ThrowHelper:ThrowIndexOutOfRangeException()
CC int3
; Total bytes of code 689, prolog size 7 for method Program:OneSpan(ref):ubytecategory:cq
theme:register-allocator
skill-level:expert
cost:medium
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMICLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMIenhancementProduct code improvement that does NOT require public API changes/additionsProduct code improvement that does NOT require public API changes/additionsoptimizationtenet-performancePerformance related issuePerformance related issue
Activity
gkhanna79 commentedon Jan 29, 2017
CC @RussKeldorph
RussKeldorph commentedon Jan 31, 2017
@dotnet/jit-contrib
AndyAyersMS commentedon Oct 27, 2017
Considering for 2.1.
AndyAyersMS commentedon Oct 30, 2017
This doesn't seem to repro anymore (from CHK jit in REL build):
Frame size of 40 is what one would expect from a non-leaf with no locals (8 bytes for align, 32 for out arg area).
Not sure what changed things, maybe struct promotion kicking in now where it didn't before?
benaadams commentedon Oct 30, 2017
2 field Span vs 3 field Span? Was before the runtime has the two field Span so was using the three field Span. Will see if can repo
benaadams commentedon Oct 31, 2017
Still does it using a three field "SpanLike" StackSpace.cs though interestingly dotnet/coreclr#9068 and dotnet/coreclr#9066 have switched output StackSpace.asm
benaadams commentedon Oct 31, 2017
This sample now does a bunch of redundant
movsbyte OneSpantype(byte[] array)(in StackSpace.cs/StackSpace.asm)AndyAyersMS commentedon Oct 31, 2017
The register shuffling could be something similar to dotnet/coreclr#11390.
AndyAyersMS commentedon Jan 31, 2018
Just to make current status clear...
First example above is now "good":
In the second example stack space is also contained, but register shuffling is still happening, even after dotnet/coreclr#16028. Will investigate.
AndyAyersMS commentedon Feb 5, 2018
The root issues are in the complexities of LSRA preferencing -- does not look like there is an easy surgical fix and any larger change here will be quite disruptive. So moving out of 2.1.
AndyAyersMS commentedon Feb 7, 2018
Here's a kind of similar example:
generates a chain of span copies, which the jit can't coalesce:
CarolEidt commentedon Nov 14, 2020
The register shuffling may have been fixed e.g. by dotnet/coreclr/pull/19429
benaadams commentedon Nov 14, 2020
Confirmed the stack trace size and register shuffling for summary code is fixed: 7279.asm