-
Notifications
You must be signed in to change notification settings - Fork 5.2k
JIT: Avoid introducing data races in RBO #78714
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
Conversation
RBO can forward sub relops into upcoming conditions. We avoid doing this if the local assigned is live out of the block, but there may still be uses between the def and the condition which could cause us to duplicate reads and introduce data races. The problem is the same as dotnet#62048, which was fixed to handle it for volatile operations. Now that we have an overapproximation of the number of SSA uses stored in their defs we can use this to handle the situation in general. This also means we no longer do the forward sub when there may be multiple uses, which makes sense from a costing perspective. Fix dotnet#78713
|
Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch Issue DetailsRBO can forward sub relops into upcoming conditions. We avoid doing this if the local assigned is live out of the block, but there may still be uses between the def and the condition which could cause us to duplicate reads and introduce data races. The problem is the same as #62048, which was fixed to handle it for volatile operations. Now that we have an overapproximation of the number of SSA uses stored in their defs we can use this to handle the situation in general. This also means we no longer do the forward sub when there may be multiple uses, which makes sense from a costing perspective. Fix #78713
|
|
This probably moves some of the regressions I'm seeing in #78698 to this PR. |
| // probably not be worth it from a profitability perspective. | ||
| // | ||
| LclSsaVarDsc* ssaDefDsc = prevTreeLclDsc->GetPerSsaData(prevTreeLHS->AsLclVarCommon()->GetSsaNum()); | ||
| if (ssaDefDsc->GetNumUses() >= 2) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Notably, this it is not a 100% fix, since we do not count composite uses.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, well that's unfortunate as I was trying to simplify the substitution that happens below.
Do we see the composite case here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is theoretically possible, though I suspect quite hard to encounter in practice.
(A reproduction would go along the lines of complex field reinterpretations s.t. we end up with LCL_FLD<parent> as the "unaccounted" use)
|
Even if we had accurate SSA counts this still does not solve the problem due to how VN is used by the optimization. For example, the following has only one use of using System;
using System.Runtime.CompilerServices;
using System.Threading;
public class Program
{
private static int _intStatic;
private static void Main()
{
for (int i = 0; i < 1; i++)
{
new Thread(() =>
{
while (true)
{
Volatile.Write(ref _intStatic, 0);
Volatile.Write(ref _intStatic, 1);
}
}).Start();
}
while (true)
{
Problem(ref _intStatic);
}
}
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)]
private static void Problem(ref int a)
{
var b = a == 0;
var c = !Id(!b);
if (!Id(!c))
{
Assert(c);
}
}
[MethodImpl(MethodImplOptions.NoInlining)]
private static void Assert(bool b)
{
if (!b)
{
throw new Exception("!!!");
}
}
private static T Id<T>(T val) => val;
}The In essence it seems like we must disallow duplicating any node that has |
|
I will close this for now and get Andy's opinion once he's back. |
RBO can forward sub relops into upcoming conditions. We avoid doing this if the local assigned is live out of the block, but there may still be uses between the def and the condition which could cause us to duplicate reads and introduce data races.
The problem is the same as #62048, which was fixed to handle it for volatile operations. Now that we have an overapproximation of the number of SSA uses stored in their defs we can use this to handle the situation in general. This also means we no longer do the forward sub when there may be multiple uses, which makes sense from a costing perspective.
Fix #78713