-
Notifications
You must be signed in to change notification settings - Fork 304
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
[Calyx] Implement combinational groups #1736
Conversation
Adds a new kind of groups `CombOpGroup` for representing combinational groups. Fixes llvm#1735. - Combinational groups have no terminators. - `group_go` and `group_done` are implicitly not allowed in comb_groups since they only accept `GroupOp`s as a parent. - A new interface `GroupOpInterface` has been implemented to allow for sharing most of the logic for validation/emission of both `GroupOp` and `CombGroupOp` Some of the tests in errors.mlir were failing - i suspect this is due to changes in the ordering of how validators are applied. Modified where necessary to isolate the error that is tested for.
test/Dialect/Calyx/emit.mlir
Outdated
@@ -102,6 +106,12 @@ calyx.program { | |||
calyx.if %c1.in with @Group2 { | |||
calyx.enable @Group2 | |||
} | |||
calyx.if %c1.in { | |||
calyx.enable @Group2 |
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.
Another restriction on comb group
that I might have not mentioned: They cannot appear inside normal control operators like seq
or par
. The places where comb group
and group
may appear are disjoint.
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.
This looks super good! Two suggestions:
- Verifier check to ensure that
comb group
don't show up in normal control operators such asseq
. - Change the emitter to print
comb group
for combinational groups.
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.
@@ -522,7 +523,16 @@ void Emitter::emitGroup(GroupOp group) { | |||
}); | |||
} | |||
}; | |||
emitCalyxSection("group", emitGroupBody, group.sym_name()); | |||
auto prefix = |
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.
nit (feel free to ignore): Is TypeSwitch necessary here? Seems to produce more code than necessary.
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.
Not strictly necessary; in general i like having an error if/when a new class is added to an interface but support is yet to be added. In the given case, however, we're probably not expecting a bunch of new group ops to be added - I can remove it if you prefer.
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.
Yeah that was my thought process. A one liner for this may be
// And even simpler if you factor out "group"
StringRef prefix = isa<CombGroupOp>(op) ? "comb group" : "group";
However, do as you please. This is mostly just me nitpicking.
lib/Dialect/Calyx/CalyxOps.cpp
Outdated
if (whileOp.body().front().empty()) | ||
return whileOp.emitError() << "empty body region."; | ||
|
||
auto optGroupName = whileOp.groupName(); |
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.
Nit: Let's try to to avoid auto
unless it is extremely long (e.g. iterators) or extremely obvious (e.g. cast<MyType>()
). It makes the code more friendly for new Calyx users and future contributors. Let me know if you disagree.
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've come to pretty much using auto
for everything but built-in types, which (to me) also seems to be the general approach in much of the MLIR codebase. However, in the given case, i agree that Optional<StringRef>
here would aid in being explicit about what is going on.
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.
https://llvm.org/docs/CodingStandards.html#use-auto-type-deduction-to-make-code-more-readable
Again, I find that auto
can obfuscate code. Something that is obvious to us may not be obvious to first-time readers. I don't imagine the type of say, groupName
, will change any time soon, but perhaps I'm wrong.
@@ -297,7 +297,8 @@ struct Emitter { | |||
.template Case<IfOp, WhileOp>([&](auto op) { | |||
indent() << (isa<IfOp>(op) ? "if " : "while "); | |||
emitValue(op.cond(), /*isIndented=*/false); | |||
os << " with " << op.groupName(); | |||
if (auto groupName = op.groupName(); groupName.hasValue()) |
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 use of if statement with initializer :)
@cgyurgyik @rachitnigam Thank you for the reviews and comments; i'll go ahead an implement the things which are missing.
I initially had an explicit check for this in a verifier for circt/include/circt/Dialect/Calyx/Calyx.td Lines 73 to 75 in 438ffeb
So as i see it, adding an explicit check is just trying to do the job of the built-in checks. The only issue is that it is a bit implicit... |
This boils down to comb groups not being allowed with |
Yup! Enable cannot contain comb groups. |
This should now be handled in 0af4cb6 |
Awesome! Let me know when this PR is ready to merge and I can coordinate the merge with calyxir/calyx#635 |
Worth linking this issue if this PR closes it: #1738 |
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.
@cgyurgyik @rachitnigam Thank you for the reviews and comments; i'll go ahead an implement the things which are missing.
Also, we should verify that combinational group does not have a GroupGoOp or GroupDoneOp.
I initially had an explicit check for this in a verifier for
CombOpGroup
, however decided to leave it out since GroupGoOp and GroupDoneOp only allow aGroupOp
as parent:
circt/include/circt/Dialect/Calyx/Calyx.td
Lines 73 to 75 in 438ffeb
class CalyxGroupPort<string mnemonic, list<OpTrait> traits = []> : CalyxOp<mnemonic, !listconcat(traits, [ HasParent<"GroupOp"> So as i see it, adding an explicit check is just trying to do the job of the built-in checks. The only issue is that it is a bit implicit...
Ah yeah you're right! This should be good enough.
@@ -522,7 +523,16 @@ void Emitter::emitGroup(GroupOp group) { | |||
}); | |||
} | |||
}; | |||
emitCalyxSection("group", emitGroupBody, group.sym_name()); | |||
auto prefix = |
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.
Yeah that was my thought process. A one liner for this may be
// And even simpler if you factor out "group"
StringRef prefix = isa<CombGroupOp>(op) ? "comb group" : "group";
However, do as you please. This is mostly just me nitpicking.
lib/Dialect/Calyx/CalyxOps.cpp
Outdated
if (whileOp.body().front().empty()) | ||
return whileOp.emitError() << "empty body region."; | ||
|
||
auto optGroupName = whileOp.groupName(); |
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.
https://llvm.org/docs/CodingStandards.html#use-auto-type-deduction-to-make-code-more-readable
Again, I find that auto
can obfuscate code. Something that is obvious to us may not be obvious to first-time readers. I don't imagine the type of say, groupName
, will change any time soon, but perhaps I'm wrong.
<< "with group: " << groupName << ", which does not exist."; | ||
<< "with group '" << groupName << "', which does not exist."; | ||
|
||
if (isa<CombGroupOp>(groupOp)) |
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!!
Adds a new kind of groups
CombOpGroup
for representing combinational groups. Fixes #1735.group_go
andgroup_done
are implicitly not allowed in comb_groups since they only acceptGroupOp
s as a parent.GroupOpInterface
has been implemented to allow for sharing most of the logic for validation/emission of bothGroupOp
andCombGroupOp
Some of the tests in errors.mlir were failing - i suspect this is due to changes in the ordering of how validators are applied. Modified where necessary to isolate the error that is tested for.