-
Notifications
You must be signed in to change notification settings - Fork 404
[FIRRTL] Various small reduction pattern tweaks #8984
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
fabianschuiki
commented
Sep 18, 2025
- Make the eager inliner not remove instances that are part of an NLA.
- Make the annotation remover not remove NLAs that have remaining uses after some annotations referencing it were removed.
- Make the constantifier not match on existing constants, and not replace operations that have the "inner_sym" attribute.
seldridge
left a comment
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.
LGTM
| struct EagerInliner : public OpReduction<firrtl::InstanceOp> { | ||
| struct EagerInliner : public OpReduction<InstanceOp> { |
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.
Nice to keep this tidy.
| /// Check if inlining the referenced module into the parent module would cause | ||
| /// inner symbol collisions. | ||
| bool hasInnerSymbolCollisions(FModuleOp referencedModule, | ||
| FModuleOp parentModule) { | ||
| // Get the inner symbol tables for both modules | ||
| auto &targetTable = innerSymTables->getInnerSymbolTable(referencedModule); | ||
| auto &parentTable = innerSymTables->getInnerSymbolTable(parentModule); | ||
|
|
||
| // Check if any inner symbol name in the target module already exists | ||
| // in the parent module. Return failure() if a collision is found to stop | ||
| // the walk early. | ||
| LogicalResult walkResult = targetTable.walkSymbols( | ||
| [&](StringAttr name, | ||
| const hw::InnerSymTarget &target) -> LogicalResult { | ||
| // Check if this symbol name exists in the parent module | ||
| if (parentTable.lookup(name)) { | ||
| // Collision found, return failure to stop the walk | ||
| return failure(); | ||
| } | ||
| return success(); | ||
| }); | ||
|
|
||
| // If the walk failed, it means we found a collision | ||
| return failed(walkResult); | ||
| } |
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.
I kind of like this style of eagerly exit if the reduction pattern isn't trivially applicable. This is in contrast with trying to do a bunch of work to clean this up. I think this makes sense because the inner symbols will get dropped with other reductions.
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.
Totally agreed! It's also very annoying if the pattern applies too eagerly and then leads to invalid IR in a lot of cases. That just sends the reducer into busy work rabbit holes that don't really improve the reduction. 😞
1719f3f to
b509ec6
Compare
7f021be to
59096e8
Compare
b509ec6 to
2fec994
Compare
- Make the eager inliner not remove instances that are part of an NLA. - Make the annotation remover not remove NLAs that have remaining uses after some annotations referencing it were removed. - Make the constantifier not match on existing constants, and not replace operations that have the "inner_sym" attribute.
2fec994 to
ac4f5c3
Compare
Avoid pruning unused operations that have inner symbols.
Add a helper struct that collects all inner references under a root op into a set. This is pretty pessimistic and specific to the reducer. Make use of this in the `NodeSymbolRemover` FIRRTL reduction to only remove symbols from ops if there are no references to them.
Do not externalize modules if they are involved in inner refs. Use the new `InnerRefUses` helper for this, with a few extensions.
Since most reduction patterns need information about whether an op is referenced by its symbol name or inner symbol name, also keep track of regular symbol references in `InnerSymbolUses`. This will allow us to get rid of many uses of `SymbolUserMap`.
Add a reduction pattern for the Emit dialect that simply deletes all Emit ops with high priority, since these often do not affect whether a circt-reduce test case is interesting.
Use the new `InnerSymbolUses` helper to make the OperationPruner and UnusedSymbolPruner more accurate by not deleting operations that still have references to them, which is very likely to break the IR.
Run canonicalization before CSE, since CSE will otherwise do a limited form of canonicalization that keeps finding minimal reductions, sending the reducer into a rabbit hole of minimal incremental improvements.