Simon Peyton Jones pushed to branch wip/substitution-via-mapper at Glasgow Haskell Compiler / GHC

Commits:

5 changed files:

Changes:

  • compiler/GHC/Core/TyCo/Make.hs
    ... ... @@ -48,14 +48,12 @@ module GHC.Core.TyCo.Make (
    48 48
         -- Coercions
    
    49 49
         , mkReflCo, mkNomReflCo, mkRepReflCo
    
    50 50
         , mkCoVarCo, mkCoVarCos, mkHoleCo
    
    51
    -    , mkKindCo, mkSelCo
    
    51
    +    , mkKindCo
    
    52 52
         , mkGReflCo, mkGReflRightCo, mkGReflLeftCo
    
    53 53
         , mkGReflMCo, mkGReflRightMCo, mkGReflLeftMCo
    
    54 54
         , mkSubCo, mkSymCo, mkSymMCo
    
    55 55
         , mkFunCo2, mkForAllCo, mkUnivCo
    
    56 56
         , mkAxiomCo, mkUnbranchedAxInstCo
    
    57
    -    , mkAppCo, mkTyConAppCo
    
    58
    -    , mkInstCo, mkLRCo
    
    59 57
         , mkFunCo, mkNakedFunCo
    
    60 58
         , mkNakedForAllCo, mkForAllVisCos, mkHomoForAllCo, mkHomoForAllCos
    
    61 59
         , mkAxInstCo
    
    ... ... @@ -83,7 +81,7 @@ module GHC.Core.TyCo.Make (
    83 81
     import GHC.Prelude
    
    84 82
     
    
    85 83
     import {-# SOURCE #-} GHC.Core.Coercion
    
    86
    -    ( mkLRCo, mkInstCo, mkAppCo, mkAppCos, mkTyConAppCo, mkSelCo
    
    84
    +    ( mkLRCo, mkInstCo, mkAppCo, mkAppCos, mkSelCo
    
    87 85
         , decomposePiCos
    
    88 86
         , isKindCo
    
    89 87
         , coercionKind -- Used in toPhantomCo
    
    ... ... @@ -222,60 +220,60 @@ mapTyCoX (TyCoMapper { tcm_tyvar = tyvar
    222 220
       = (go_ty, go_tys, go_co, go_cos)
    
    223 221
       where
    
    224 222
         -- See Note [Use explicit recursion in mapTyCo]
    
    225
    -    go_tys !_   []       = return []
    
    226
    -    go_tys !env (ty:tys) = (:) <$> go_ty env ty <*> go_tys env tys
    
    223
    +    go_tys _   []       = return []
    
    224
    +    go_tys env (ty:tys) = (:) <$> go_ty env ty <*> go_tys env tys
    
    227 225
     
    
    228
    -    go_ty !env (TyVarTy tv)    = tyvar env tv
    
    229
    -    go_ty !env (AppTy t1 t2)   = mkAppTy <$> go_ty env t1 <*> go_ty env t2
    
    230
    -    go_ty !_   ty@(LitTy {})   = return ty
    
    231
    -    go_ty !env (CastTy ty co)  = mkCastTy <$> go_ty env ty <*> go_co env co
    
    232
    -    go_ty !env (CoercionTy co) = CoercionTy <$> go_co env co
    
    226
    +    go_ty env (TyVarTy tv)    = tyvar env tv
    
    227
    +    go_ty env (AppTy t1 t2)   = mkAppTy <$> go_ty env t1 <*> go_ty env t2
    
    228
    +    go_ty _   ty@(LitTy {})   = return ty
    
    229
    +    go_ty env (CastTy ty co)  = mkCastTy <$> go_ty env ty <*> go_co env co
    
    230
    +    go_ty env (CoercionTy co) = CoercionTy <$> go_co env co
    
    233 231
     
    
    234
    -    go_ty !env ty@(FunTy _ w arg res)
    
    232
    +    go_ty env ty@(FunTy _ w arg res)
    
    235 233
           = do { w' <- go_ty env w; arg' <- go_ty env arg; res' <- go_ty env res
    
    236 234
                ; return (ty { ft_mult = w', ft_arg = arg', ft_res = res' }) }
    
    237 235
     
    
    238
    -    go_ty !env ty@(TyConApp tc tys)
    
    236
    +    go_ty env ty@(TyConApp tc tys)
    
    239 237
           = do { tys' <- go_tys env tys; tcapp_ty env ty tc tys' }
    
    240 238
     
    
    241
    -    go_ty !env (ForAllTy (Bndr tv vis) inner)
    
    239
    +    go_ty env (ForAllTy (Bndr tv vis) inner)
    
    242 240
           = do { tycobinder env tv vis $ \env' tv' -> do
    
    243 241
                ; inner' <- go_ty env' inner
    
    244 242
                ; return $ ForAllTy (Bndr tv' vis) inner' }
    
    245 243
     
    
    246 244
         -- See Note [Use explicit recursion in mapTyCo]
    
    247
    -    go_cos !_   []       = return []
    
    248
    -    go_cos !env (co:cos) = (:) <$> go_co env co <*> go_cos env cos
    
    245
    +    go_cos _   []       = return []
    
    246
    +    go_cos env (co:cos) = (:) <$> go_co env co <*> go_cos env cos
    
    249 247
     
    
    250
    -    go_mco !_   MRefl    = return MRefl
    
    251
    -    go_mco !env (MCo co) = MCo <$> (go_co env co)
    
    248
    +    go_mco _   MRefl    = return MRefl
    
    249
    +    go_mco env (MCo co) = MCo <$> (go_co env co)
    
    252 250
     
    
    253 251
         go_co :: env -> Coercion -> m Coercion
    
    254
    -    go_co !env (Refl ty)                  = Refl <$> go_ty env ty
    
    255
    -    go_co !env (GRefl r ty mco)           = mkGReflCo r <$> go_ty env ty <*> go_mco env mco
    
    256
    -    go_co !env (AppCo c1 c2)              = mkAppCo <$> go_co env c1 <*> go_co env c2
    
    257
    -    go_co !env (FunCo r afl afr cw c1 c2) = mkFunCo2 r afl afr <$> go_co env cw
    
    252
    +    go_co env (Refl ty)                  = Refl <$> go_ty env ty
    
    253
    +    go_co env (GRefl r ty mco)           = mkGReflCo r <$> go_ty env ty <*> go_mco env mco
    
    254
    +    go_co env (AppCo c1 c2)              = mkAppCo <$> go_co env c1 <*> go_co env c2
    
    255
    +    go_co env (FunCo r afl afr cw c1 c2) = mkFunCo2 r afl afr <$> go_co env cw
    
    258 256
                                                <*> go_co env c1 <*> go_co env c2
    
    259
    -    go_co !env (CoVarCo cv)               = covar env cv
    
    260
    -    go_co !env (HoleCo hole)              = cohole env hole
    
    261
    -    go_co !env (UnivCo { uco_prov = p, uco_role = r
    
    262
    -                       , uco_lty = t1, uco_rty = t2, uco_deps = deps })
    
    263
    -                                          = mkUnivCo <$> pure p
    
    264
    -                                                     <*> go_cos env deps
    
    265
    -                                                     <*> pure r
    
    266
    -                                                     <*> go_ty env t1 <*> go_ty env t2
    
    267
    -    go_co !env (SymCo co)                 = mkSymCo <$> go_co env co
    
    268
    -    go_co !env (TransCo c1 c2)            = mkTransCo <$> go_co env c1 <*> go_co env c2
    
    269
    -    go_co !env (AxiomCo r cos)            = mkAxiomCo r <$> go_cos env cos
    
    270
    -    go_co !env (SelCo i co)               = SelCo i <$> go_co env co
    
    271
    -    go_co !env (LRCo lr co)               = mkLRCo lr <$> go_co env co
    
    272
    -    go_co !env (InstCo co arg)            = mkInstCo <$> go_co env co <*> go_co env arg
    
    273
    -    go_co !env (KindCo co)                = mkKindCo <$> go_co env co
    
    274
    -    go_co !env (SubCo co)                 = mkSubCo <$> go_co env co
    
    275
    -    go_co !env co@(TyConAppCo r tc cos)   = do { cos' <- go_cos env cos
    
    257
    +    go_co env (CoVarCo cv)               = covar env cv
    
    258
    +    go_co env (HoleCo hole)              = cohole env hole
    
    259
    +    go_co env (UnivCo { uco_prov = p, uco_role = r
    
    260
    +                      , uco_lty = t1, uco_rty = t2, uco_deps = deps })
    
    261
    +                                         = mkUnivCo <$> pure p
    
    262
    +                                                    <*> go_cos env deps
    
    263
    +                                                    <*> pure r
    
    264
    +                                                    <*> go_ty env t1 <*> go_ty env t2
    
    265
    +    go_co env (SymCo co)                 = mkSymCo <$> go_co env co
    
    266
    +    go_co env (TransCo c1 c2)            = mkTransCo <$> go_co env c1 <*> go_co env c2
    
    267
    +    go_co env (AxiomCo r cos)            = mkAxiomCo r <$> go_cos env cos
    
    268
    +    go_co env (SelCo i co)               = mkSelCo i <$> go_co env co
    
    269
    +    go_co env (LRCo lr co)               = mkLRCo lr <$> go_co env co
    
    270
    +    go_co env (InstCo co arg)            = mkInstCo <$> go_co env co <*> go_co env arg
    
    271
    +    go_co env (KindCo co)                = mkKindCo <$> go_co env co
    
    272
    +    go_co env (SubCo co)                 = mkSubCo <$> go_co env co
    
    273
    +    go_co env co@(TyConAppCo r tc cos)   = do { cos' <- go_cos env cos
    
    276 274
                                                    ; tcapp_co env co r tc cos' }
    
    277
    -    go_co !env (ForAllCo { fco_tcv = tv, fco_visL = visL, fco_visR = visR
    
    278
    -                         , fco_kind = kind_co, fco_body = co })
    
    275
    +    go_co env (ForAllCo { fco_tcv = tv, fco_visL = visL, fco_visR = visR
    
    276
    +                        , fco_kind = kind_co, fco_body = co })
    
    279 277
           = do { kind_co' <- go_mco env kind_co
    
    280 278
                ; tycobinder env tv visL $ \env' tv' ->  do
    
    281 279
                ; co' <- go_co env' co
    

  • compiler/GHC/Core/TyCo/Subst.hs
    ... ... @@ -53,7 +53,7 @@ module GHC.Core.TyCo.Subst
    53 53
     import GHC.Prelude
    
    54 54
     
    
    55 55
     
    
    56
    -import {-# SOURCE #-} GHC.Core.Coercion ( mkCoercionType, coVarTypesRole )
    
    56
    +import {-# SOURCE #-} GHC.Core.Coercion ( mkCoercionType, coVarTypesRole, mkTyConAppCo )
    
    57 57
     import {-# SOURCE #-} GHC.Core.TyCo.Ppr ( pprTyVar )
    
    58 58
     import {-# SOURCE #-} GHC.Core.Ppr ( ) -- instance Outputable CoreExpr
    
    59 59
     import {-# SOURCE #-} GHC.Core ( CoreExpr )
    
    ... ... @@ -76,8 +76,8 @@ import GHC.Utils.Constants (debugIsOn)
    76 76
     import GHC.Utils.Misc
    
    77 77
     import GHC.Utils.Outputable
    
    78 78
     import GHC.Utils.Panic
    
    79
    +import GHC.Utils.StrictIdentity
    
    79 80
     
    
    80
    -import Data.Functor.Identity ( Identity (..) )
    
    81 81
     import Data.List (mapAccumL)
    
    82 82
     
    
    83 83
     {-
    
    ... ... @@ -769,8 +769,9 @@ substTheta = substTys
    769 769
     substThetaUnchecked :: Subst -> ThetaType -> ThetaType
    
    770 770
     substThetaUnchecked = substTysUnchecked
    
    771 771
     
    
    772
    -
    
    773
    -substTyCoMapper :: TyCoMapper Subst Identity
    
    772
    +substTyCoMapper :: TyCoMapper Subst StrictIdentity
    
    773
    +-- Use StrictIdentity, so that the entire mapping
    
    774
    +-- operation is strict, building no thunks
    
    774 775
     substTyCoMapper
    
    775 776
       = TyCoMapper { tcm_tyvar      = subst_tv
    
    776 777
                    , tcm_covar      = subst_cv
    
    ... ... @@ -787,16 +788,16 @@ substTyCoMapper
    787 788
        tcv_bndr subst tcv _vis k
    
    788 789
          = k subst' tcv'
    
    789 790
          where
    
    790
    -       (subst', tcv') = substVarBndrUnchecked subst tcv
    
    791
    +       !(subst', tcv') = substVarBndrUnchecked subst tcv
    
    791 792
            -- Sadly unchecked because subst_ty is used from substTyUnchecked
    
    792 793
     
    
    793 794
        -- Avoid allocation in this very
    
    794 795
        -- common case (E.g. Int, LiftedRep etc)
    
    795
    -   tcapp_ty :: Subst -> Type -> TyCon -> [Type] -> Identity Type
    
    796
    +   tcapp_ty :: Subst -> Type -> TyCon -> [Type] -> StrictIdentity Type
    
    796 797
        tcapp_ty _ ty tc tys'
    
    797 798
           | null tys'  = return ty
    
    798 799
           | otherwise  = return (mkTyConApp tc tys')
    
    799
    -   tcapp_co :: Subst -> Coercion -> Role -> TyCon -> [Coercion] -> Identity Coercion
    
    800
    +   tcapp_co :: Subst -> Coercion -> Role -> TyCon -> [Coercion] -> StrictIdentity Coercion
    
    800 801
        tcapp_co _ co r tc cos'
    
    801 802
           | null cos'  = return co
    
    802 803
           | otherwise  = return (mkTyConAppCo r tc cos')
    
    ... ... @@ -807,43 +808,8 @@ subst_co :: Subst -> Coercion -> Coercion
    807 808
       = case mapTyCoX substTyCoMapper of
    
    808 809
           (ms_ty, _, ms_co, _) -> (run ms_ty, run ms_co)
    
    809 810
       where
    
    810
    -    run :: forall a. (Subst -> a -> Identity a) -> Subst -> a -> a
    
    811
    -    run ms subst x = runIdentity (ms subst x)
    
    812
    -
    
    813
    -{-
    
    814
    -subst_ty :: Subst -> Type -> Type
    
    815
    --- subst_ty is the main workhorse for type substitution
    
    816
    ---
    
    817
    --- Note that the in_scope set is poked only if we hit a forall
    
    818
    --- so it may often never be fully computed
    
    819
    -subst_ty subst ty
    
    820
    -   = go ty
    
    821
    -  where
    
    822
    -    go (TyVarTy tv)      = substTyVar subst tv
    
    823
    -    go (AppTy fun arg)   = (mkAppTy $! (go fun)) $! (go arg)
    
    824
    -                -- The mkAppTy smart constructor is important
    
    825
    -                -- we might be replacing (a Int), represented with App
    
    826
    -                -- by [Int], represented with TyConApp
    
    827
    -    go ty@(TyConApp tc []) = tc `seq` ty  -- avoid allocation in this common case
    
    828
    -    go (TyConApp tc tys) = (mkTyConApp $! tc) $! strictMap go tys
    
    829
    -                               -- NB: mkTyConApp, not TyConApp.
    
    830
    -                               -- mkTyConApp has optimizations.
    
    831
    -                               -- See Note [Using synonyms to compress types]
    
    832
    -                               -- in GHC.Core.Type
    
    833
    -    go ty@(FunTy { ft_mult = mult, ft_arg = arg, ft_res = res })
    
    834
    -      = let !mult' = go mult
    
    835
    -            !arg' = go arg
    
    836
    -            !res' = go res
    
    837
    -        in ty { ft_mult = mult', ft_arg = arg', ft_res = res' }
    
    838
    -    go (ForAllTy (Bndr tv vis) ty)
    
    839
    -      = (ForAllTy $! ((Bndr $! tv') vis)) $! (subst_ty subst' ty)
    
    840
    -      where
    
    841
    -        !(subst',tv') = substVarBndrUnchecked subst tv
    
    842
    -                        -- Unchecked because subst_ty is used from substTyUnchecked
    
    843
    -    go (LitTy n)         = LitTy $! n
    
    844
    -    go (CastTy ty co)    = (mkCastTy $! (go ty)) $! (subst_co subst co)
    
    845
    -    go (CoercionTy co)   = CoercionTy $! (subst_co subst co)
    
    846
    --}
    
    811
    +    run :: forall a. (Subst -> a -> StrictIdentity a) -> Subst -> a -> a
    
    812
    +    run ms subst x = runStrictIdentity (ms subst x)
    
    847 813
     
    
    848 814
     substTyVar :: Subst -> TyVar -> Type
    
    849 815
     substTyVar (Subst _ _ tenv _) tv
    
    ... ... @@ -885,51 +851,6 @@ substCos subst cos
    885 851
       | isEmptyTCvSubst subst = cos
    
    886 852
       | otherwise = checkValidSubst subst [] cos $ map (subst_co subst) cos
    
    887 853
     
    
    888
    -{-
    
    889
    -subst_co :: HasDebugCallStack => Subst -> Coercion -> Coercion
    
    890
    -subst_co subst co
    
    891
    -  = go co
    
    892
    -  where
    
    893
    -    go_ty :: Type -> Type
    
    894
    -    go_ty = subst_ty subst
    
    895
    -
    
    896
    -    go_mco :: MCoercion -> MCoercion
    
    897
    -    go_mco MRefl    = MRefl
    
    898
    -    go_mco (MCo co) = MCo (go co)
    
    899
    -
    
    900
    -    go :: Coercion -> Coercion
    
    901
    -    go (Refl ty)             = mkNomReflCo $! (go_ty ty)
    
    902
    -    go (GRefl r ty mco)      = (mkGReflCo r $! (go_ty ty)) $! (go_mco mco)
    
    903
    -    go (TyConAppCo r tc args)= mkTyConAppCo r tc $! go_cos args
    
    904
    -    go (AxiomCo con cos)     = mkAxiomCo con $! go_cos cos
    
    905
    -    go (AppCo co arg)        = (mkAppCo $! go co) $! go arg
    
    906
    -    go (ForAllCo { fco_tcv = tcv, fco_visL = visL, fco_visR = visR
    
    907
    -                 , fco_kind = kind_co, fco_body = co })
    
    908
    -      = ((mkForAllCo $! tcv') visL visR
    
    909
    -           $! go_mco kind_co)
    
    910
    -           $! subst_co subst' co
    
    911
    -      where
    
    912
    -        !(subst', tcv') = substVarBndrUnchecked subst tcv
    
    913
    -                          -- Unchecked because used from substTyUnchecked
    
    914
    -    go (FunCo r afl afr w co1 co2)   = ((mkFunCo2 r afl afr $! go w) $! go co1) $! go co2
    
    915
    -    go (CoVarCo cv)          = substCoVar subst cv
    
    916
    -    go (HoleCo h)            = substCoHole subst h
    
    917
    -    go (UnivCo { uco_prov = p, uco_role = r
    
    918
    -               , uco_lty = t1, uco_rty = t2, uco_deps = deps })
    
    919
    -                             = ((((mkUnivCo $! p) $! go_cos deps) $! r) $!
    
    920
    -                                  (go_ty t1)) $! (go_ty t2)
    
    921
    -    go (SymCo co)            = mkSymCo $! (go co)
    
    922
    -    go (TransCo co1 co2)     = (mkTransCo $! (go co1)) $! (go co2)
    
    923
    -    go (SelCo d co)          = mkSelCo d $! (go co)
    
    924
    -    go (LRCo lr co)          = mkLRCo lr $! (go co)
    
    925
    -    go (InstCo co arg)       = (mkInstCo $! (go co)) $! go arg
    
    926
    -    go (KindCo co)           = mkKindCo $! (go co)
    
    927
    -    go (SubCo co)            = mkSubCo $! (go co)
    
    928
    -
    
    929
    -    go_cos cos = let cos' = map go cos
    
    930
    -                 in cos' `seqList` cos'
    
    931
    --}
    
    932
    -
    
    933 854
     -- | Perform a substitution within a 'DVarSet' of free variables,
    
    934 855
     -- returning the free coercion variables.
    
    935 856
     substDCoVarSet :: Subst -> DCoVarSet -> DCoVarSet
    

  • compiler/GHC/Core/Type.hs
    ... ... @@ -256,13 +256,13 @@ import {-# SOURCE #-} GHC.Tc.Utils.TcType ( isConcreteTyVar )
    256 256
     import GHC.Utils.Misc
    
    257 257
     import GHC.Utils.Outputable
    
    258 258
     import GHC.Utils.Panic
    
    259
    -import GHC.Data.FastString
    
    259
    +import GHC.Utils.StrictIdentity
    
    260 260
     
    
    261
    +import GHC.Data.FastString
    
    261 262
     import GHC.Data.Maybe   ( orElse, isJust )
    
    262 263
     import GHC.List (build)
    
    263 264
     
    
    264 265
     import qualified Data.Monoid as M
    
    265
    -import Data.Functor.Identity
    
    266 266
     
    
    267 267
     -- $type_classification
    
    268 268
     -- #type_classification#
    
    ... ... @@ -483,9 +483,9 @@ expandTypeSynonyms ty
    483 483
     expandTypeSynonymsX :: Subst -> Type -> Type
    
    484 484
     expandTypeSynonymsX
    
    485 485
       = case mapTyCoX expandTypeSynonymMapper of
    
    486
    -      (exp_ty, _, _, _) -> \subst ty -> runIdentity (exp_ty subst ty)
    
    486
    +      (exp_ty, _, _, _) -> \subst ty -> runStrictIdentity (exp_ty subst ty)
    
    487 487
     
    
    488
    -expandTypeSynonymMapper :: TyCoMapper Subst Identity
    
    488
    +expandTypeSynonymMapper :: TyCoMapper Subst StrictIdentity
    
    489 489
     -- Just like substitution, but treat TyConApp specially
    
    490 490
     expandTypeSynonymMapper
    
    491 491
       = substTyCoMapper { tcm_tcapp_ty = tcapp_ty }
    

  • compiler/GHC/Utils/StrictIdentity.hs
    1
    +-- |
    
    2
    +-- Module      :  GHC.Utils.StrictIdentity
    
    3
    +-- License     :  BSD-style (see the file LICENSE)
    
    4
    +--
    
    5
    +-- The /strict/ identity functor and monad.
    
    6
    +--
    
    7
    +-- This trivial type constructor serves two purposes:
    
    8
    +--
    
    9
    +-- * It can be used with functions parameterized by functor or monad classes.
    
    10
    +--
    
    11
    +-- * It can be used as a base monad to which a series of monad
    
    12
    +--   transformers may be applied to construct a composite monad.
    
    13
    +--   Most monad transformer modules include the special case of
    
    14
    +--   applying the transformer to 'Identity'.  For example, @State s@
    
    15
    +--   is an abbreviation for @StateT s 'Identity'@.
    
    16
    +
    
    17
    +-----------------------------------------------------------------------------
    
    18
    +
    
    19
    +module GHC.Utils.StrictIdentity (
    
    20
    +    StrictIdentity(..)
    
    21
    +  ) where
    
    22
    +
    
    23
    +import GHC.Prelude
    
    24
    +
    
    25
    +import Data.Coerce( coerce )
    
    26
    +
    
    27
    +newtype StrictIdentity a = StrictIdentity { runStrictIdentity :: a }
    
    28
    +
    
    29
    +-----------------------------------------------------------------------------
    
    30
    +-- In the following instances, the key lines are the strict applications ($!)
    
    31
    +-----------------------------------------------------------------------------
    
    32
    +
    
    33
    +instance Functor StrictIdentity where
    
    34
    +    fmap f (StrictIdentity x) = StrictIdentity (f $! x)
    
    35
    +
    
    36
    +instance Applicative StrictIdentity where
    
    37
    +    pure = StrictIdentity
    
    38
    +    (StrictIdentity f) <*> (StrictIdentity x) = StrictIdentity (f $! x)
    
    39
    +
    
    40
    +instance Monad StrictIdentity where
    
    41
    +    m >>= k  = k $! (runStrictIdentity m)

  • compiler/ghc.cabal.in
    ... ... @@ -1029,6 +1029,7 @@ Library
    1029 1029
             GHC.Utils.Panic.Plain
    
    1030 1030
             GHC.Utils.Ppr
    
    1031 1031
             GHC.Utils.Ppr.Colour
    
    1032
    +        GHC.Utils.StrictIdentity
    
    1032 1033
             GHC.Utils.TmpFs
    
    1033 1034
             GHC.Utils.Touch
    
    1034 1035
             GHC.Utils.Trace