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
[FIRRTL] Add start of FIRRTL types lowering #157
Conversation
@seldridge @lattner here is the start of lowering FIRRTL types (cc @fabianschuiki @teqdruid who were also interested). I'm pretty happy with the functionality (i.e. the test cases I was able to write), but I'm sure I have more to clean up. If you have any feedback at this point, that would be great. I've really only focused on flattening bundle types here. It's already a pretty hefty chunk of code, so I'd like to try and get this solidified, and then we can work on fleshing out more of this pass incrementally. |
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 didn't review the logic of the pass closely, but the code looks nice and clean in a quick glance. Here are some quick comments.
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.
That's super nice! Will make the FIRRTL-to-LLHD lowering so much simpler as well.
8e758aa
to
aeeb457
Compare
bbbaaf6
to
dee8a84
Compare
@lattner @seldridge I've done a round of updates from the previous feedback, and dressed up the tests. I think this should be ready for review now. Thanks! |
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 was going to add some tests for the ways this pass can error out, but now I'm not sure it is even necessary to emit an error (instead of asserting). The places I have emitError
are only possible if the fields of bundles don't line up, or the subfields weren't traversed correctly, etc. To me, it seems like these sorts of checks belong in the verifier, but I could go either way.
aeb1396
to
03aac9d
Compare
54634ed
to
79302d3
Compare
Sorry @fabianschuiki meant to request your review on #200. |
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 from the LLHD side 😃 👍
4ecc367
to
fe22dd2
Compare
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 is looking really nice, lots of minor suggestions and thoughts, but the code is very clean!
fe22dd2
to
d356a7f
Compare
@lattner your review was requested automatically, but FYI I still have work in progress. So far, I rebased master and removed the unrelated changes in the previous revision. I also went through and updated the places you had minor feedback. Now, I'm going to try and think about how to improve the data structures in order to generally simplify the pass. |
8e4dd88
to
ec3bb4c
Compare
@lattner please take another look when you get a chance. I've updated the data structures along the lines of what you were suggesting, and I've been able to simplify this pass a lot. Thanks for the push in the right direction! |
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 really awesome @mikeurbach great work. A few more comments below, but feel free to commit after you resolve them however you think best. No need for another round of review from me :)
// Flatten any bundle types. | ||
SmallVector<FlatBundleFieldEntry, 8> fieldTypes; | ||
flattenBundleTypes(type, "", false, fieldTypes); | ||
|
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.
Would it make sense to add a check to see if we are lowering an argument to itself here to avoid needlessly rewriting the IR?
Something like:
if (fieldTypes.size() == 1 && (other checks?)) return;
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.
Good point, I will try to add early exit for those cases.
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.
Actually, the reason I wasn't exiting early for the unchanged arguments was to keep the resulting arguments in the same relative order (with bundles flattened of course). I achieve this by copying unchanged arguments to the end of the argument list and rewriting the IR to use the copy.
I think the proper thing to do here is twofold: first, any time we lower a bundle argument, we should just insert the lowered values right after the original bundle in the argument list. Then, we don't need to needlessly copy/rewrite for every unchanged argument to keep the same order.
I will try to take this approach here.
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.
And now I remember why this was tricky--as we lower arguments, if we insert a flattened argument into the middle of the argument list, this may interfere with any argument attributes for the original argument that was at that index. I think it may be possible, but the bookkeeping gets more complicated.
So I see three options:
- copy the unchanged arguments and rewrite the IR accordingly, so we can keep the same relative ordering (what is in the current revision)
- don't touch unchanged arguments and allow the arguments to change order in the result
- insert new arguments into the middle of the argument list and figure out the bookkeeping to keep track of argument attributes
I think 2) is not what we want. It would violate the principle of least surprise, at least for me. For example, output ports would often be arguments at the end of the list, and could get shifted to the middle if some inputs were lowered but outputs were not.
It seems like 3) is the best option in the long run since it would avoid some unnecessary work.
However, I think 1) is sufficient for now. It's doing some unnecessary work in some cases, but the implementation is straightforward and the results are not surprising. I think I'll land this as-is, and if it is worth pursing 3) (or some other approach), I can address it in a follow-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 landed this pass and opened this issue to track this specific concern for follow up: #247.
This adds a new pass to lower FIRRTL types, initially focused on bundle types. This flattens bundle types in module and instance ports, and deals with the flattened values in subfield and connect operations. Starts to resolve #123.
* New subfields are created immediately after the new instance * They are stored in the central loweredBundleValues map * Subfields of instances are mapped directly to the new subfields
Now, everything is stored in one mapping. There is no difference between how to handle subfields of block args, other subfields, and instances.
Before, it used a DenseMap of Value to StringMap of Value, which was not ideal for having many small string maps. Now, it uses a DenseMap of pairs of (Value, Identifier) to map to Values.
This pipeline can now lower FIRRTL with bundle types to RTL.
ec3bb4c
to
5f1cf57
Compare
Great work @mikeurbach ! |
My pleasure. Thanks for all the reviews and suggestions, I really appreciate it! |
This adds a new pass to lower FIRRTL types, initially focused on
bundle types. This flattens bundle types in module and instance
ports, and deals with the flattened values in subfield and connect
operations. Starts to resolve #123.