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

HandshakeToFIRRTL should respect FIRRTL requiring classic SSA def-before-use #534

Closed
mikeurbach opened this issue Jan 29, 2021 · 9 comments
Assignees
Labels
bug Something isn't working Handshake

Comments

@mikeurbach
Copy link
Contributor

mikeurbach commented Jan 29, 2021

The following psuedo-IR can be produced by HandshakeToFIRRTL, passes the verifier, but will crash the LowerTypes pass:

%0 = firrtl.instance ...
firrtl.connect %0, %1
%1 = firrtl.instance ...

The actual test case I have is quite complex, and I'm trying to reduce it to something we can realistically put in a unit test.

The solution quick fix seems pretty clear: instead of processing every operation in order in the LowerTypes runOnOperation function, just track the connects to process, and take a second pass to actually process them. I've implemented this already, and will share a PR once I've reduced a reasonable test case.

@mikeurbach mikeurbach added bug Something isn't working FIRRTL Involving the `firrtl` dialect labels Jan 29, 2021
@mikeurbach mikeurbach self-assigned this Jan 29, 2021
@seldridge
Copy link
Member

seldridge commented Jan 29, 2021

Interesting... Is that supposed to be legal given that it's a use before def of an SSA value?

The SFC disallows use before def like this:

circuit Foo:
  module Foo:
    input a: UInt<1>
    output b: UInt<1>

    x <= a
    wire x: UInt<1>
    b <= x
firrtl -i Foo.fir
# Exception in thread "main" firrtl.passes.CheckHighFormLike$UndeclaredReferenceException: : [module Foo] Reference x is not declared.

But, interestingly, CIRCT will allow the equivalent MLIR input. 🤔

My gut is that this should be a hard error and we should fix this in HandshakeToFIRRTL so it doesn't emit this style of code.

@mikeurbach
Copy link
Contributor Author

mikeurbach commented Jan 29, 2021

Since Handshake supports Graph regions, it is natural to use values before they are defined. The HandshakeToFIRRTL pass just loops over the ops in order as it generates FIRRTL, so situations like this can arise. I guess we could have HandshakeToFIRRTL generate all the connects at the end, kind of like what was discussed here in the context of RTL/SV: #438.

It's not up to me if it should be a requirement that FIRRTL modules enforce definitions before use, so I'll leave it to the FIRRTL owners. That said, the quick fix for this within LowerTypes is simple, and I've already implemented it, so I'll make a PR anyway. If you ultimately decide this IR shouldn't be valid, I can update the HandshakeToFIRRTL pass to resolve the impedance mismatch between Graph and SSA regions.

mikeurbach added a commit that referenced this issue Jan 29, 2021
It is currently valid for FIRRTL to contain ops that use values before
they are defined. This is being discussed in
#534, but for the meantime, this
fixes the LowerTypes pass to handle such situations.
@lattner
Copy link
Collaborator

lattner commented Jan 30, 2021

I don't think the firrtl dialect should support this, it should require classic def-before-use SSA-style dominance. The RTL dialect should support more flexible graph-style constructs. LowerToRTL (as one example) won't work with graph style FIRRTL IR.

@lattner
Copy link
Collaborator

lattner commented Jan 30, 2021

This is easy enough to fix, we should remove this from FModuleOp:

  // Implement RegionKindInterface.
    static RegionKind getRegionKind(unsigned index) { return RegionKind::Graph;}

And remove the RegionKindInterface trait.

Rationale: FIRRTL is really a part of the Chisel stack, and it doesn't need graph support. We should implement most of the interesting logic in CIRCT on the RTL dialect, and keep the FIRRTL lowering stuff as simple as possible. I'd recommend Handshake lowering to eventually move to targeting RTL directly as it gets more mature.

@mikeurbach
Copy link
Contributor Author

Sounds good to me. This is really a HandshakeToFIRRTL issue then.

@mikeurbach mikeurbach added Handshake and removed FIRRTL Involving the `firrtl` dialect labels Jan 30, 2021
@mikeurbach mikeurbach changed the title LowerTypes fails to lower connects when the connect happens before the arguments are defined. HandshakeToFIRRTL should respect FIRRTL requiring classic SSA def-before-use Jan 30, 2021
lattner added a commit that referenced this issue Jan 30, 2021
This matches the expectation of the SFC compiler, and LowerTypes/LowerToRTL
require this.

This patch xfails the HandshakeToFIRRTL/test_load.mlir test, which is tracked
in Issue #534.
@lattner
Copy link
Collaborator

lattner commented Jan 30, 2021

Thanks Mike, I changed the FIRRTL dialect to correctly enforce this in bf56ef1. This broke HandshakeToFIRRTL/test_load.mlir which I xfailed. I looked into it, but didn't see an obvious solution. I hope that is ok, if not, lemme know and I'll be happy to revert this for now.

@hanchenye
Copy link
Member

Thanks @lattner, the change in bf56ef1 makes sense to me. I just created a patch for fixing the failed test case.

@hanchenye
Copy link
Member

Done in #537

@lattner
Copy link
Collaborator

lattner commented Feb 21, 2021

thx!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working Handshake
Projects
None yet
Development

No branches or pull requests

4 participants