-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
(byte[], (int, int))
struct spilled onto the stack when it doesn't have to
#91517
Comments
Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch Issue DetailsDescriptionGiven a struct with field layout Configuration
Regression?No. Steps to reproduce
AnalysisGiven methods accepting a struct of layout [MethodImpl(MethodImplOptions.AggressiveOptimization)]
private static U8String StripSpace(U8String str)
{
return str.Remove(' ');
}
...
partial readonly struct U8String
{
public U8String Remove(char value) => U8Manipulation.Remove(this, value);
} .NET currently emits: ; Assembly listing for method Program:StripSpace(U8Primitives.U8String):U8Primitives.U8String (Tier1)
G_M000_IG01: ;; offset=0x0000
stp fp, lr, [sp, #-0x40]!
mov fp, sp
str xzr, [fp, #0x20] //
str xzr, [fp, #0x10] //
stp x0, x1, [fp, #0x30] // ,
G_M000_IG02: ;; offset=0x0014
ldp x0, x1, [fp, #0x30] // ,
mov w2, #32
movz x3, #0xE970
movk x3, #0x4C4 LSL #16
movk x3, #1 LSL #32
ldr x3, [x3]
blr x3
stp x0, x1, [fp, #0x10] // ,
G_M000_IG03: ;; offset=0x0034
ldp x0, x1, [fp, #0x10]
stp x0, x1, [fp, #0x20]
G_M000_IG04: ;; offset=0x003C
ldp x0, x1, [fp, #0x20] // ,
G_M000_IG05: ;; offset=0x0040
ldp fp, lr, [sp], #0x40
ret lr
; Total bytes of code 72 As we can see, there are (unnecessary) stores and loads to/from stack of the struct. If my understanding is correct, they can be omitted: G_M000_IG01: ;; offset=0x0000
stp fp, lr, [sp, #-0x40]!
mov fp, sp
G_M000_IG02: ;; offset=0x0014
mov w2, #32
movz x3, #0xE970
movk x3, #0x4C4 LSL #16
movk x3, #1 LSL #32
ldr x3, [x3]
blr x3 ; sets x0, x1 regs which we do not need to store from/load to
G_M000_IG03: ;; offset=0x0040
ldp fp, lr, [sp], #0x40
ret lr
|
(byte[], (int, int))
struct spilled onto the stack when it doesn't have to
cc @jakobbotsch. |
This is sort of a long-standing issue -- the JIT does not have a first class representation that allows it to keep multiple struct fields in a single register, which is sort of what would be required here. Currently we are only able to keep multireg args in registers if the fields map cleanly into the registers (so e.g. Physical promotion might be able to handle this case with some enhancements:
|
Description
Given a struct with field layout
(byte[], (int, int))
, it appears that such struct is spilled onto the stack in many situations where it could have been kept in registers entirely on platforms with ABI supporting multi-reg returns (e.g. SysV orosx-arm64
).Configuration
Regression?
No.
Steps to reproduce
git clone --recurse-submodules https://github.com/neon-sunset/U8StrRepro
)cd U8StrRepro/Repro1
DOTNET_JitDisasm='StripSpace' dotnet run -c release
Analysis
Given methods accepting a struct of layout
(byte[], (int, int))
:.NET currently emits:
As we can see, there are (unnecessary) stores and loads to/from stack of the struct. If my understanding is correct, they can be omitted:
The text was updated successfully, but these errors were encountered: