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

[SVExtractTestCode] Fix a bug that instance inlining doesn't update inner symbols and clone sv.bind #5679

Merged
merged 2 commits into from
Jul 26, 2023

Conversation

uenoku
Copy link
Member

@uenoku uenoku commented Jul 25, 2023

Close #5665. This commit fixes a bug that bound instances are accidentally erased. When inlining input only modules it's necessary to clone bind statements for bound instances in the module. Previously single bind op is shared by multiple instances, as a result ExportVerilog only emits a bind statement for one of them.

Copy link
Contributor

@mikeurbach mikeurbach left a comment

Choose a reason for hiding this comment

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

This looks really good to me, thanks for fixing this up!

I know there is some ongoing improvement around the interfaces/utilities for inner symbols. Not sure yet if those are ready to use yet, or if this is the way for now. @dtzSiFive what do you think?

emitWarning(oldMod.getLoc()) << "module " << oldMod.getModuleName()
<< " is an input only module but cannot "
"be inlined because a signal "
<< port.name << " is referred by names";
Copy link
Contributor

Choose a reason for hiding this comment

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

This error message is great, but I got confused at the very end with names (plural). I think it makes sense to just say referred by name, was that the intent?

emitWarning(op.getLoc())
<< "module " << oldMod.getModuleName()
<< " is an input only module but cannot be inlined because signals "
"are referred by names";
Copy link
Contributor

Choose a reason for hiding this comment

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

Same comment about names plural. Also, could you print the innerSym in the error message here like is done for ports?

// declaration with an inner symbol referred by non-bind ops (e.g. hierpath).
for (auto port : oldMod.getAllPorts()) {
if (port.sym) {
if (!port.sym.getSymName())
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
if (!port.sym.getSymName())
if (!port.sym.empty())

Copy link
Contributor

Choose a reason for hiding this comment

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

Actually, maybe leave as-is since none of this works for per-field symbols presently anyway.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yep, I added this logic to reject per-field symbols.

}
}
for (auto &op : *oldMod.getBodyBlock()) {
if (auto innerSym = op.getAttrOfType<StringAttr>("inner_sym"))
Copy link
Contributor

Choose a reason for hiding this comment

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

-> InnerSymbolOpInterface once HW uses any of the inner symbol bits. This is probably okay as-is.

if (auto innerSym = op.getAttrOfType<StringAttr>("inner_sym")) {
auto newName = b.getStringAttr(nameSpace.newName(innerSym.getValue()));
auto result = symMapping.insert({innerSym, newName});
assert(result.second);
Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, was wondering if the rename-multiple-times bugs/concerns we've encountered in ModuleInliner would apply here. Is that possible, do you know?

Copy link
Member Author

Choose a reason for hiding this comment

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

I think this is fine unless the original module doesn't contain non-unique inner symbols. Though there is no verification for IR so probably we need better messages.

// contain bound instances so create a set of inner refs used by non bind op
// in order to allow bind ops.
DenseSet<hw::InnerRefAttr> innerRefUsedByNonBindOp;
top.walk([&](hw::InnerRefUserOpInterface op) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think the majority of the current inner-ref users in HW/related dialects implement this interface "yet".
Notably BindInterfaceOp, FWIW, but also in OM and such from a quick grep. Might need to just walk everywhere for now, but probably this works "for now" as-is?

Copy link
Member Author

@uenoku uenoku Jul 26, 2023

Choose a reason for hiding this comment

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

Yep, good point. I'll just remove InnerRefUserOpInterface here.

@dtzSiFive
Copy link
Contributor

Nit:

[SVEtractTestCode]

SVExtractTestCode, FWIW

test/Dialect/SV/hw-extract-test-code.mlir Show resolved Hide resolved
static void
inlineInputOnly(hw::HWModuleOp oldMod, hw::InstanceGraph &instanceGraph,
BindTable &bindTable, SmallPtrSetImpl<Operation *> &opsToErase,
DenseSet<hw::InnerRefAttr> &innerRefUsedByNonBindOp) {
Copy link
Member

Choose a reason for hiding this comment

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

Possibly: DenseSetImpl.

Copy link
Member Author

@uenoku uenoku Jul 26, 2023

Choose a reason for hiding this comment

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

It seems DenseSetImpl cannot be used for that purpose unlike SmallVectorImpl

Comment on lines 353 to 356
emitWarning(oldMod.getLoc()) << "module " << oldMod.getModuleName()
<< " is an input only module but cannot "
"be inlined because a signal "
<< port.name << " is referred by names";
Copy link
Member

Choose a reason for hiding this comment

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

Nit: oldMod.emitWarning() should be fine as any production use should be running with -mlir-print-op-on-diagnostic=false.

Same comment elsewhere.

attr.getValue().walk([&](hw::InnerRefAttr attr) {
innerRefUsedByNonBindOp.insert(attr);
});
});
Copy link
Member

Choose a reason for hiding this comment

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

Can this be called multiple times on the same module (causing performance issues)?

Copy link
Member Author

Choose a reason for hiding this comment

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

No, it called just once for each module. It's still a bit concerning to walk the entire circuit (and its attributes) but I think there is no other way around.

@uenoku uenoku force-pushed the dev/uenoku/etc-fix-inlining branch from bedcac3 to f59b2ac Compare July 26, 2023 06:25
…ner symbols and clone sv.bind

Close #5665. This commit fixes a bug that
bound instances are accidentally erased. When inlining input only modules it's necessary
to clone bind statements for bound instances in the module. Previously single bind op is shared by multiple instances, as a result ExportVerilog only emits a bind statement for one of them.
@uenoku uenoku force-pushed the dev/uenoku/etc-fix-inlining branch from f59b2ac to ccf7168 Compare July 26, 2023 06:45
@uenoku uenoku changed the title [SVEtractTestCode] Fix a bug that instance inlining doesn't update in… [SVExtractTestCode] Fix a bug that instance inlining doesn't update in… Jul 26, 2023
@uenoku uenoku changed the title [SVExtractTestCode] Fix a bug that instance inlining doesn't update in… [SVExtractTestCode] Fix a bug that instance inlining doesn't update inner symbols and clone sv.bind Jul 26, 2023
@uenoku uenoku merged commit feebfdc into main Jul 26, 2023
5 checks passed
@uenoku uenoku deleted the dev/uenoku/etc-fix-inlining branch July 26, 2023 07:18
uenoku added a commit that referenced this pull request Jul 31, 2023
…nner symbols and clone sv.bind (#5679)

Close #5665. This commit fixes a bug that
bound instances are accidentally erased. When inlining input only modules it's necessary
to clone bind statements for bound instances in the module. Previously single bind op is
shared by multiple instances, as a result ExportVerilog only emits a bind statement for one of them.
uenoku added a commit that referenced this pull request Aug 2, 2023
…nner symbols and clone sv.bind (#5679)

Close #5665. This commit fixes a bug that
bound instances are accidentally erased. When inlining input only modules it's necessary
to clone bind statements for bound instances in the module. Previously single bind op is
shared by multiple instances, as a result ExportVerilog only emits a bind statement for one of them.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[SVExtractTestCode] Instance inlining doesn't update inner symbols and clone sv.bind
4 participants