Skip to content

Wasm loop aware rpo compute last block in loop quickly#125101

Open
AndyAyersMS wants to merge 2 commits intodotnet:mainfrom
AndyAyersMS:WasmLoopAwareRpoComputeLastBlockInLoopQuickly
Open

Wasm loop aware rpo compute last block in loop quickly#125101
AndyAyersMS wants to merge 2 commits intodotnet:mainfrom
AndyAyersMS:WasmLoopAwareRpoComputeLastBlockInLoopQuickly

Conversation

@AndyAyersMS
Copy link
Member

Since Loop Aware RPO keeps loops compact, we can quickly figure out the last block in the loop in the order.

AndyAyersMS and others added 2 commits March 2, 2026 18:49
…Flow

The LaRPO guarantees loop bodies are contiguous, so the end position
of a loop starting at cursor is simply cursor + NumLoopBlocks().
This replaces the O(n) while loop that scanned forward calling
ContainsBlock per block.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings March 3, 2026 04:39
@github-actions github-actions bot added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Mar 3, 2026
@AndyAyersMS
Copy link
Member Author

@jakobbotsch PTAL
cc @dotnet/jit-contrib

Verified the fix in a local crossgen run.

@dotnet-policy-service
Copy link
Contributor

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

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR optimizes WebAssembly control-flow interval construction by leveraging the invariant that Loop-Aware RPO (LaRPO) keeps loop bodies contiguous, enabling O(1) computation of a loop’s end position in the LaRPO order.

Changes:

  • Compute loop interval end position as headerIndex + NumLoopBlocks() instead of scanning forward through the layout.
  • Add a DEBUG-only verification that the new computation matches the previous scan-based behavior.
  • Update the TODO list to remove items that are no longer applicable.

//
unsigned endCursor = cursor;
while ((endCursor < numBlocks) && loop->ContainsBlock(initialLayout[endCursor]))
unsigned endCursor = cursor + loop->NumLoopBlocks();
Copy link
Member

Choose a reason for hiding this comment

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

Would VisitLoopBlocksPostOrder work too and be even faster? NumLoopBlocks still requires iterating the full set.

Copy link
Member

Choose a reason for hiding this comment

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

Maybe not since the first block in the post order may belong to a nested loop that was visited early in the loop aware RPO. Hard to be sure at least.

Copy link
Member Author

Choose a reason for hiding this comment

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

Not sure I follow. NumLoopBlocks just does a bit vector count so ought to be fairly fast.

Copy link
Member

Choose a reason for hiding this comment

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

I was proposing implementing this as:

BasicBlock* lastBlock = nullptr;
loop->VisitLoopBlocksPostOrder([&](BasicBlock* block) { lastBlock = block; return BasicBlockVisit::Abort; });

It accesses the last block in constant time. But I am not convinced that it would be correct in all cases since it may belong to a nested loop.

Copy link
Member Author

Choose a reason for hiding this comment

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

Aha: PostOrder, not ReversePostOrder.

Copy link
Member Author

Choose a reason for hiding this comment

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

Returning a block in a nested loop would be ok. We just need to find the last block that might try and branch back to the loop head.

But I think I'll just stick with this version, it should be fast enough.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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.

3 participants