summaryrefslogtreecommitdiff
path: root/compiler/GHC/Core
diff options
context:
space:
mode:
authorBen Gamari <ben@smart-cactus.org>2022-10-13 18:17:13 -0400
committerBen Gamari <ben@smart-cactus.org>2022-10-19 10:06:10 -0400
commit6148bd126c4602d011e7dd458288c02db1c16dc6 (patch)
tree0cebae532fef06af2374485530549273cee14bac /compiler/GHC/Core
parent1ef412dde750d4ffd01a332e555ed4503d4eda85 (diff)
downloadhaskell-wip/T22291.tar.gz
codeGen: Allow levity-polymorphic primop resultswip/T22291
Consider a program such as: ```haskell foo :: forall (lev :: Levity) (a :: TYPE (BoxedRep lev)). Addr# -> (# a #) foo x = addrToAny# x ``` While this program is accepted by the type-checker, the code generator would previously choke on it due the levity polymorphism of `foo`'s result. Specifically, `boxedRepDataCon` would fail as it was unable to determine the result's `PrimRep` while trying to identify its Cmm type: ``` <no location info>: error: panic! (the 'impossible' happened) GHC version 9.5.20220906: boxedRepDataCon [lev_ayH] Call stack: CallStack (from HasCallStack): callStackDoc, called at compiler/GHC/Utils/Panic.hs:188:37 in ghc:GHC.Utils.Panic pprPanic, called at compiler/GHC/Builtin/Types.hs:1629:9 in ghc:GHC.Builtin.Types prim_rep_fun, called at compiler/GHC/Builtin/Types.hs:1618:44 in ghc:GHC.Builtin.Types fun, called at compiler/GHC/Types/RepType.hs:615:5 in ghc:GHC.Types.RepType runtimeRepPrimRep, called at compiler/GHC/Builtin/Types.hs:1660:20 in ghc:GHC.Builtin.Types prim_rep_fun, called at compiler/GHC/Builtin/Types.hs:1655:64 in ghc:GHC.Builtin.Types fun, called at compiler/GHC/Types/RepType.hs:615:5 in ghc:GHC.Types.RepType runtimeRepPrimRep, called at compiler/GHC/Types/RepType.hs:585:5 in ghc:GHC.Types.RepType kindPrimRep, called at compiler/GHC/Types/RepType.hs:537:18 in ghc:GHC.Types.RepType typePrimRep, called at compiler/GHC/StgToCmm/Utils.hs:305:58 in ghc:GHC.StgToCmm.Utils newUnboxedTupleRegs, called at compiler/GHC/StgToCmm/Prim.hs:1701:33 in ghc:GHC.StgToCmm.Prim ``` Here we fix this by modifying `PrimRep` to reflect the fact that we may know that a value is boxed without knowing its particular levity: ```haskell data PrimRep = BoxedRep Levity | IntRep | ... ``` This allows `kindPrimRep (TYPE (BoxedRep lev))` to return `BoxedRep _|_`, which is enough information for the code generator to compile `foo`. Fixes #22291.
Diffstat (limited to 'compiler/GHC/Core')
-rw-r--r--compiler/GHC/Core/TyCon.hs21
1 files changed, 9 insertions, 12 deletions
diff --git a/compiler/GHC/Core/TyCon.hs b/compiler/GHC/Core/TyCon.hs
index 5ae1e2bf6b..75eeafcb00 100644
--- a/compiler/GHC/Core/TyCon.hs
+++ b/compiler/GHC/Core/TyCon.hs
@@ -1629,8 +1629,7 @@ See Note [RuntimeRep and PrimRep] in GHC.Types.RepType.
-- "GHC.Types.RepType" and Note [VoidRep] in "GHC.Types.RepType".
data PrimRep
= VoidRep
- | LiftedRep
- | UnliftedRep -- ^ Unlifted pointer
+ | BoxedRep Levity
| Int8Rep -- ^ Signed, 8-bit value
| Int16Rep -- ^ Signed, 16-bit value
| Int32Rep -- ^ Signed, 32-bit value
@@ -1668,8 +1667,8 @@ instance Outputable PrimElemRep where
instance Binary PrimRep where
put_ bh VoidRep = putByte bh 0
- put_ bh LiftedRep = putByte bh 1
- put_ bh UnliftedRep = putByte bh 2
+ put_ bh (BoxedRep Lifted) = putByte bh 1
+ put_ bh (BoxedRep Unlifted) = putByte bh 2
put_ bh Int8Rep = putByte bh 3
put_ bh Int16Rep = putByte bh 4
put_ bh Int32Rep = putByte bh 5
@@ -1688,8 +1687,8 @@ instance Binary PrimRep where
h <- getByte bh
case h of
0 -> pure VoidRep
- 1 -> pure LiftedRep
- 2 -> pure UnliftedRep
+ 1 -> pure (BoxedRep Lifted)
+ 2 -> pure (BoxedRep Unlifted)
3 -> pure Int8Rep
4 -> pure Int16Rep
5 -> pure Int32Rep
@@ -1715,9 +1714,8 @@ isVoidRep VoidRep = True
isVoidRep _other = False
isGcPtrRep :: PrimRep -> Bool
-isGcPtrRep LiftedRep = True
-isGcPtrRep UnliftedRep = True
-isGcPtrRep _ = False
+isGcPtrRep (BoxedRep _) = True
+isGcPtrRep _ = False
-- A PrimRep is compatible with another iff one can be coerced to the other.
-- See Note [Bad unsafe coercion] in GHC.Core.Lint for when are two types coercible.
@@ -1758,10 +1756,9 @@ primRepSizeB platform = \case
FloatRep -> fLOAT_SIZE
DoubleRep -> dOUBLE_SIZE
AddrRep -> platformWordSizeInBytes platform
- LiftedRep -> platformWordSizeInBytes platform
- UnliftedRep -> platformWordSizeInBytes platform
+ BoxedRep _ -> platformWordSizeInBytes platform
VoidRep -> 0
- (VecRep len rep) -> len * primElemRepSizeB platform rep
+ VecRep len rep -> len * primElemRepSizeB platform rep
primElemRepSizeB :: Platform -> PrimElemRep -> Int
primElemRepSizeB platform = primRepSizeB platform . primElemRepToPrimRep