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

[LowerTypes] Preserve rwprobes, forceable. #5051

Merged
merged 5 commits into from
Apr 27, 2023

Conversation

dtzSiFive
Copy link
Contributor

@dtzSiFive dtzSiFive commented Apr 14, 2023

Don't lower these as much as possible.

Keep the always-lower-(non-rw-)probe behavior
to workaround the memtaps / 4479 issue.

Also, if we need to lower the source operand,
re-construct/materialize it (like "Source Materialization").

This does of course mean rwprobe'ing something means it needs to be okay to preserve as an aggregate.

@dtzSiFive dtzSiFive force-pushed the experimental/dont-force-lower-reftypes branch from e8d739a to c7f2cca Compare April 14, 2023 20:59
@dtzSiFive
Copy link
Contributor Author

dtzSiFive commented Apr 14, 2023

This might be best to land after some support for ref.sub in LowerXMR, or without the ability to split up force statements (which isn't ideal anyway) even when the source operand is being expanded.

Fixed, source operand is re-built if needed for a force (but for whatever reason expanded elsewhere).
This is a little weird, but is basically "Source Materialization" re:retaining uses of the "illegal" type.

No longer split up force or release or forceable (with rwprobe result active), ever, that code is removed.

This also changes things so rwprobe's are never lowered, regardless of convention, which seems reasonable if you squint they could count as "scalars".

@dtzSiFive
Copy link
Contributor Author

Wargarbl, connections to forceable declarations get sad with this unless agg preservation is on:

https://github.com/dtzSiFive/reftype-inputs/blob/main/force_agg.fir

Gives error:

./ref_tests/force_agg.fir:26:7: error: 'hw.struct_extract' op used as connect destination
    p <= x
      ^
./ref_tests/force_agg.fir:26:7: note: see current operation: %7 = "hw.struct_extract"(%5) {field = "a"} : (!hw.struct<a: i2, b: !hw.array<3xi2>>) -> i2
./ref_tests/force_agg.fir:26:7: error: 'firrtl.strictconnect' op LowerToHW couldn't handle this operation
    p <= x
      ^
./ref_tests/force_agg.fir:26:7: note: see current operation: "firrtl.strictconnect"(%8, %1) : (!firrtl.uint<2>, !firrtl.uint<2>) -> ()

Bit of a balancing act, will think/bake this some more...

@uenoku
Copy link
Member

uenoku commented Apr 16, 2023

I think this error was because we started to reject subelement connection from HW wire PR: #4826

To fix this I guess it's sufficient to enable MergeConnection pass even when with non-aggregate preservation (currently ran only when preserveAggregate != None).

@fabianschuiki
Copy link
Contributor

Yeah there was a version of lowerConnect in the hw.wire PRs that would allow you to connect to subaccesses on the LHS, and it would basically refactor the connect to be to the whole non-subaccessed value, with an updated value on the RHS. But MergeConnection does that in a more orthogonal way, which is why it's missing on the lowerConnect side.

@dtzSiFive
Copy link
Contributor Author

Thank you both very much! I'll look into that, enabling MergeConnections does resolve that error! And appreciate the context/analysis.

@dtzSiFive dtzSiFive force-pushed the experimental/dont-force-lower-reftypes branch 2 times, most recently from 69ad6b4 to b621efd Compare April 26, 2023 02:02
@dtzSiFive
Copy link
Contributor Author

dtzSiFive commented Apr 26, 2023

Note: If MergeConnections is required for correctness (legalization), it shouldn't be gated on "disable-opts". This is not yet a concern, but should be fixed as part of landing this PR.

EDIT: Discussed in #5086, fixed in 9ed6ecf .

Copy link
Member

@uenoku uenoku left a comment

Choose a reason for hiding this comment

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

Few nits, otherwise LGTM!

Comment on lines +649 to +676
.Case<RefForceOp, RefForceInitialOp, RefSendOp, VectorCreateOp,
BundleCreateOp>([&](auto op) {
// Reconstruct the aggregate for the ref operation.
// (or vector/bundle create that were inserted.. woof.)
ImplicitLocOpBuilder b(user->getLoc(), user);

Value input =
TypeSwitch<Type, Value>(val.getType())
.template Case<FVectorType>([&](auto vecType) {
return b.createOrFold<VectorCreateOp>(vecType, mapping);
})
.template Case<BundleType>([&](auto bundleType) {
return b.createOrFold<BundleCreateOp>(bundleType, mapping);
})
.Default([&](auto _) -> Value { return {}; });
if (!input) {
user->emitError("unable to reconstruct source of type ")
<< val.getType();
return;
}
Copy link
Member

@uenoku uenoku Apr 27, 2023

Choose a reason for hiding this comment

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

I think we can use for Default as well. Default currently creates aggrgates by bitcast operations (since there was no vector/bundle_create at that time) so it would be way better to explicitly use vector/bundle_create.

Example: firtool -preserve-aggregate=1d-vec.

circuit Bar:
  module Bar:
    input a1: UInt<1>[2]
    input a2: UInt<1>[2]

    input cond: UInt<1>
    output b: UInt<1>[2]

    b <= mux(cond, a1, a2)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

As an aside: I've noticed playing with aggregates that often names become _GEN -- if we're exploding then reconstructing that would sure explain that. Unfortunately this doesn't (easily) lend itself to addressing that, but it'd be neat if so.

In your example you're showing another case where we "unevenly" lower things--here, the scalarization of the top module causes the vectors to be split and we'd prefer a vector/bundle create to recover those pieces vs bitcast.
Is that right?
(Makes lots of sense to me!)

Interesting point!! I am unsure... okay digging a little it appears this code was written before we had aggregate creation ops 😄 .
(( Depending on how you look at the purpose of LowerTypes, I was concerned the mechanism for materializing the aggregate might be important -- for claims like "No FIRRTL op will still take an aggregate" or if the story for foreign ops made more sense giving it an opaque blob of bits directly. In that sense this was a little suboptimal but I didn't have a better story other than rejecting. ))

Anyway a few conversations later I think this makes sense. I'll change it separately.

cc #3989 which might be useful to revive here re:neater IR but not 100% as haven't gone through that carefully.

Don't lower these as much as possible.

Keep the always-lower-(non-rw-)probe behavior
to workaround the memtaps / 4479 issue.

Also, if we need to lower the source operand
to a force statement, split it up as well.

Some sharp corners here re:references to non-passive things,
can be handled similarly to the force situation-- just
reconstruct or cat+cast the elements back.
If not splitting the force, reconstruct the source operands
from the expanded elements.

This is similar to source materialization in MLIR's conversion.
Leave the boolean simplify thing along for note re:memtaps issue.
Undo change that used the input argument, which was motivated by
ensuring a ref.send of a non-passive would be lowered since
we always lower non-passive types.

Instead, always look at the ref result for determining this,
so that ref chains are consistent.

We can rebuild the aggregate into the send as needed.

As-is we always expand read-only references anyway,
so this just ensures the send is also split apart
using same logic splitting up ref.define/etc of probe's.
@dtzSiFive dtzSiFive force-pushed the experimental/dont-force-lower-reftypes branch from b621efd to 12affab Compare April 27, 2023 19:04
@dtzSiFive
Copy link
Contributor Author

Thank you all very much for the feedback and review! Will make the suggested change re:improving other paths in an immediate follow-up.

(also makes me happy to not make this so specific to references... 👍)

@dtzSiFive dtzSiFive merged commit cacff52 into llvm:main Apr 27, 2023
@dtzSiFive dtzSiFive deleted the experimental/dont-force-lower-reftypes branch April 27, 2023 19:32
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.

3 participants