-
Notifications
You must be signed in to change notification settings - Fork 159
Add support for GHC 9.12 #2941
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
base: master
Are you sure you want to change the base?
Add support for GHC 9.12 #2941
Conversation
e0c3a9f
to
bc4cbf1
Compare
bc4cbf1
to
5b1b746
Compare
cb04227
to
80d8721
Compare
@@ -184,7 +184,7 @@ type role Signed nominal | |||
-- | |||
-- as it is not safe to coerce between different width Signed. To change the | |||
-- width, use the functions in the 'Clash.Class.Resize.Resize' class. | |||
#if MIN_VERSION_base(4,15,0) && !MIN_VERSION_base(4,17,0) | |||
#if (__GLASGOW_HASKELL__ >= 900 && __GLASGOW_HASKELL__ < 904) || __GLASGOW_HASKELL__ >= 912 |
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.
Do you have more information on what’s going on? As in, how is it failing? Could there be a GHC bug that an OPAQUE pragma isn’t being handled as it should?
Also, would it be possible to run the clash-prelude benchmark to see the effects of newtype vs data?
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.
It seems to come down to in which order GHC decides to do the seq
/cast
s.. Here is a minimal reproducer:
module Strict where
import Clash.Prelude
type Nr = Unsigned (64+4)
topEntity :: Nr -> Nr -> Vec 1 Nr
topEntity x y = let res = x + y
in res `seq` res :> Nil
Normalization log with newtype
:
topEntity after normalization:
λ(c$arg :: Unsigned (+ 64 4)) ->
λ(c$arg :: Unsigned (+ 64 4)) ->
letrec
result :: Vec 1 (Unsigned 68)
= topEntity1[GlobalId] c$arg[LocalId]
c$arg[LocalId]
in result[LocalId]
topEntity1 before normalization:
λ(x :: Unsigned (+ 64 4)) ->
λ(y :: Unsigned (+ 64 4)) ->
let
nt :: Natural
= +# @68 topEntity2[GlobalId] x[LocalId]
y[LocalId]
in case nt[LocalId] of
_ ->
Cons @(+ 0 1) @(Unsigned 68) @0
(_CO_ @(~# Natural Natural (+ 0 1) (+ 0 1)))
nt[LocalId]
((Λb ->
Nil @0 @b (_CO_ @(~# Natural Natural 0 0)))
@(Unsigned 68))
Normalization log with data
:
topEntity after normalization:
λ(c$arg :: Unsigned (+ 64 4)) ->
λ(c$arg :: Unsigned (+ 64 4)) ->
letrec
result :: Vec 1 (Unsigned 68)
= topEntity1[GlobalId] c$arg[LocalId]
c$arg[LocalId]
in result[LocalId]
topEntity1 before normalization:
λ(x :: Unsigned (+ 64 4)) ->
λ(y :: Unsigned (+ 64 4)) ->
let
res :: Unsigned 68
= +# @68 topEntity2[GlobalId] x[LocalId]
y[LocalId]
in case res[LocalId] of
U (ipv :: Natural) ->
Cons @(+ 0 1) @(Unsigned 68) @0
(_CO_ @(~# Natural Natural (+ 0 1) (+ 0 1)))
res[LocalId]
((Λb ->
Nil @0 @b (_CO_ @(~# Natural Natural 0 0)))
@(Unsigned 68))
Core with newtype
:
topEntity1_r3Mt :: Nr -> Nr -> Vec 1 (Unsigned 68)
[GblId, Arity=2, Str=<L><L>, Unf=OtherCon []]
topEntity1_r3Mt
= \ (x_a3H7 :: Nr) (y_a3H8 [OS=OneShot] :: Nr) ->
case (+ @(Unsigned 68)
$dNum_r3Mo
(x_a3H7
`cast` ((Unsigned (AddDef <64>_N <4>_N))_R
:: Unsigned (64 + 4) ~R# Unsigned 68))
(y_a3H8
`cast` ((Unsigned (AddDef <64>_N <4>_N))_R
:: Unsigned (64 + 4) ~R# Unsigned 68)))
`cast` (Clash.Sized.Internal.Unsigned.N:Unsigned <68>_N
:: Unsigned 68 ~R# Natural)
of nt_s3M1
{ __DEFAULT ->
(Clash.Sized.Vector.$b:>
@(Unsigned 68)
@0
(nt_s3M1
`cast` (Sym (Clash.Sized.Internal.Unsigned.N:Unsigned <68>_N)
:: Natural ~R# Unsigned 68))
(Clash.Sized.Vector.$WNil @(Unsigned 68)))
`cast` ((Vec (Add0L <1>_N) <Unsigned 68>_R)_R
:: Vec (0 + 1) (Unsigned 68) ~R# Vec 1 (Unsigned 68))
}
Core with data
:
topEntity1_r3Mp :: Nr -> Nr -> Vec 1 (Unsigned 68)
[GblId, Arity=2, Str=<L><L>, Unf=OtherCon []]
topEntity1_r3Mp
= \ (x_a3H2 :: Nr) (y_a3H3 [OS=OneShot] :: Nr) ->
case + @(Unsigned 68)
$dNum_r3Mk
(x_a3H2
`cast` ((Unsigned (AddDef <64>_N <4>_N))_R
:: Unsigned (64 + 4) ~R# Unsigned 68))
(y_a3H3
`cast` ((Unsigned (AddDef <64>_N <4>_N))_R
:: Unsigned (64 + 4) ~R# Unsigned 68))
of res_a3H4
{ Clash.Sized.Internal.Unsigned.U ipv_s3LU ->
(Clash.Sized.Vector.$b:>
@(Unsigned 68)
@0
res_a3H4
(Clash.Sized.Vector.$WNil @(Unsigned 68)))
`cast` ((Vec (Add0L <1>_N) <Unsigned 68>_R)_R
:: Vec (0 + 1) (Unsigned 68) ~R# Vec 1 (Unsigned 68))
}
Though I'm not sure, it seems pretty fundamental to me that we cannot support coercion/casts between types that we represent differently in hardware.
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.
Love to hear what you make of it.
You did already do a benchmark a while back: #2535. Are you asking for a 9.12 one?
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.
No, there doesn't seem to be anything we can do. Once this is merged, could you add an issue to see if we can revert back to newtypes at some later day/ghc version. Maybe we can try once again to track the actual size of Integer
and Natural
, instead of fixing it at 64.
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.
Okay, I'll make an issue. I've got some comments but I'll leave that for the replies there.
@christiaanb It seems to me this is perfectly fine behavior for any GHC, so I'd prefer to remove newtype
for every GHC release we support. Agreed?
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've added Use data for `Signed`, `Unsigned`, `Index`, and `BiSignalOut`
. I didn't add a changelog because I don't think it is a public API change.
Could you add 9.12 to the README in the GHC compatibility section as part of this PR? |
Prevents `Numbers.Strict` test case from failing
80d8721
to
141df71
Compare
GHC may insert coercions making Clash see underlying types. For the types mentioned in the commit title, this means Clash will see either a `Natural` or an `Integer`. These types are (for better or for worse) represented as machine words, potentially truncating any operations. As a concrete example, take: top :: Unsinged 68 -> Unsigned 68 -> Vec 1 (Unsigned 64) top x y = let res = x + y in res `seq` res :> Nil Translated to core, we get: λ(x :: Unsigned 68) -> λ(y :: Unsigned 68) -> let nt :: Natural = +# @68 topEntity2[GlobalId] x[LocalId] y[LocalId] in case nt[LocalId] of _ -> Cons @(+ 0 1) @(Unsigned 68) @0 (_CO_ @(~# Natural Natural (+ 0 1) (+ 0 1))) nt[LocalId] ((Λb -> Nil @0 @b (_CO_ @(~# Natural Natural 0 0))) @(Unsigned 68)) I.e., the result of `x + y` gets assinged to a binder of type `Natural`, making the calculation truncate.
141df71
to
6958d7e
Compare
@@ -77,6 +77,7 @@ Note that release branches might contain non-released patches. | |||
| 9.6 | ✔️<sup>3</sup> | ✔️<sup>3,4</sup> | ✔️<sup>3</sup> | 1.8 | ✔️ | |||
| 9.8 | ✔️ | ✔️<sup>4</sup> | ✔️ | 1.8 | ️✔️ | |||
| 9.10 | ✔️ | ✔️<sup>4</sup> | ✔️ | 1.8 | ️✔️ | |||
| 9.12 | ✔️ | ✔️<sup>4,5</sup> | ✔️<sup>5</sup> | 1.8.3 | ️✔️ |
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.
As far as I'm concerned, I'd just put "1.8" there, not the minor. The minor version isn't all that important, and so far we've only indicated the major version. I feel it's kinda implied you pick the latest minor unless there's a strong reason not to.
I also feel a check mark for something we haven't actually tested (Windows and macOS) is a bit too optimistic.
I'm inclined to keep stuff we haven't tested crossed out. If you think crossed out is too negative, maybe we need to add a question mark emoji to indicate "might or might not work, why don't you try".
Closes #2930
Still TODO:
Check copyright notices are up to date in edited filescabal run -- clash-testsuite -p VACC -p VHDL -p clash
deps
tomkUnivCo
ghc-typelits-natnormalise#88cabal run -- clash-testsuite -p Numbers -p Strict
newtype
for any GHC version?Add source for GHC 9.12 executable
commit{-# OPTIONS_GHC -Wno-deprecations #-}
fromclash-ghc/src-ghc/Clash/GHC/Util.hs