Skip to content

[FirRegLowering] Add limit to number of ifs generated #8313

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

Merged
merged 1 commit into from
Apr 2, 2025

Conversation

rwy7
Copy link
Contributor

@rwy7 rwy7 commented Mar 12, 2025

When lowering a firreg to SV, we structure the IR so that the register is driven from inside an if-op tree. We build this structure by examining the register's next value, translating mux ops into if-ops.

This PR sets a limit of 1024 on the number of if-ops generated for each register. While it is unlikely to hit this limit in the common case, it is possible to cause firtool to produce a very large if-op tree from a relatively small number of mux ops.

If we exceed the limit, we stop translating muxes to nested if-ops, and just drive the register with the original mux op result instead.

This PR changes the work stack to a work queue, so that we create if-ops in a breadth-first order, so that the budget is allocated evenly across the branches of the if-op tree.

@rwy7 rwy7 force-pushed the limit-if-branches branch 2 times, most recently from 35c6e44 to 7cf88ed Compare March 13, 2025 14:56
When lowering a firreg to SV, we structure the IR so that the register is
driven from inside an if-op tree. We build this structure by examining the
register's next value, translating mux ops into if-ops.

This PR sets a limit of 1024 on the number of if-ops generated for each
register.  While it is unlikely to hit this limit in the common case, it is
possible to cause firtool to produce a very large if-op tree from a relatively
small number of mux ops. The goal is to prevent firtool from hanging.

If we exceed the limit, we stop translating muxes to nested if-ops, and just
drive the register with the original mux op result instead.

This PR changes the work stack to a work queue, so that we create if-ops in a
breadth-first order, so that the budget is allocated evenly across the branches
of the if-op tree.
@rwy7 rwy7 force-pushed the limit-if-branches branch from 7cf88ed to e03ce86 Compare March 13, 2025 14:57
@rwy7 rwy7 marked this pull request as ready for review March 13, 2025 14:57
@rwy7 rwy7 added the Seq Involving the `seq` dialect label Mar 13, 2025
@rwy7 rwy7 requested a review from youngar March 20, 2025 02:43
@rwy7 rwy7 merged commit 3d2bf41 into llvm:main Apr 2, 2025
5 checks passed
@rwy7 rwy7 deleted the limit-if-branches branch April 2, 2025 16:30
KelvinChung2000 pushed a commit to KelvinChung2000/circt that referenced this pull request Apr 22, 2025
When lowering a firreg to SV, we structure the IR so that the register is
driven from inside an if-op tree. We build this structure by examining the
register's next value, translating mux ops into if-ops.

This PR sets a limit of 1024 on the number of if-ops generated for each
register.  While it is unlikely to hit this limit in the common case, it is
possible to cause firtool to produce a very large if-op tree from a relatively
small number of mux ops. The goal is to prevent firtool from hanging.

If we exceed the limit, we stop translating muxes to nested if-ops, and just
drive the register with the original mux op result instead.

This PR changes the work stack to a work queue, so that we create if-ops in a
breadth-first order, so that the budget is allocated evenly across the branches
of the if-op tree.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Seq Involving the `seq` dialect
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant