diff options
author | romes <rodrigo.m.mesquita@gmail.com> | 2023-03-24 14:11:11 +0000 |
---|---|---|
committer | Rodrigo Mesquita <rodrigo.m.mesquita@gmail.com> | 2023-03-27 18:35:41 +0100 |
commit | 76b1f647f3da7c54e92a3bc559ce9200c14712fc (patch) | |
tree | f0c1da6f5f2f0a5ab7f18ea1fc7349ebb4dfe89c | |
parent | be1d4be8d09072091b77cb68ccf234434754af00 (diff) | |
download | haskell-wip/romes/rep-arity.tar.gz |
Account for all VoidRep types on precomputedStaticConInfowip/romes/rep-arity
Previously, we were considering coercion values whose unlifted type
equality had a zerobit runtime representation (VoidRep) to be
constructor arguments when determining whether we should pre-compute a
staticConInfo for a data constructor.
This made it so that GADT constructors with type-equality constraints
that should have no runtime representation actually ended up impacting
the code generation.
Fixes #23158
-rw-r--r-- | compiler/GHC/Core/DataCon.hs | 34 | ||||
-rw-r--r-- | compiler/GHC/Core/Opt/Simplify/Utils.hs | 4 | ||||
-rw-r--r-- | compiler/GHC/Types/RepType.hs-boot | 9 |
3 files changed, 38 insertions, 9 deletions
diff --git a/compiler/GHC/Core/DataCon.hs b/compiler/GHC/Core/DataCon.hs index f54f42d99d..2440a3154b 100644 --- a/compiler/GHC/Core/DataCon.hs +++ b/compiler/GHC/Core/DataCon.hs @@ -79,6 +79,7 @@ import GHC.Core.TyCo.Subst import GHC.Core.TyCo.Compare( eqType ) import GHC.Core.Multiplicity import {-# SOURCE #-} GHC.Types.TyThing +import {-# SOURCE #-} GHC.Types.RepType (isZeroBitTy) import GHC.Types.FieldLabel import GHC.Types.SourceText import GHC.Core.Class @@ -111,8 +112,8 @@ import Data.List( find ) import Language.Haskell.Syntax.Module.Name {- -Data constructor representation -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Note [Data constructor representation] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider the following Haskell data type declaration data T = T !Int ![Int] @@ -981,7 +982,7 @@ but the rep type is Trep :: Int# -> a -> Void# -> T a Actually, the unboxed part isn't implemented yet! -Not that this representation is still *different* from runtime +Note that this representation is still *different* from runtime representation. (Which is what STG uses after unarise). This is how T would end up being used in STG post-unarise: @@ -1395,9 +1396,9 @@ dataConSrcBangs = dcSrcBangs dataConSourceArity :: DataCon -> Arity dataConSourceArity (MkData { dcSourceArity = arity }) = arity --- | Gives the number of actual fields in the /representation/ of the --- data constructor. This may be more than appear in the source code; --- the extra ones are the existentially quantified dictionaries +-- | Gives the number of actual fields in the core /representation/ of the data +-- constructor. This may be more than appear in the source code; the extra ones +-- are the existentially quantified dictionaries. dataConRepArity :: DataCon -> Arity dataConRepArity (MkData { dcRepArity = arity }) = arity @@ -1408,8 +1409,12 @@ isNullarySrcDataCon dc = dataConSourceArity dc == 0 -- | Return whether there are any argument types for this 'DataCon's runtime representation type -- See Note [DataCon arities] +-- ROMES:TODO: I'll improve the comment so this is clearer +-- +-- ROMES: The arity of the runtime representation DOES NOT match the arity of the Core representation, which is what `dataConRepArity` means +-- TODO: Might need caching isNullaryRepDataCon :: DataCon -> Bool -isNullaryRepDataCon dc = dataConRepArity dc == 0 +isNullaryRepDataCon dc = length (filter (not . isZeroBitTy . scaledThing) (dataConRepArgTys dc)) == 0 dataConRepStrictness :: DataCon -> [StrictnessMark] -- ^ Give the demands on the arguments of a @@ -1668,6 +1673,21 @@ dataConOtherTheta dc = dcOtherTheta dc -- | Returns the arg types of the worker, including *all* non-dependent -- evidence, after any flattening has been done and without substituting for -- any type variables +-- +-- In Note [Data constructor workers and wrappers], 'dataConRepArgTys' is +-- mentioned as the arguments of the worker, in contrast with 'dcOrigArgTys' +-- which are the arguments of the wrapper. In this context, it makes sense to +-- consider that coercions should be in the list returned by 'dataConRepArgTys' +-- +-- In Note [Data con representation] it is said the following +-- +-- So whenever this module talks about the representation of a data constructor +-- what it means is the DataCon with all Unpacking having been applied. +-- We can think of this as the Core representation. +-- +-- This means we should be careful NOT to use 'dataConRepArgTys' to determine +-- the number of runtime arguments a function has. +-- filter (not . isZeroBitTy . scaledThing) dataConRepArgTys :: DataCon -> [Scaled Type] dataConRepArgTys (MkData { dcRep = rep , dcEqSpec = eq_spec diff --git a/compiler/GHC/Core/Opt/Simplify/Utils.hs b/compiler/GHC/Core/Opt/Simplify/Utils.hs index 7eb4692231..de431198d5 100644 --- a/compiler/GHC/Core/Opt/Simplify/Utils.hs +++ b/compiler/GHC/Core/Opt/Simplify/Utils.hs @@ -62,7 +62,7 @@ import GHC.Core.Unfold.Make import GHC.Core.Opt.Simplify.Monad import GHC.Core.Type hiding( substTy ) import GHC.Core.Coercion hiding( substCo ) -import GHC.Core.DataCon ( dataConWorkId, isNullaryRepDataCon ) +import GHC.Core.DataCon ( dataConWorkId, dataConRepArity ) import GHC.Core.Multiplicity import GHC.Core.Opt.ConstantFold @@ -2659,7 +2659,7 @@ mkCase2 mode scrut bndr alts_ty alts DataAlt dc -> mkConApp2 dc (tyConAppArgs (idType bndr)) bs mk_new_bndrs new_bndr (DataAlt dc) - | not (isNullaryRepDataCon dc) + | dataConRepArity dc /= 0 = -- For non-nullary data cons we must invent some fake binders -- See Note [caseRules for dataToTag] in GHC.Core.Opt.ConstantFold do { us <- getUniquesM diff --git a/compiler/GHC/Types/RepType.hs-boot b/compiler/GHC/Types/RepType.hs-boot new file mode 100644 index 0000000000..e20d66b6e9 --- /dev/null +++ b/compiler/GHC/Types/RepType.hs-boot @@ -0,0 +1,9 @@ +module GHC.Types.RepType where + +import Data.Bool +import GHC.Core.TyCo.Rep (Type) +import GHC.Utils.Misc (HasDebugCallStack) + +isZeroBitTy :: HasDebugCallStack => Type -> Bool + + |