-
Notifications
You must be signed in to change notification settings - Fork 147
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
Keep recursive and non-recursive let in Clash Core #1980
Conversation
b4bfa0f
to
af89bec
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.
According to https://ghc.gitlab.haskell.org/ghc/doc/users_guide/exts/pattern_synonyms.html you shouldn't need the PatternSynonyms
extension when you use them, only when you define them. Is that not true?
data Bind a | ||
= NonRec Id a | ||
| Rec [(Id, a)] | ||
deriving (Eq, Show, Generic, NFData, Hashable, Binary, Functor) |
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.
deriving (Eq, Show, Generic, NFData, Hashable, Binary, Functor) | |
deriving (Show, Generic, NFData, Hashable, Binary, Functor) | |
-- | Structural equivalence, not alpha equivalence | |
deriving instance Eq a => Eq (Bind a) |
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.
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 don't want to add the Structural
and Alpha
newtypes suggested in #1987 to #1990 though, I want to do that in a separate PR. #1990 significantly reduces compile times which I don't want to delay merging just because there's a further improvement on the horizon, here's master
vs #1990
christiaan@DESKTOP-O5QKI8I:~/clash-compiler$ time cabal run clash-testsuite -- -p VHDL.clash --hide-successes -j6
Up to date
All 378 tests passed (555.68s)
real 9m17.383s
user 54m37.413s
sys 2m58.446s
christiaan@DESKTOP-O5QKI8I:~/clash-compiler$ time cabal run clash-testsuite -- -p VHDL.clash --hide-successes -j6
Up to date
All 378 tests passed (410.44s)
real 6m51.604s
user 38m45.764s
sys 2m21.107s
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.
Right, but you add the eqTerm
function, and I want to add Bind
to that and remove the TODO
(since I also want to dig out the alpha / structural equality on Pat
and add it to that PR anyway we may as well do both)
af89bec
to
ccf5962
Compare
ccf5962
to
7528d28
Compare
data Bind a | ||
= NonRec Id a | ||
| Rec [(Id, a)] | ||
deriving (Eq, Show, Generic, NFData, Hashable, Binary, Functor) |
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 don't want to add the Structural
and Alpha
newtypes suggested in #1987 to #1990 though, I want to do that in a separate PR. #1990 significantly reduces compile times which I don't want to delay merging just because there's a further improvement on the horizon, here's master
vs #1990
christiaan@DESKTOP-O5QKI8I:~/clash-compiler$ time cabal run clash-testsuite -- -p VHDL.clash --hide-successes -j6
Up to date
All 378 tests passed (555.68s)
real 9m17.383s
user 54m37.413s
sys 2m58.446s
christiaan@DESKTOP-O5QKI8I:~/clash-compiler$ time cabal run clash-testsuite -- -p VHDL.clash --hide-successes -j6
Up to date
All 378 tests passed (410.44s)
real 6m51.604s
user 38m45.764s
sys 2m21.107s
7528d28
to
99e67e8
Compare
99e67e8
to
9571180
Compare
In GHC core, the difference between recursive and non-recursive binders is preserved. In Clash, this difference is not preserved in let expressions / the bindings map, which leads to sometimes needing to calculate the connected components of the bindings. However, since Letrec is used a lot (i.e. in normalization) it is painful to simply differentiate everywhere now. As a compromise, this is kept as a pattern synyonm so exsting code should work as it did before. In the future we can migrate these cases until only `Let NonRec{}` and `Let Rec{}` are used in code. Until this time, the assumption is made that `NonRec` is _always_ non-recursive, but `Rec` holds recursive and _potentially_ recursive bindings. The parts of the compiler where it is easier to change the definitions now have been changed.
9571180
to
1b3662e
Compare
In #1980, Clash started to keep the distinction between recursive and non-recursive let expressions in Core (like GHC). However, for convenience the old Letrec constructor is still used in some places to avoid the need to fix every location at once. The `inlineCleanup` transformation was one such place, however the fix is relatively simple: when there is only one binder at the end of cleanup and the original let expression was non-recursive, this binding must also be non-recursive.
In GHC core, the difference between recursive and non-recursive binders is preserved. In Clash, this difference is not preserved in let expressions / the bindings map, which leads to sometimes needing to calculate the connected components of the bindings.
However, since Letrec is used a lot (i.e. in normalization) it is painful to simply differentiate everywhere immediately. As a compromise, this is kept as a pattern synonym so existing code should work as it did before. In the future we can migrate these cases until only
Let NonRec{}
andLet Rec{}
are used in code. Until this time, the assumption is made thatNonRec
is always non-recursive, butRec
holds recursive and potentially recursive bindings.The parts of the compiler where it is easier to change the definitions now have been changed.
Still TODO: