-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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: dead stores are not eliminated #13727
Comments
How often people write such code? 👀 |
Aside question: will the cpu eliminate the dead stores? |
@gfoidl I don't think CPU can eliminate those codes. |
Another case to note: public class MyType<T>
{
T value;
public MyType(T _value)
{
value = _value;
}
public T GetValue()
{
return value;
}
}
[MethodImpl(MethodImplOptions.NoInlining)]
uint deadStore()
{
char result;
result = myType.GetValue(); result = myType.GetValue(); result = myType.GetValue(); result = myType.GetValue();
result = myType.GetValue(); result = myType.GetValue(); result = myType.GetValue(); result = myType.GetValue();
result = myType.GetValue(); result = myType.GetValue(); result = myType.GetValue(); result = myType.GetValue();
result = myType.GetValue(); result = myType.GetValue(); result = myType.GetValue(); result = myType.GetValue();
return result;
} Code generated for x64: G_M30105_IG02:
488B4108 mov rax, gword ptr [rcx+8]
488BD0 mov rdx, rax
3912 cmp dword ptr [rdx], edx # <-- Not sure what this cmp are for?
488BD0 mov rdx, rax
3912 cmp dword ptr [rdx], edx
488BD0 mov rdx, rax
3912 cmp dword ptr [rdx], edx
488BD0 mov rdx, rax
3912 cmp dword ptr [rdx], edx
488BD0 mov rdx, rax
3912 cmp dword ptr [rdx], edx
488BD0 mov rdx, rax Code generated for arm64: G_M5313_IG02:
F9400400 ldr x0, [x0,#8]
AA0003E1 mov x1, x0
B940003F ldr wzr, [x1]
AA0003E1 mov x1, x0
B940003F ldr wzr, [x1]
AA0003E1 mov x1, x0
B940003F ldr wzr, [x1]
AA0003E1 mov x1, x0
B940003F ldr wzr, [x1]
AA0003E1 mov x1, x0
B940003F ldr wzr, [x1]
AA0003E1 mov x1, x0
B940003F ldr wzr, [x1] |
@EgorBo I looked at your examples in #13727 (comment) |
The example in #13727 (comment) is different since these are redundant null checks. We should be able to handle it. |
Analysis of the example in #13727 (comment). For simplicity I reduced the number of
from 16 to 3. Before null check folding optimization (in earlyProp) we have:
The optimization gets rid of the last
After CSE we end up with:
Here occurrences of Another idea is to run null check folding after CSE either instead or in addition to the existing pass. It would still have to changed in a non-trivial way to get rid of the Since there is no easy solution here, moving this issue to future. |
The design is not confirmed, but it's possible Roslyn will begin inserting implicit 'default' initialization of some struct fields in constructors as part of the "semi-auto properties" feature (dotnet/roslyn#57012). SharpLab public struct S {
public int Item { get => field; set => field = value; }
public S(int item)
{
// 'field' is only accessible by users within accessors of 'Item', so users cannot definitely assign it in the constructor.
// To ensure 'field' is definitely assigned, we implicitly assign 'default' before any user code in the constructor.
Item = item;
}
} If the IL contains 'field = default' before any user code, and the JIT inlines access of 'Item.set', it would ideally be able to then eliminate the dead store 'field = default'. |
@RikkiGibson hm.. good to know! Thanks |
All examples from the description are now optimized in .net 9.0 |
Couldn't find any related issue and decided to file it:
Codegen:
In none of these cases dead stores were eliminated.
Is it a known Value Numbering limitation?
Mono-LLVM:
category:cq
theme:optimization
skill-level:intermediate
cost:small
impact:small
The text was updated successfully, but these errors were encountered: