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: Sparse conditional propagation in value numbering #94563

Merged

Conversation

jakobbotsch
Copy link
Member

@jakobbotsch jakobbotsch commented Nov 9, 2023

Utilize the fact that VN is able to decide whether many non-trivial branches will be taken or not taken to prove basic blocks dynamically unreachable. Take this into account when building PHIs.

Fix #94559

There are some additional improvements to make:

  1. I'm not sure if we see statically unreachable blocks, but if we do, we should try to handle them similarly. Currently it seems like we pessimize PHIs if these are present.
  2. We should fully skip VN'ing the blocks that are proven unreachable, but downstream phases currently are not prepared to handle that. We should maybe eliminate the proven unreachable blocks as part of VN to make sure downstream phases see a consistent view. (This is also necessary to make VN correct on its own when it is utilizing liberal VNs to prove the reachability.)
  3. I couldn't figure out how to look up the predecessor corresponding to a memory PHI arg, so currently we do not do this for memory PHIs. Adding the pred blocks for these and making use of them has almost no diffs, so doesn't seem worth it.

Codegen of the example from #94559 before:

       mov      rcx, 0xD1FFAB1E      ; ubyte[]
       mov      edx, 128
       call     CORINFO_HELP_NEWARR_1_VC
       add      rax, 16
       mov      ecx, 128
       xor      rdx, rdx
       test     ecx, ecx
       cmovne   rdx, rax
       mov      bword ptr [rsp+0x20], rdx
       mov      rcx, rdx
       call     [Program:DoSomething(ulong)]
       xor      eax, eax
       mov      bword ptr [rsp+0x20], rax

Codegen after:

       mov      rcx, 0xD1FFAB1E      ; ubyte[]
       mov      edx, 128
       call     CORINFO_HELP_NEWARR_1_VC
       add      rax, 16
       mov      rcx, rax
       mov      bword ptr [rsp+0x20], rcx
       call     [Program:DoSomething(ulong)]
       xor      eax, eax
       mov      bword ptr [rsp+0x20], rax

Utilize the fact that VN is able to decide whether many non-trivial
branches will be taken or not taken to prove basic blocks dynamically
unreachable. Take this into account when building PHIs.

Fix dotnet#94559
@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 Nov 9, 2023
@ghost ghost assigned jakobbotsch Nov 9, 2023
@ghost
Copy link

ghost commented Nov 9, 2023

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

Issue Details

Utilize the fact that VN is able to decide whether many non-trivial branches will be taken or not taken to prove basic blocks dynamically unreachable. Take this into account when building PHIs.

Fix #94559

There are some additional improvements to make:

  1. I'm not sure if we see statically unreachable blocks, but if we do, we should try to handle them similarly. Currently it seems like we pessimize PHIs if these are present.
  2. We should fully skip VN'ing the blocks that are proven unreachable, but downstream phases currently are not prepared to handle that. We should maybe eliminate the proven unreachable blocks as part of VN to make sure downstream phases see a consistent view.
Author: jakobbotsch
Assignees: -
Labels:

area-CodeGen-coreclr

Milestone: -

@jakobbotsch
Copy link
Member Author

It would also be possible to add some of RBO's smarts in here to make it even stronger, of course at a TP cost.

@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

/azp run Fuzzlyn

Copy link

Azure Pipelines successfully started running 1 pipeline(s).

The assert that the phi loop found a phi could be hit in cases where a
block had a statically unreachable pred. In that case SSA may not have
added any PHI arg for that pred, and if we then proved all other preds
unreachable, we would end up with no VN for a phi. Fix it by using the
value of the last phi arg in those cases.
@jakobbotsch
Copy link
Member Author

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

Copy link

Azure Pipelines successfully started running 3 pipeline(s).

@jakobbotsch
Copy link
Member Author

cc @dotnet/jit-contrib PTAL @AndyAyersMS

Diffs. Mostly dominated by tests, in the real world I think the PHI disambiguation that RBO does handles most cases already. However, doing it this way in VN is naturally more precise. I want to try moving some of RBO's smarts to VN (at least the simple dominator checks).

TP regressions weren't as bad as I expected, so I didn't bother to do more work to optimize the TP. I also ended up not doing the work to switch to a precomputed RPO. I still want to do that, but as a follow-up.

@jakobbotsch jakobbotsch marked this pull request as ready for review November 10, 2023 09:31
continue;
}

JITDUMP(" ..but it looks like all preds are unreachable, so we are using it anyway\n");
Copy link
Member

Choose a reason for hiding this comment

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

Maybe add a comment that since we're quite sure this block is unreachable it's ok to use a somewhat arbitrary VN for the PHI? Can add it later if you're going to tweak nearby code again soon (for rbo say).

Copy link
Member Author

Choose a reason for hiding this comment

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

Will do that in the follow-up.

Copy link
Member

@AndyAyersMS AndyAyersMS left a comment

Choose a reason for hiding this comment

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

Changes LGTM.

If you did switch over to the new RPO you could identify statically unreachable blocks. But maybe these are rare. At any rate rather than tolerate them here we probably should get rid of them before (or just after) we build SSA; it has identified these blocks too.

@jakobbotsch
Copy link
Member Author

If you did switch over to the new RPO you could identify statically unreachable blocks.

Yeah, I'll make use of that in the follow-up.

@github-actions github-actions bot locked and limited conversation to collaborators Dec 11, 2023
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.

Pinning ROS with known length causes unnecessary code generation.
2 participants