summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorromes <rodrigo.m.mesquita@gmail.com>2023-03-24 14:11:11 +0000
committerRodrigo Mesquita <rodrigo.m.mesquita@gmail.com>2023-03-27 21:33:31 +0100
commit405c6825059a9c071479996025c52227e4aae85c (patch)
treeef2331e0a03d6053131ad775ebd09169fc34d31b
parentbe1d4be8d09072091b77cb68ccf234434754af00 (diff)
downloadhaskell-wip/romes/static-gadt-con-info.tar.gz
Account for all VoidRep types on precomputedStaticConInfowip/romes/static-gadt-con-info
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.hs38
-rw-r--r--compiler/GHC/Core/Opt/Simplify/Utils.hs4
-rw-r--r--compiler/GHC/Types/RepType.hs-boot9
3 files changed, 40 insertions, 11 deletions
diff --git a/compiler/GHC/Core/DataCon.hs b/compiler/GHC/Core/DataCon.hs
index f54f42d99d..677bd42d65 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
@@ -1406,10 +1407,14 @@ dataConRepArity (MkData { dcRepArity = arity }) = arity
isNullarySrcDataCon :: DataCon -> Bool
isNullarySrcDataCon dc = dataConSourceArity dc == 0
--- | Return whether there are any argument types for this 'DataCon's runtime representation type
--- See Note [DataCon arities]
+-- | Return whether there are any non-zero-width argument types for this
+-- 'DataCon's runtime representation type. See Note [DataCon arities] and Note [
+-- 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. The || is to test performance
isNullaryRepDataCon :: DataCon -> Bool
-isNullaryRepDataCon dc = dataConRepArity dc == 0
+isNullaryRepDataCon dc = dataConRepArity dc == 0 || 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
+
+