-
Notifications
You must be signed in to change notification settings - Fork 298
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
[HW] Disallow duplicate field names in HW aggregate types #6225
Conversation
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.
Approach looks good! Some thoughts in the review.
lib/Dialect/HW/HWTypes.cpp
Outdated
llvm::StringSet<> nameSet; | ||
return p.parseCommaSeparatedList( | ||
mlir::AsmParser::Delimiter::LessGreater, [&]() -> ParseResult { | ||
std::string name; | ||
Type type; | ||
if (p.parseKeywordOrString(&name) || p.parseColon() || | ||
p.parseType(type)) | ||
return failure(); | ||
if (!nameSet.insert(name).second) | ||
return p.emitError(p.getCurrentLocation(), | ||
"duplicate field name \'" + name + "\'"); |
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.
Checking this during parsing and verification results means the check has to be duplicated. Is the error just as good if you ignore the parsing check and wait for the verifier to blow up?
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 originally just did the verify method. It does the trick, but a failure there will dump a full stack trace, which I found too verbose and somewhat intimidating. 😄
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.
Fair. One thing you can do to further improve this is to use a better location for the error. Currently the error looks like:
# circt-opt Foo.mlir
Foo.mlir:2:65: error: duplicate field name 'foo'
%0 = hw.struct_create (%a, %b) : !hw.struct<foo: i8, foo: i8, foo: i8>
^
Foo.mlir:2:74: error: duplicate field name 'foo'
%0 = hw.struct_create (%a, %b) : !hw.struct<foo: i8, foo: i8, foo: i8>
^
If you use:
diff --git a/lib/Dialect/HW/HWTypes.cpp b/lib/Dialect/HW/HWTypes.cpp
index e89d9b3ab..0c22baef2 100644
--- a/lib/Dialect/HW/HWTypes.cpp
+++ b/lib/Dialect/HW/HWTypes.cpp
@@ -248,13 +248,14 @@ static ParseResult parseFields(AsmParser &p,
mlir::AsmParser::Delimiter::LessGreater, [&]() -> ParseResult {
std::string name;
Type type;
+
+ auto fieldLoc = p.getCurrentLocation();
if (p.parseKeywordOrString(&name) || p.parseColon() ||
p.parseType(type))
return failure();
if (!nameSet.insert(name).second) {
- p.emitError(p.getCurrentLocation(),
- "duplicate field name \'" + name + "\'");
+ p.emitError(fieldLoc, "duplicate field name \'" + name + "\'");
// Continue parsing to print all duplicates, but make sure to error
// eventually
hasDuplicateName = true;
You get:
# circt-opt Foo.mlir
Foo.mlir:2:58: error: duplicate field name 'foo'
%0 = hw.struct_create (%a, %b) : !hw.struct<foo: i8, foo: i8, foo: i8>
^
Foo.mlir:2:67: error: duplicate field name 'foo'
%0 = hw.struct_create (%a, %b) : !hw.struct<foo: i8, foo: i8, foo: i8>
^
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
Nice improvement, thanks!
Thanks a lot for the review. I'll get the commit changing the StructExtract/Inject operations PR ready next week, assuming there is no specific reason to keep the reference by-name. |
Prevent the creation of HW struct/union types containing multiple fields of the same name to avoid ambiguities.
hw.struct_extract
,hw.struct_inject
andhw.union_extract
refer to their respective field by name. However, field names of structs and union types are currently not enforced to be unique. This can cause ambiguities, e.g.:This PR prevents the creation of HW aggregate types with duplicate field names.
As @seldridge pointed out to me, the FIRRTL dialect refers to subfields by index rather than by name. I've prepared a follow-up commit adopting this for StructExtract and StructInject ops. Allowing ambiguous names in structs is probably not a good idea either way. But it should be marginally more efficient, as it avoids iterating over the field names to find the matching one.