diff options
| author | Ben Gamari <ben@smart-cactus.org> | 2015-08-26 18:24:34 +0200 | 
|---|---|---|
| committer | Ben Gamari <ben@smart-cactus.org> | 2015-10-29 16:14:51 +0100 | 
| commit | bef2f03e4d56d88a7e9752a7afd6a0a35616da6c (patch) | |
| tree | 9ae33978cf43d8268a6c5afa42e7a6c8a7e227a1 /compiler/prelude/PrelNames.hs | |
| parent | 40e6214c06bc197dbdfcf9f7345dad1ad271922b (diff) | |
| download | haskell-bef2f03e4d56d88a7e9752a7afd6a0a35616da6c.tar.gz | |
Generate Typeable info at definition sites
This patch implements the idea floated in Trac #9858, namely that we
should generate type-representation information at the data type
declaration site, rather than when solving a Typeable constraint.
However, this turned out quite a bit harder than I expected. I still
think it's the right thing to do, and it's done now, but it was quite
a struggle.
See particularly
 * Note [Grand plan for Typeable] in TcTypeable (which is a new module)
 * Note [The overall promotion story] in DataCon (clarifies existing stuff)
The most painful bit was that to generate Typeable instances (ie
TyConRepName bindings) for every TyCon is tricky for types in ghc-prim
etc:
 * We need to have enough data types around to *define* a TyCon
 * Many of these types are wired-in
Also, to minimise the code generated for each data type, I wanted to
generate pure data, not CAFs with unpackCString# stuff floating about.
Performance
~~~~~~~~~~~
Three perf/compiler tests start to allocate quite a bit more. This isn't
surprising, because they all allocate zillions of data types, with
practically no other code, esp. T1969
 * T3294:   GHC allocates 110% more (filed #11030 to track this)
 * T1969:   GHC allocates 30% more
 * T4801:   GHC allocates 14% more
 * T5321FD: GHC allocates 13% more
 * T783:    GHC allocates 12% more
 * T9675:   GHC allocates 12% more
 * T5642:   GHC allocates 10% more
 * T9961:   GHC allocates 6% more
 * T9203:   Program allocates 54% less
I'm treating this as acceptable. The payoff comes in Typeable-heavy
code.
Remaining to do
~~~~~~~~~~~~~~~
 * I think that "TyCon" and "Module" are over-generic names to use for
   the runtime type representations used in GHC.Typeable. Better might be
   "TrTyCon" and "TrModule". But I have not yet done this
 * Add more info the the "TyCon" e.g. source location where it was
   defined
 * Use the new "Module" type to help with Trac Trac #10068
 * It would be possible to generate TyConRepName (ie Typeable
   instances) selectively rather than all the time. We'd need to persist
   the information in interface files. Lacking a motivating reason I have
   not done this, but it would not be difficult.
Refactoring
~~~~~~~~~~~
As is so often the case, I ended up refactoring more than I intended.
In particular
 * In TyCon, a type *family* (whether type or data) is repesented by a
   FamilyTyCon
     * a algebraic data type (including data/newtype instances) is
       represented by AlgTyCon This wasn't true before; a data family
       was represented as an AlgTyCon. There are some corresponding
       changes in IfaceSyn.
     * Also get rid of the (unhelpfully named) tyConParent.
 * In TyCon define 'Promoted', isomorphic to Maybe, used when things are
   optionally promoted; and use it elsewhere in GHC.
 * Cleanup handling of knownKeyNames
 * Each TyCon, including promoted TyCons, contains its TyConRepName, if
   it has one. This is, in effect, the name of its Typeable instance.
Requires update of the haddock submodule.
Differential Revision: https://phabricator.haskell.org/D757
Diffstat (limited to 'compiler/prelude/PrelNames.hs')
| -rw-r--r-- | compiler/prelude/PrelNames.hs | 88 | 
1 files changed, 66 insertions, 22 deletions
diff --git a/compiler/prelude/PrelNames.hs b/compiler/prelude/PrelNames.hs index 30d11fef59..05a38ffec9 100644 --- a/compiler/prelude/PrelNames.hs +++ b/compiler/prelude/PrelNames.hs @@ -206,11 +206,13 @@ basicKnownKeyNames          -- Typeable          typeableClassName,          typeRepTyConName, -        mkTyConName, +        trTyConDataConName, +        trModuleDataConName, +        trNameSDataConName, +        typeRepIdName,          mkPolyTyConAppName,          mkAppTyName, -        typeNatTypeRepName, -        typeSymbolTypeRepName, +        typeSymbolTypeRepName, typeNatTypeRepName,          -- Dynamic          toDynName, @@ -226,7 +228,6 @@ basicKnownKeyNames          fromIntegralName, realToFracName,          -- String stuff -        stringTyConName,          fromStringName,          -- Enum stuff @@ -607,7 +608,8 @@ toInteger_RDR           = nameRdrName toIntegerName  toRational_RDR          = nameRdrName toRationalName  fromIntegral_RDR        = nameRdrName fromIntegralName -fromString_RDR :: RdrName +stringTy_RDR, fromString_RDR :: RdrName +stringTy_RDR            = tcQual_RDR gHC_BASE (fsLit "String")  fromString_RDR          = nameRdrName fromStringName  fromList_RDR, fromListN_RDR, toList_RDR :: RdrName @@ -668,11 +670,6 @@ showString_RDR          = varQual_RDR gHC_SHOW (fsLit "showString")  showSpace_RDR           = varQual_RDR gHC_SHOW (fsLit "showSpace")  showParen_RDR           = varQual_RDR gHC_SHOW (fsLit "showParen") -typeRep_RDR, mkTyCon_RDR, mkTyConApp_RDR :: RdrName -typeRep_RDR       = varQual_RDR tYPEABLE_INTERNAL    (fsLit "typeRep#") -mkTyCon_RDR       = varQual_RDR tYPEABLE_INTERNAL    (fsLit "mkTyCon") -mkTyConApp_RDR    = varQual_RDR tYPEABLE_INTERNAL    (fsLit "mkTyConApp") -  undefined_RDR :: RdrName  undefined_RDR = varQual_RDR gHC_ERR (fsLit "undefined") @@ -782,6 +779,39 @@ and it's convenient to write them all down in one place.  -- guys as well (perhaps) e.g. see  trueDataConName     below  -} +-- | Build a 'Name' for the 'Typeable' representation of the given special 'TyCon'. +-- Special 'TyCon's include @(->)@, @BOX@, @Constraint@, etc. See 'TysPrim'. +mkSpecialTyConRepName :: FastString -> Name -> Name +-- See Note [Grand plan for Typeable] in 'TcTypeable' in TcTypeable. +mkSpecialTyConRepName fs tc_name +  = mkExternalName (tyConRepNameUnique (nameUnique tc_name)) +                   tYPEABLE_INTERNAL +                   (mkVarOccFS fs) +                   wiredInSrcSpan + +-- | Make a 'Name' for the 'Typeable' representation of the given wired-in type +mkPrelTyConRepName :: Name -> Name +-- See Note [Grand plan for Typeable] in 'TcTypeable' in TcTypeable. +mkPrelTyConRepName tc_name  -- Prelude tc_name is always External, +                            -- so nameModule will work +  = mkExternalName rep_uniq rep_mod rep_occ (nameSrcSpan tc_name) +  where +    name_occ  = nameOccName tc_name +    name_mod  = nameModule  tc_name +    name_uniq = nameUnique  tc_name +    rep_uniq | isTcOcc name_occ = tyConRepNameUnique   name_uniq +             | otherwise        = dataConRepNameUnique name_uniq +    (rep_mod, rep_occ) = tyConRepModOcc name_mod name_occ + +-- | TODO +-- See Note [Grand plan for Typeable] in 'TcTypeable' in TcTypeable. +tyConRepModOcc :: Module -> OccName -> (Module, OccName) +tyConRepModOcc tc_module tc_occ +  | tc_module == gHC_TYPES +  = (tYPEABLE_INTERNAL, mkTyConRepUserOcc tc_occ) +  | otherwise +  = (tc_module,         mkTyConRepSysOcc tc_occ) +  wildCardName :: Name  wildCardName = mkSystemVarName wildCardKey (fsLit "wild") @@ -849,12 +879,11 @@ uWordTyConName     = tcQual gHC_GENERICS (fsLit "UWord") uWordTyConKey  -- Base strings Strings  unpackCStringName, unpackCStringFoldrName, -    unpackCStringUtf8Name, eqStringName, stringTyConName :: Name +    unpackCStringUtf8Name, eqStringName :: Name  unpackCStringName       = varQual gHC_CSTRING (fsLit "unpackCString#") unpackCStringIdKey  unpackCStringFoldrName  = varQual gHC_CSTRING (fsLit "unpackFoldrCString#") unpackCStringFoldrIdKey  unpackCStringUtf8Name   = varQual gHC_CSTRING (fsLit "unpackCStringUtf8#") unpackCStringUtf8IdKey  eqStringName            = varQual gHC_BASE (fsLit "eqString")  eqStringIdKey -stringTyConName         = tcQual  gHC_BASE (fsLit "String") stringTyConKey  -- The 'inline' function  inlineIdName :: Name @@ -1053,15 +1082,21 @@ ixClassName = clsQual gHC_ARR (fsLit "Ix") ixClassKey  -- Class Typeable, and functions for constructing `Typeable` dictionaries  typeableClassName    , typeRepTyConName -  , mkTyConName +  , trTyConDataConName +  , trModuleDataConName +  , trNameSDataConName    , mkPolyTyConAppName    , mkAppTyName +  , typeRepIdName    , typeNatTypeRepName    , typeSymbolTypeRepName    :: Name  typeableClassName     = clsQual tYPEABLE_INTERNAL (fsLit "Typeable")       typeableClassKey  typeRepTyConName      = tcQual  tYPEABLE_INTERNAL (fsLit "TypeRep")        typeRepTyConKey -mkTyConName           = varQual tYPEABLE_INTERNAL (fsLit "mkTyCon")        mkTyConKey +trTyConDataConName    = dcQual  gHC_TYPES         (fsLit "TyCon")          trTyConDataConKey +trModuleDataConName   = dcQual  gHC_TYPES         (fsLit "Module")         trModuleDataConKey +trNameSDataConName    = dcQual  gHC_TYPES         (fsLit "TrNameS")        trNameSDataConKey +typeRepIdName         = varQual tYPEABLE_INTERNAL (fsLit "typeRep#")       typeRepIdKey  mkPolyTyConAppName    = varQual tYPEABLE_INTERNAL (fsLit "mkPolyTyConApp") mkPolyTyConAppKey  mkAppTyName           = varQual tYPEABLE_INTERNAL (fsLit "mkAppTy")        mkAppTyKey  typeNatTypeRepName    = varQual tYPEABLE_INTERNAL (fsLit "typeNatTypeRep") typeNatTypeRepKey @@ -1342,7 +1377,7 @@ ghciIoClassKey :: Unique  ghciIoClassKey = mkPreludeClassUnique 44  ---------------- Template Haskell ------------------- ---      USES ClassUniques 200-299 +--      THNames.hs: USES ClassUniques 200-299  -----------------------------------------------------  {- @@ -1489,9 +1524,6 @@ unknown2TyConKey                        = mkPreludeTyConUnique 131  unknown3TyConKey                        = mkPreludeTyConUnique 132  opaqueTyConKey                          = mkPreludeTyConUnique 133 -stringTyConKey :: Unique -stringTyConKey                          = mkPreludeTyConUnique 134 -  -- Generics (Unique keys)  v1TyConKey, u1TyConKey, par1TyConKey, rec1TyConKey,    k1TyConKey, m1TyConKey, sumTyConKey, prodTyConKey, @@ -1589,7 +1621,7 @@ ipCoNameKey = mkPreludeTyConUnique 185  ---------------- Template Haskell ------------------- ---      USES TyConUniques 200-299 +--      THNames.hs: USES TyConUniques 200-299  -----------------------------------------------------  ----------------------- SIMD ------------------------ @@ -1668,6 +1700,16 @@ srcLocDataConKey                        = mkPreludeDataConUnique 37  ipDataConKey :: Unique  ipDataConKey                            = mkPreludeDataConUnique 38 +trTyConDataConKey, trModuleDataConKey, trNameSDataConKey :: Unique +trTyConDataConKey                       = mkPreludeDataConUnique 40 +trModuleDataConKey                      = mkPreludeDataConUnique 41 +trNameSDataConKey                       = mkPreludeDataConUnique 42 + +---------------- Template Haskell ------------------- +--      THNames.hs: USES DataUniques 100-150 +----------------------------------------------------- + +  {-  ************************************************************************  *                                                                      * @@ -1922,7 +1964,7 @@ proxyHashKey :: Unique  proxyHashKey = mkPreludeMiscIdUnique 502  ---------------- Template Haskell ------------------- ---      USES IdUniques 200-499 +--      THNames.hs: USES IdUniques 200-499  -----------------------------------------------------  -- Used to make `Typeable` dictionaries @@ -1931,19 +1973,21 @@ mkTyConKey    , mkAppTyKey    , typeNatTypeRepKey    , typeSymbolTypeRepKey +  , typeRepIdKey    :: Unique  mkTyConKey            = mkPreludeMiscIdUnique 503  mkPolyTyConAppKey     = mkPreludeMiscIdUnique 504  mkAppTyKey            = mkPreludeMiscIdUnique 505  typeNatTypeRepKey     = mkPreludeMiscIdUnique 506  typeSymbolTypeRepKey  = mkPreludeMiscIdUnique 507 +typeRepIdKey          = mkPreludeMiscIdUnique 508  -- Dynamic  toDynIdKey :: Unique -toDynIdKey = mkPreludeMiscIdUnique 508 +toDynIdKey            = mkPreludeMiscIdUnique 509  bitIntegerIdKey :: Unique -bitIntegerIdKey       = mkPreludeMiscIdUnique 509 +bitIntegerIdKey       = mkPreludeMiscIdUnique 510  {-  ************************************************************************  | 
