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

[FIRRTL] Add start of FIRRTL types lowering #157

Merged
merged 8 commits into from Nov 16, 2020
Merged

Conversation

mikeurbach
Copy link
Contributor

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.

include/circt/Dialect/FIRRTL/Dialect.h Outdated Show resolved Hide resolved
include/circt/Dialect/FIRRTL/Types.h Outdated Show resolved Hide resolved
include/circt/Dialect/FIRRTL/Types.h Outdated Show resolved Hide resolved
lib/Dialect/FIRRTL/Ops.cpp Outdated Show resolved Hide resolved
test/e2e/simple_addi.mlir Outdated Show resolved Hide resolved
test/firrtl/lower-types.mlir Show resolved Hide resolved
@mikeurbach mikeurbach marked this pull request as draft October 16, 2020 04:36
@mikeurbach
Copy link
Contributor Author

@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.

Copy link
Collaborator

@lattner lattner left a 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.

include/circt/Dialect/FIRRTL/Dialect.h Outdated Show resolved Hide resolved
include/circt/Dialect/FIRRTL/Types.h Outdated Show resolved Hide resolved
include/circt/Dialect/FIRRTL/Types.h Outdated Show resolved Hide resolved
include/circt/Dialect/FIRRTL/Types.h Outdated Show resolved Hide resolved
lib/Dialect/FIRRTL/Ops.cpp Outdated Show resolved Hide resolved
lib/Dialect/FIRRTL/LowerTypes.cpp Outdated Show resolved Hide resolved
lib/Dialect/FIRRTL/LowerTypes.cpp Outdated Show resolved Hide resolved
lib/Dialect/FIRRTL/LowerTypes.cpp Outdated Show resolved Hide resolved
lib/Dialect/FIRRTL/LowerTypes.cpp Outdated Show resolved Hide resolved
lib/Dialect/FIRRTL/LowerTypes.cpp Outdated Show resolved Hide resolved
Copy link
Contributor

@fabianschuiki fabianschuiki left a 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.

@mikeurbach mikeurbach marked this pull request as ready for review October 21, 2020 01:36
@mikeurbach
Copy link
Contributor Author

@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!

Copy link
Contributor Author

@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.

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.

lib/Dialect/FIRRTL/LowerTypes.cpp Outdated Show resolved Hide resolved
lib/Dialect/FIRRTL/LowerTypes.cpp Outdated Show resolved Hide resolved
@mikeurbach
Copy link
Contributor Author

Sorry @fabianschuiki meant to request your review on #200.

Copy link
Contributor

@fabianschuiki fabianschuiki left a 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 😃 👍

Copy link
Collaborator

@lattner lattner left a 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!

lib/Dialect/FIRRTL/PassDetails.h Show resolved Hide resolved
tools/firtool/firtool.cpp Outdated Show resolved Hide resolved
lib/Dialect/FIRRTL/Types.cpp Outdated Show resolved Hide resolved
lib/Dialect/FIRRTL/LowerTypes.cpp Outdated Show resolved Hide resolved
lib/Dialect/FIRRTL/LowerTypes.cpp Outdated Show resolved Hide resolved
lib/Dialect/FIRRTL/LowerTypes.cpp Outdated Show resolved Hide resolved
lib/Dialect/FIRRTL/LowerTypes.cpp Outdated Show resolved Hide resolved
lib/Dialect/FIRRTL/LowerTypes.cpp Outdated Show resolved Hide resolved
lib/Dialect/FIRRTL/LowerTypes.cpp Outdated Show resolved Hide resolved
lib/Dialect/FIRRTL/LowerTypes.cpp Outdated Show resolved Hide resolved
@mikeurbach
Copy link
Contributor Author

@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.

@mikeurbach
Copy link
Contributor Author

@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!

Copy link
Collaborator

@lattner lattner 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 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 :)

lib/Dialect/FIRRTL/LowerTypes.cpp Outdated Show resolved Hide resolved
lib/Dialect/FIRRTL/LowerTypes.cpp Outdated Show resolved Hide resolved
lib/Dialect/FIRRTL/LowerTypes.cpp Outdated Show resolved Hide resolved
lib/Dialect/FIRRTL/LowerTypes.cpp Outdated Show resolved Hide resolved
// Flatten any bundle types.
SmallVector<FlatBundleFieldEntry, 8> fieldTypes;
flattenBundleTypes(type, "", false, fieldTypes);

Copy link
Collaborator

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;

Copy link
Contributor Author

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.

Copy link
Contributor Author

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.

Copy link
Contributor Author

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:

  1. copy the unchanged arguments and rewrite the IR accordingly, so we can keep the same relative ordering (what is in the current revision)
  2. don't touch unchanged arguments and allow the arguments to change order in the result
  3. 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.

Copy link
Contributor Author

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.

lib/Dialect/FIRRTL/LowerTypes.cpp Outdated Show resolved Hide resolved
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.
@lattner
Copy link
Collaborator

lattner commented Nov 17, 2020

Great work @mikeurbach !

@mikeurbach
Copy link
Contributor Author

My pleasure. Thanks for all the reviews and suggestions, I really appreciate it!

@mikeurbach mikeurbach mentioned this pull request Nov 20, 2020
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.

[FIRRTL] Add support for lowering aggregate types within FIRRTL
4 participants