Skip to content
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: Prove some cases where strength reducing to GC pointers is ok #104679

Merged
merged 4 commits into from
Jul 15, 2024

Conversation

jakobbotsch
Copy link
Member

@jakobbotsch jakobbotsch commented Jul 10, 2024

For loops iterating over arrays we often have bounds that allow us to
prove that an add recurrence formed by strength reduction will stay
within that array. In these cases we know that forming the byrefs
eagerly is ok.

For example, when strength reduction is enabled, this changes the
codegen of

private struct S
{
    public int A, B, C;
}

[MethodImpl(MethodImplOptions.NoInlining)]
private static float Sum(S[] ss)
{
    int sum = 0;
    for (int i = 0; i < ss.Length; i++)
    {
        S v = ss[i];
        sum += v.A;
        sum += v.B;
        sum += v.C;
    }

    return sum;
}

in the following way:

 G_M63518_IG03:
-       mov      r11d, 16
+       add      rcx, 16
 						;; size=4 bbWeight=0.25 PerfScore 0.06
 G_M63518_IG04:
-       lea      r8, bword ptr [rcx+r11]
+       mov      r8, rcx
        mov      r10d, dword ptr [r8]
        mov      r9d, dword ptr [r8+0x04]
        mov      r8d, dword ptr [r8+0x08]
        add      eax, r10d
        add      eax, r9d
        add      eax, r8d
-       add      r11, 12
+       add      rcx, 12
        dec      edx
        jne      SHORT G_M63518_IG04
 						;; size=31 bbWeight=4 PerfScore 34.00

which removes a live loop-carried value.

For loops iterating over arrays we often have bounds that allow us to
prove that an add recurrence formed by strength reduction will stay
within that array. In these cases we know that forming the byrefs
eagerly is ok.

For example, when strength reduction is enabled, this changes the
codegen of

```csharp
private struct S
{
    public int A, B, C;
}

[MethodImpl(MethodImplOptions.NoInlining)]
private static float Sum(S[] ss)
{
    int sum = 0;
    for (int i = 0; i < ss.Length; i++)
    {
        S v = ss[i];
        sum += v.A;
        sum += v.B;
        sum += v.C;
    }

    return sum;
}
```
in the following way:
```diff
 G_M63518_IG03:
-       mov      r11d, 16
+       add      rcx, 16
 						;; size=4 bbWeight=0.25 PerfScore 0.06
 G_M63518_IG04:
-       lea      r8, bword ptr [rcx+r11]
+       mov      r8, rcx
        mov      r10d, dword ptr [r8]
        mov      r9d, dword ptr [r8+0x04]
        mov      r8d, dword ptr [r8+0x08]
        add      eax, r10d
        add      eax, r9d
        add      eax, r8d
-       add      r11, 12
+       add      rcx, 12
        dec      edx
        jne      SHORT G_M63518_IG04
 						;; size=31 bbWeight=4 PerfScore 34.00
```
@dotnet-issue-labeler dotnet-issue-labeler bot added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Jul 10, 2024
Copy link
Contributor

Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch
See info in area-owners.md if you want to be subscribed.

@jakobbotsch
Copy link
Member Author

/azp run runtime-coreclr jitstress, runtime-coreclr libraries-jitstress

Copy link

Azure Pipelines successfully started running 2 pipeline(s).

@jakobbotsch
Copy link
Member Author

cc @dotnet/jit-contrib PTAL @AndyAyersMS

Diffs with strength reduction enabled.

Failures are #104650 and the superpmi-diffs failure is being fixed by #104725. For some reason build analysis is analyzing the superpmi-diffs runs I manually kicked off and blocking the merge on them, even though superpmi-diffs should not be monitored (cc @JulieLeeMSFT)

@jakobbotsch jakobbotsch requested a review from AndyAyersMS July 12, 2024 14:51
return false;
}

// Now see if we have a bound that guarantees that we iterate less than the
Copy link
Member

Choose a reason for hiding this comment

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

I'm a little surprised the IV step is not showing up in the calculations here, though perhaps cases where the step is not the element size are rare.

Copy link
Member Author

Choose a reason for hiding this comment

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

We do compare the element size against the IV step size above. I suppose the more general formulation would be a symbolic check like bound * iv->Step <= ARR_LENGTH(arr) * arrElemSize

@jakobbotsch
Copy link
Member Author

/ba-g Build analysis is blocking on superpmi-diffs that it normally should not care about. Remaining failures are known/infra issues.

@jakobbotsch jakobbotsch merged commit 2199c77 into dotnet:main Jul 15, 2024
119 of 132 checks passed
@jakobbotsch jakobbotsch deleted the strength-reduce-gc-pointers branch July 15, 2024 08:49
@github-actions github-actions bot locked and limited conversation to collaborators Aug 15, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants