Simon Peyton Jones pushed to branch wip/spj-try-opt-coercion at Glasgow Haskell Compiler / GHC

Commits:

12 changed files:

Changes:

  • compiler/GHC/Core/Coercion.hs
    ... ... @@ -172,7 +172,6 @@ import qualified Data.Monoid as Monoid
    172 172
     import Data.List.NonEmpty ( NonEmpty (..) )
    
    173 173
     import Control.DeepSeq
    
    174 174
     
    
    175
    -import GHC.Exts
    
    176 175
     
    
    177 176
     {-
    
    178 177
     %************************************************************************
    
    ... ... @@ -2473,40 +2472,6 @@ seqCos :: [Coercion] -> ()
    2473 2472
     seqCos []       = ()
    
    2474 2473
     seqCos (co:cos) = seqCo co `seq` seqCos cos
    
    2475 2474
     
    
    2476
    -coercionIsSmall :: Coercion -> Bool
    
    2477
    --- This function should return False quickly on a big coercion
    
    2478
    --- It should /not/ traverse the big coercion!
    
    2479
    -coercionIsSmall co
    
    2480
    -  = not (isTrue# ((go co 100#) <# 0#))
    
    2481
    -  where
    
    2482
    -    go :: Coercion -> Int# -> Int#
    
    2483
    -    go _co n | isTrue# (n <# 0#)   = n
    
    2484
    -    go (Refl {})                 n = dec n
    
    2485
    -    go (GRefl _ _ mco)           n = go_mco mco (dec n)
    
    2486
    -    go (TyConAppCo _ _ cos)      n = go_cos cos (dec n)
    
    2487
    -    go (AxiomCo _ cos)           n = go_cos cos (dec n)
    
    2488
    -    go (UnivCo _ _ _ _ cos)      n = go_cos cos (dec n)
    
    2489
    -    go (AppCo co1 co2)           n = go co1 (go co2 (dec n))
    
    2490
    -    go (CoVarCo {})              n = dec n
    
    2491
    -    go (HoleCo {})               n = dec n
    
    2492
    -    go (SymCo co)                n = go co (dec n)
    
    2493
    -    go (KindCo co)               n = go co (dec n)
    
    2494
    -    go (SubCo co)                n = go co (dec n)
    
    2495
    -    go (TransCo co1 co2)         n = go co1 (go co2 (dec n))
    
    2496
    -    go (SelCo _  co)             n = go co (dec n)
    
    2497
    -    go (LRCo _  co)              n = go co (dec n)
    
    2498
    -    go (InstCo co1 co2)          n = go co1 (go co2 (dec n))
    
    2499
    -    go (ForAllCo _ _ _ kco co)   n = go co (go_mco kco (dec n))
    
    2500
    -    go (FunCo _ _ _ mco aco rco) n = go mco (go aco (go rco (dec n)))
    
    2501
    -
    
    2502
    -    go_cos []       n = n
    
    2503
    -    go_cos (co:cos) n = go_cos cos (go co n)
    
    2504
    -
    
    2505
    -    go_mco MRefl    n = dec n
    
    2506
    -    go_mco (MCo co) n = go co n
    
    2507
    -
    
    2508
    -    dec n = n -# 1#
    
    2509
    -
    
    2510 2475
     {-
    
    2511 2476
     %************************************************************************
    
    2512 2477
     %*                                                                      *
    

  • compiler/GHC/Core/FVs.hs
    ... ... @@ -29,12 +29,14 @@ module GHC.Core.FVs (
    29 29
             idUnfoldingVars, idFreeVars, dIdFreeVars,
    
    30 30
             bndrRuleAndUnfoldingVarsDSet,
    
    31 31
             bndrRuleAndUnfoldingIds,
    
    32
    -        idFVs,
    
    33
    -        idRuleVars, stableUnfoldingVars,
    
    32
    +        idFVs, idRuleVars,
    
    33
    +        stableUnfoldingVars,
    
    34
    +        unfoldingFVs,
    
    34 35
             ruleFreeVars, rulesFreeVars,
    
    35 36
             rulesFreeVarsDSet, mkRuleInfo,
    
    36 37
             ruleLhsFreeIds, ruleLhsFreeIdsList,
    
    37 38
             ruleRhsFreeVars, rulesRhsFreeIds,
    
    39
    +        rulesFVs, RuleFVsFrom(..),
    
    38 40
     
    
    39 41
             exprFVs, exprLocalFVs, addBndrFV, addBndrsFV,
    
    40 42
     
    
    ... ... @@ -645,17 +647,18 @@ idUnfoldingFVs id = stableUnfoldingFVs (realIdUnfolding id) `orElse` emptyFV
    645 647
     stableUnfoldingVars :: Unfolding -> Maybe VarSet
    
    646 648
     stableUnfoldingVars unf = fvVarSet `fmap` stableUnfoldingFVs unf
    
    647 649
     
    
    648
    -stableUnfoldingFVs :: Unfolding -> Maybe FV
    
    649 650
     stableUnfoldingFVs unf
    
    650
    -  = case unf of
    
    651
    -      CoreUnfolding { uf_tmpl = rhs, uf_src = src }
    
    652
    -         | isStableSource src
    
    653
    -         -> Just (exprLocalFVs rhs)
    
    654
    -      DFunUnfolding { df_bndrs = bndrs, df_args = args }
    
    655
    -         -> Just (filterFV isLocalVar $ FV.delFVs (mkVarSet bndrs) $ exprsFVs args)
    
    656
    -            -- DFuns are top level, so no fvs from types of bndrs
    
    657
    -      _other -> Nothing
    
    658
    -
    
    651
    +  | isStableUnfolding unf = Just (unfoldingFVs unf)
    
    652
    +  | otherwise             = Nothing
    
    653
    +
    
    654
    +unfoldingFVs :: Unfolding -> FV
    
    655
    +unfoldingFVs (CoreUnfolding { uf_tmpl = rhs })
    
    656
    +  = exprLocalFVs rhs
    
    657
    +unfoldingFVs (DFunUnfolding { df_bndrs = bndrs, df_args = args })
    
    658
    +  = FV.delFVs (mkVarSet bndrs) $ exprsLocalFVs args
    
    659
    +    -- DFuns are top level, so no fvs from types of bndrs
    
    660
    +unfoldingFVs _
    
    661
    +  = emptyFV
    
    659 662
     
    
    660 663
     {-
    
    661 664
     ************************************************************************
    

  • compiler/GHC/Core/Lint.hs
    ... ... @@ -82,7 +82,6 @@ import GHC.Types.Basic
    82 82
     import GHC.Types.Demand      ( splitDmdSig, isDeadEndDiv )
    
    83 83
     
    
    84 84
     import GHC.Builtin.Names
    
    85
    -import GHC.Builtin.Types.Prim
    
    86 85
     
    
    87 86
     import GHC.Data.Bag
    
    88 87
     import GHC.Data.List.SetOps
    
    ... ... @@ -589,19 +588,20 @@ lintLetBind top_lvl rec_flag binder rhs rhs_ty
    589 588
     
    
    590 589
             -- Check the let-can-float invariant
    
    591 590
             -- See Note [Core let-can-float invariant] in GHC.Core
    
    592
    -       ; checkL ( isJoinId binder
    
    593
    -               || mightBeLiftedType binder_ty
    
    594
    -               || (isNonRec rec_flag && exprOkForSpeculation rhs)
    
    595
    -               || isDataConWorkId binder || isDataConWrapId binder -- until #17521 is fixed
    
    596
    -               || exprIsTickedString rhs)
    
    597
    -           (badBndrTyMsg binder (text "unlifted"))
    
    598
    -
    
    599
    -        -- Check that if the binder is at the top level and has type Addr#,
    
    600
    -        -- that it is a string literal.
    
    591
    +       ; checkL (  isTopLevel top_lvl
    
    592
    +                || isJoinId binder
    
    593
    +                || mightBeLiftedType binder_ty
    
    594
    +                || (isNonRec rec_flag && exprOkForSpeculation rhs)) $
    
    595
    +         badBndrTyMsg binder (text "unlifted")
    
    596
    +
    
    597
    +        -- Check that if the binder is at the top level the binding
    
    598
    +        -- satisfies exprIsTopLevelBindable
    
    601 599
             -- See Note [Core top-level string literals].
    
    602
    -       ; checkL (not (isTopLevel top_lvl && binder_ty `eqType` addrPrimTy)
    
    603
    -                 || exprIsTickedString rhs)
    
    604
    -           (mkTopNonLitStrMsg binder)
    
    600
    +       ; checkL (  not (isTopLevel top_lvl)
    
    601
    +                || exprIsTopLevelBindable rhs binder_ty
    
    602
    +                || isDataConWorkId binder || isDataConWrapId binder -- until #17521 is fixed
    
    603
    +                ) $
    
    604
    +         mkTopNonLitStrMsg binder
    
    605 605
     
    
    606 606
            ; flags <- getLintFlags
    
    607 607
     
    
    ... ... @@ -942,7 +942,7 @@ lintCoreExpr (Let (NonRec tv (Type ty)) body)
    942 942
       | isTyVar tv
    
    943 943
       =     -- See Note [Linting type lets]
    
    944 944
         do  { ty' <- lintTypeAndSubst ty
    
    945
    -        ; lintTyCoBndr tv              $ \ tv' ->
    
    945
    +        ; lintTyVarBndr tv              $ \ tv' ->
    
    946 946
         do  { addLoc (RhsOf tv) $ lintTyKind tv' ty'
    
    947 947
                     -- Now extend the substitution so we
    
    948 948
                     -- take advantage of it in the body
    
    ... ... @@ -1796,24 +1796,24 @@ lintBinders site (var:vars) linterF = lintBinder site var $ \var' ->
    1796 1796
     -- See Note [GHC Formalism]
    
    1797 1797
     lintBinder :: HasDebugCallStack => BindingSite -> InVar -> (OutVar -> LintM a) -> LintM a
    
    1798 1798
     lintBinder site var linterF
    
    1799
    -  | isTyCoVar var = lintTyCoBndr var linterF
    
    1800
    -  | otherwise     = lintIdBndr NotTopLevel site var linterF
    
    1799
    +  | isTyVar var = lintTyVarBndr var linterF
    
    1800
    +  | otherwise   = lintIdBndr NotTopLevel site var linterF
    
    1801 1801
     
    
    1802
    -lintTyCoBndr :: HasDebugCallStack => TyCoVar -> (OutTyCoVar -> LintM a) -> LintM a
    
    1803
    -lintTyCoBndr tcv thing_inside
    
    1802
    +lintTyCoBndr :: HasDebugCallStack => InTyCoVar
    
    1803
    +                                  -> (OutTyCoVar -> LintM a) -> LintM a
    
    1804
    +lintTyCoBndr var linterF
    
    1805
    +  | isTyVar var = lintTyVarBndr var linterF
    
    1806
    +  | otherwise   = lintIdBndr NotTopLevel LambdaBind var linterF
    
    1807
    +
    
    1808
    +lintTyVarBndr :: HasDebugCallStack => InTyVar -> (OutTyVar -> LintM a) -> LintM a
    
    1809
    +lintTyVarBndr tcv thing_inside
    
    1804 1810
       = do { tcv_type' <- lintTypeAndSubst (varType tcv)
    
    1805 1811
            ; let tcv_kind' = typeKind tcv_type'
    
    1806 1812
     
    
    1807
    -         -- See (FORALL1) and (FORALL2) in GHC.Core.Type
    
    1808
    -       ; if (isTyVar tcv)
    
    1809
    -         then -- Check that in (forall (a:ki). blah) we have ki:Type
    
    1810
    -              lintL (isLiftedTypeKind tcv_kind') $
    
    1813
    +         -- See (FORALL1) in GHC.Core.Type
    
    1814
    +       ; lintL (isLiftedTypeKind tcv_kind') $
    
    1811 1815
                   hang (text "TyVar whose kind does not have kind Type:")
    
    1812 1816
                      2 (ppr tcv <+> dcolon <+> ppr tcv_type' <+> dcolon <+> ppr tcv_kind')
    
    1813
    -         else -- Check that in (forall (cv::ty). blah),
    
    1814
    -              -- then ty looks like (t1 ~# t2)
    
    1815
    -              lintL (isCoVarType tcv_type') $
    
    1816
    -              text "CoVar with non-coercion type:" <+> pprTyVar tcv
    
    1817 1817
     
    
    1818 1818
            ; addInScopeTyCoVar tcv tcv_type' thing_inside }
    
    1819 1819
     
    
    ... ... @@ -1858,19 +1858,21 @@ lintIdBndr top_lvl bind_site id thing_inside
    1858 1858
              checkL (not is_top_lvl && is_let_bind) $
    
    1859 1859
              mkBadJoinBindMsg id
    
    1860 1860
     
    
    1861
    -       -- Check that the Id does not have type (t1 ~# t2) or (t1 ~R# t2);
    
    1862
    -       -- if so, it should be a CoVar, and checked by lintCoVarBndr
    
    1863
    -       ; lintL (not (isCoVarType id_ty))
    
    1864
    -               (text "Non-CoVar has coercion type" <+> ppr id <+> dcolon <+> ppr id_ty)
    
    1861
    +       -- Check that the Id is a CoVar <=> has type  (t1 ~# t2) or (t1 ~R# t2);
    
    1862
    +       ; lintL (isCoVar id == isCoVarType id_ty) $
    
    1863
    +         hang (text "CoVar with non-coercion type or vice versa:")
    
    1864
    +            2 (ppr id <+> dcolon <+> ppr id_ty)
    
    1865 1865
     
    
    1866 1866
            -- Check that the lambda binder has no value or OtherCon unfolding.
    
    1867 1867
            -- See #21496
    
    1868 1868
            ; lintL (not (bind_site == LambdaBind && isEvaldUnfolding (idUnfolding id)))
    
    1869
    -                (text "Lambda binder with value or OtherCon unfolding.")
    
    1869
    +               (text "Lambda binder with value or OtherCon unfolding.")
    
    1870 1870
     
    
    1871 1871
            ; out_ty <- addLoc (IdTy id) (lintValueType id_ty)
    
    1872 1872
     
    
    1873
    -       ; addInScopeId id out_ty thing_inside }
    
    1873
    +       ; if isCoVar id
    
    1874
    +         then addInScopeTyCoVar id out_ty thing_inside
    
    1875
    +         else addInScopeId      id out_ty thing_inside }
    
    1874 1876
       where
    
    1875 1877
         id_ty = idType id
    
    1876 1878
     
    

  • compiler/GHC/Core/Opt/Simplify/Env.hs
    ... ... @@ -934,6 +934,8 @@ addJoinFlts = appOL
    934 934
     mkRecFloats :: SimplFloats -> SimplFloats
    
    935 935
     -- Flattens the floats into a single Rec group,
    
    936 936
     -- They must either all be lifted LetFloats or all JoinFloats
    
    937
    +--
    
    938
    +-- ToDo: explain about CoVar floats
    
    937 939
     mkRecFloats floats@(SimplFloats { sfLetFloats  = LetFloats bs _ff
    
    938 940
                                     , sfJoinFloats = jbs
    
    939 941
                                     , sfInScope    = in_scope })
    
    ... ... @@ -944,9 +946,24 @@ mkRecFloats floats@(SimplFloats { sfLetFloats = LetFloats bs _ff
    944 946
       where
    
    945 947
         -- See Note [Bangs in the Simplifier]
    
    946 948
         !floats'  | isNilOL bs  = emptyLetFloats
    
    947
    -              | otherwise   = unitLetFloat (Rec (flattenBinds (fromOL bs)))
    
    949
    +              | otherwise   = LetFloats (flatten_rec bs) FltLifted
    
    948 950
         !jfloats' | isNilOL jbs = emptyJoinFloats
    
    949
    -              | otherwise   = unitJoinFloat (Rec (flattenBinds (fromOL jbs)))
    
    951
    +              | otherwise   = flatten_rec jbs
    
    952
    +
    
    953
    +    flatten_rec :: OrdList OutBind -> OrdList OutBind
    
    954
    +    -- Put CoVar bindings first (guaranteed non-recursive)
    
    955
    +    -- then one recursive value binding
    
    956
    +    flatten_rec bs = let !(covar_bs, prs) = foldrOL do_one (nilOL, []) bs
    
    957
    +                     in covar_bs `snocOL` Rec prs
    
    958
    +
    
    959
    +    do_one :: OutBind -> (OrdList OutBind,[(OutId,OutExpr)])
    
    960
    +                      -> (OrdList OutBind,[(OutId,OutExpr)])
    
    961
    +    do_one bind (cvbs, prs)
    
    962
    +      = case bind of
    
    963
    +          NonRec bndr rhs
    
    964
    +            | isCoVar bndr -> (bind `consOL` cvbs, prs)
    
    965
    +            | otherwise    -> (cvbs,               (bndr,rhs):prs)
    
    966
    +          Rec prs1         -> (cvbs,               prs1 ++ prs)
    
    950 967
     
    
    951 968
     wrapFloats :: SimplFloats -> OutExpr -> OutExpr
    
    952 969
     -- Wrap the floats around the expression
    

  • compiler/GHC/Core/Opt/Simplify/Iteration.hs
    ... ... @@ -298,6 +298,7 @@ simplRecOrTopPair env bind_cxt old_bndr new_bndr rhs
    298 298
                                                  (old_bndr,env) (new_bndr,env) (rhs,env)
    
    299 299
     
    
    300 300
     simplTrace :: String -> SDoc -> SimplM a -> SimplM a
    
    301
    +-- Spit out a trace with `-dverbose-core2core`
    
    301 302
     simplTrace herald doc thing_inside = do
    
    302 303
       logger <- getLogger
    
    303 304
       if logHasDumpFlag logger Opt_D_verbose_core2core
    
    ... ... @@ -762,18 +763,15 @@ prepareRhs :: HasDebugCallStack
    762 763
     -- See Note [prepareRhs]
    
    763 764
     prepareRhs env top_lvl occ rhs0
    
    764 765
       | is_expandable = do { (flts,rhs) <- anfise rhs0
    
    765
    -                       ; pprTrace "prepareRhs" (ppr rhs0 $$ text "new" <+> ppr rhs) $
    
    766
    -                         return (flts, rhs) }
    
    766
    +                       ; return (flts, rhs) }
    
    767 767
       | otherwise     = return (emptyLetFloats, rhs0)
    
    768 768
       where
    
    769
    -    -- We can't use exprIsExpandable because the WHOLE POINT is that
    
    770
    -    -- we want to treat (K <big>) as expandable, because we are just
    
    771
    -    -- about "anfise" the <big> expression.  exprIsExpandable would
    
    772
    -    -- just say no!
    
    769
    +    -- We can't use exprIsExpandable because the WHOLE POINT is that we want to
    
    770
    +    -- treat (K <big>) as expandable, because we are just about "anfise" the
    
    771
    +    -- <big> expression.  exprIsExpandable would just say no!
    
    773 772
         is_expandable = go rhs0 0
    
    774 773
            where
    
    775
    -         go (Var fun) n_val_args       = pprTrace "is_exp" (ppr fun <+> ppr n_val_args $$ ppr (isExpandableApp fun n_val_args)) $
    
    776
    -                                         isExpandableApp fun n_val_args
    
    774
    +         go (Var fun) n_val_args       = isExpandableApp fun n_val_args
    
    777 775
              go (App fun arg) n_val_args
    
    778 776
                | isTypeArg arg             = go fun n_val_args
    
    779 777
                | otherwise                 = go fun (n_val_args + 1)
    

  • compiler/GHC/Core/Opt/Simplify/Utils.hs
    ... ... @@ -2251,9 +2251,12 @@ new binding is abstracted. Several points worth noting
    2251 2251
     abstractFloats :: UnfoldingOpts -> TopLevelFlag -> [OutTyVar] -> SimplFloats
    
    2252 2252
                   -> OutExpr -> SimplM ([OutBind], OutExpr)
    
    2253 2253
     abstractFloats uf_opts top_lvl main_tvs floats body
    
    2254
    -  = assert (notNull body_floats) $
    
    2254
    +  | assert (notNull body_floats) $
    
    2255 2255
         assert (isNilOL (sfJoinFloats floats)) $
    
    2256
    -    do  { let sccs = concatMap to_sccs body_floats
    
    2256
    +    any isCoVar (bindersOfBinds body_floats)   -- ToDo: Explain this case
    
    2257
    +  = return ([], wrapFloats floats body)
    
    2258
    +  | otherwise
    
    2259
    +  = do  { let sccs = concatMap to_sccs body_floats
    
    2257 2260
             ; (subst, float_binds) <- mapAccumLM abstract empty_subst sccs
    
    2258 2261
             ; return (float_binds, GHC.Core.Subst.substExpr subst body) }
    
    2259 2262
       where
    

  • compiler/GHC/Core/TyCo/Rep.hs
    1
    +{-# LANGUAGE MagicHash #-}
    
    1 2
     {-# OPTIONS_HADDOCK not-home #-}
    
    2 3
     
    
    3 4
     {-
    
    ... ... @@ -63,7 +64,7 @@ module GHC.Core.TyCo.Rep (
    63 64
             TyCoFolder(..), foldTyCo, noView,
    
    64 65
     
    
    65 66
             -- * Sizes
    
    66
    -        typeSize, typesSize, coercionSize,
    
    67
    +        typeSize, typesSize, coercionSize, coercionIsSmall,
    
    67 68
     
    
    68 69
             -- * Multiplicities
    
    69 70
             Scaled(..), scaledMult, scaledThing, mapScaledType, Mult
    
    ... ... @@ -96,8 +97,8 @@ import GHC.Utils.Panic
    96 97
     import GHC.Utils.Binary
    
    97 98
     
    
    98 99
     -- libraries
    
    100
    +import GHC.Exts
    
    99 101
     import qualified Data.Data as Data hiding ( TyCon )
    
    100
    -import Data.Coerce
    
    101 102
     import Data.IORef ( IORef )   -- for CoercionHole
    
    102 103
     import Control.DeepSeq
    
    103 104
     
    
    ... ... @@ -2093,6 +2094,61 @@ mCoercionSize :: MCoercion -> Int
    2093 2094
     mCoercionSize MRefl    = 0
    
    2094 2095
     mCoercionSize (MCo co) = coercionSize co
    
    2095 2096
     
    
    2097
    +coercionIsSmall :: Coercion -> Bool
    
    2098
    +-- This function is called inside `exprIsTrivial` so it needs to be
    
    2099
    +-- pretty efficient.  It should return False quickly on a big coercion;
    
    2100
    +-- it should /not/ traverse the big coercion!
    
    2101
    +coercionIsSmall co
    
    2102
    +  = not (isTrue# ((coercion_is_small co 100#) <# 0#))
    
    2103
    +
    
    2104
    +coercion_is_small :: Coercion -> Int# -> Int#
    
    2105
    +coercion_is_small co n = go co n
    
    2106
    +  where
    
    2107
    +    go :: Coercion -> Int# -> Int#
    
    2108
    +    go _co n | isTrue# (n <# 0#)   = n
    
    2109
    +    go (Refl ty)                 n = type_is_small ty n
    
    2110
    +    go (GRefl _ ty mco)          n = type_is_small ty $ go_mco mco n
    
    2111
    +    go (TyConAppCo _ _ cos)      n = go_cos cos $ dec n
    
    2112
    +    go (AxiomCo _ cos)           n = go_cos cos $ dec n
    
    2113
    +    go (UnivCo _ _ _ _ cos)      n = go_cos cos $ dec n
    
    2114
    +    go (AppCo co1 co2)           n = go co1 $ go co2 $ dec n
    
    2115
    +    go (CoVarCo {})              n = dec n
    
    2116
    +    go (HoleCo {})               n = dec n
    
    2117
    +    go (SymCo co)                n = go co $ dec n
    
    2118
    +    go (KindCo co)               n = go co $ dec n
    
    2119
    +    go (SubCo co)                n = go co $ dec n
    
    2120
    +    go (TransCo co1 co2)         n = go co1 $ go co2 $ dec n
    
    2121
    +    go (SelCo _  co)             n = go co $ dec n
    
    2122
    +    go (LRCo _  co)              n = go co $ dec n
    
    2123
    +    go (InstCo co1 co2)          n = go co1 $ go co2 $ dec n
    
    2124
    +    go (ForAllCo _ _ _ kco co)   n = go co $ go_mco kco $ dec n
    
    2125
    +    go (FunCo _ _ _ mco aco rco) n = go mco $ go aco $ go rco $ dec n
    
    2126
    +
    
    2127
    +    go_cos []       n = n
    
    2128
    +    go_cos (co:cos) n = go_cos cos (go co n)
    
    2129
    +
    
    2130
    +    go_mco MRefl    n = dec n
    
    2131
    +    go_mco (MCo co) n = go co n
    
    2132
    +
    
    2133
    +type_is_small :: Type -> Int# -> Int#
    
    2134
    +type_is_small ty n = go ty n
    
    2135
    +  where
    
    2136
    +    go _ty n | isTrue# (n <# 0#) = n
    
    2137
    +    go (TyVarTy {})      n = dec n
    
    2138
    +    go (LitTy {})        n = dec n
    
    2139
    +    go (AppTy t1 t2)     n = go t1 $ go t2 $ dec n
    
    2140
    +    go (TyConApp _ tys) n = go_tys tys $ dec n
    
    2141
    +    go (ForAllTy _ ty)   n = go ty $ dec n
    
    2142
    +    go (FunTy _ m a r)   n = go m $ go a $ go r $ dec n
    
    2143
    +    go (CastTy ty co)    n = go ty $ coercion_is_small co $ dec n
    
    2144
    +    go (CoercionTy co)   n = coercion_is_small co n
    
    2145
    +
    
    2146
    +    go_tys []       n = n
    
    2147
    +    go_tys (ty:tys) n = go ty $ go_tys tys n
    
    2148
    +
    
    2149
    +dec :: Int# -> Int#
    
    2150
    +dec n = n -# 1#
    
    2151
    +
    
    2096 2152
     {-
    
    2097 2153
     ************************************************************************
    
    2098 2154
     *                                                                      *
    

  • compiler/GHC/Core/Utils.hs
    ... ... @@ -31,7 +31,7 @@ module GHC.Core.Utils (
    31 31
             exprIsWorkFree, exprIsConLike,
    
    32 32
             isCheapApp, isExpandableApp, isSaturatedConApp,
    
    33 33
             exprIsTickedString, exprIsTickedString_maybe,
    
    34
    -        exprIsTopLevelBindable,
    
    34
    +        exprIsCoercion, exprIsTopLevelBindable,
    
    35 35
             exprIsUnaryClassFun, isUnaryClassId,
    
    36 36
             altsAreExhaustive, etaExpansionTick,
    
    37 37
     
    
    ... ... @@ -1331,8 +1331,7 @@ exprIsTrivial e = trivial_expr_fold
    1331 1331
                           (const True)     -- Literals
    
    1332 1332
                           (const True)     -- Types
    
    1333 1333
                           coercionIsSmall  -- Coercions
    
    1334
    -                      (\ r co -> pprTrace "exprIsTrivial" (ppr (coercionIsSmall co) $$ ppr co) $
    
    1335
    -                                 r && coercionIsSmall co)  -- Casts
    
    1334
    +                      (\ r co -> r && coercionIsSmall co)  -- Casts
    
    1336 1335
                           False e
    
    1337 1336
     
    
    1338 1337
     {-
    

  • compiler/GHC/CoreToStg.hs
    ... ... @@ -599,8 +599,10 @@ getStgArgFromTrivialArg :: HasDebugCallStack => CoreArg -> StgArg
    599 599
     -- `case unsafeequalityProof of UnsafeRefl -> e` might intervene.
    
    600 600
     -- Good thing we can just call `trivial_expr_fold` here.
    
    601 601
     getStgArgFromTrivialArg e = trivial_expr_fold StgVarArg StgLitArg
    
    602
    -                                panic panic panic panic e
    
    602
    +                                panic panic get_cast panic e
    
    603 603
       where
    
    604
    +    get_cast r _ = r
    
    605
    +
    
    604 606
         panic :: forall a. a
    
    605 607
         panic = pprPanic "getStgArgFromTrivialArg" (ppr e)
    
    606 608
     
    

  • compiler/GHC/CoreToStg/Prep.hs
    ... ... @@ -2169,6 +2169,7 @@ data FloatInfoArgs
    2169 2169
       , fia_is_hnf :: Bool
    
    2170 2170
       , fia_is_triv :: Bool
    
    2171 2171
       , fia_is_string :: Bool
    
    2172
    +  , fia_is_coercion :: Bool
    
    2172 2173
       , fia_is_dc_worker :: Bool
    
    2173 2174
       , fia_ok_for_spec :: Bool
    
    2174 2175
       }
    
    ... ... @@ -2181,14 +2182,17 @@ defFloatInfoArgs bndr rhs
    2181 2182
       , fia_is_hnf = exprIsHNF rhs
    
    2182 2183
       , fia_is_triv = exprIsTrivial rhs
    
    2183 2184
       , fia_is_string = exprIsTickedString rhs
    
    2185
    +  , fia_is_coercion = exprIsCoercion rhs
    
    2184 2186
       , fia_is_dc_worker = isJust (isDataConId_maybe bndr) -- mkCaseFloat uses False
    
    2185 2187
       , fia_ok_for_spec = False -- mkNonRecFloat uses exprOkForSpecEval
    
    2186 2188
       }
    
    2187 2189
     
    
    2188 2190
     decideFloatInfo :: FloatInfoArgs -> (BindInfo, FloatInfo)
    
    2189 2191
     decideFloatInfo FIA{fia_levity=lev, fia_demand=dmd, fia_is_hnf=is_hnf,
    
    2190
    -                    fia_is_triv=is_triv, fia_is_string=is_string,
    
    2192
    +                    fia_is_triv=is_triv, fia_is_string=is_string, fia_is_coercion = is_coercion,
    
    2191 2193
                         fia_is_dc_worker=is_dc_worker, fia_ok_for_spec=ok_for_spec}
    
    2194
    +  -- NB: this function should line up with exprIsTopLevelBindable
    
    2195
    +  -- ToDo: explain a bit more
    
    2192 2196
       | Lifted <- lev, is_hnf, not is_triv = (LetBound, TopLvlFloatable)
    
    2193 2197
           -- is_lifted: We currently don't allow unlifted values at the
    
    2194 2198
           --            top-level or inside letrecs
    
    ... ... @@ -2199,8 +2203,9 @@ decideFloatInfo FIA{fia_levity=lev, fia_demand=dmd, fia_is_hnf=is_hnf,
    2199 2203
           -- We need this special case for nullary unlifted DataCon
    
    2200 2204
           -- workers/wrappers (top-level bindings) until #17521 is fixed
    
    2201 2205
       | is_string             = (CaseBound, TopLvlFloatable)
    
    2206
    +  | is_coercion           = (LetBound,  TopLvlFloatable)
    
    2202 2207
           -- String literals are unboxed (so must be case-bound) and float to
    
    2203
    -      -- the top-level
    
    2208
    +      -- the top-level. Coercion are ok at top level too.
    
    2204 2209
       | ok_for_spec           = (CaseBound, case lev of Unlifted -> LazyContextFloatable
    
    2205 2210
                                                         Lifted   -> TopLvlFloatable)
    
    2206 2211
           -- See Note [Speculative evaluation]
    

  • compiler/GHC/Driver/Config/Core/Lint.hs
    ... ... @@ -149,10 +149,12 @@ perPassFlags dflags pass
    149 149
                               _                     -> AllowAnywhere
    
    150 150
     
    
    151 151
         -- See Note [Linting linearity]
    
    152
    -    check_linearity = gopt Opt_DoLinearCoreLinting dflags || (
    
    153
    -                        case pass of
    
    152
    +    check_linearity = gopt Opt_DoLinearCoreLinting dflags
    
    153
    +                          -- `-dlinear-core-lint`: check linearity in every pass
    
    154
    +                    || -- Always check linearity just after desugaring
    
    155
    +                       case pass of
    
    154 156
                               CoreDesugar -> True
    
    155
    -                          _ -> False)
    
    157
    +                          _ -> False
    
    156 158
     
    
    157 159
         -- See Note [Checking for rubbish literals] in GHC.Core.Lint
    
    158 160
         check_rubbish = case pass of
    

  • compiler/GHC/Iface/Tidy.hs
    ... ... @@ -58,6 +58,7 @@ import GHC.Core.Opt.OccurAnal ( occurAnalyseExpr )
    58 58
     import GHC.Iface.Tidy.StaticPtrTable
    
    59 59
     import GHC.Iface.Env
    
    60 60
     
    
    61
    +import GHC.Utils.FV
    
    61 62
     import GHC.Utils.Outputable
    
    62 63
     import GHC.Utils.Misc( filterOut )
    
    63 64
     import GHC.Utils.Panic
    
    ... ... @@ -89,7 +90,6 @@ import GHC.Unit.Module.Deps
    89 90
     
    
    90 91
     import GHC.Data.Maybe
    
    91 92
     
    
    92
    -import Control.Monad
    
    93 93
     import Data.Function
    
    94 94
     import Data.List        ( sortBy, mapAccumL )
    
    95 95
     import qualified Data.Set as S
    
    ... ... @@ -826,71 +826,7 @@ See Note [Choosing external Ids]
    826 826
     -}
    
    827 827
     
    
    828 828
     bndrFvsInOrder :: Bool -> Id -> [Id]
    
    829
    -bndrFvsInOrder show_unfold id
    
    830
    -  = run (dffvLetBndr show_unfold id)
    
    831
    -
    
    832
    -run :: DFFV () -> [Id]
    
    833
    -run (DFFV m) = case m emptyVarSet (emptyVarSet, []) of
    
    834
    -                 ((_,ids),_) -> ids
    
    835
    -
    
    836
    -newtype DFFV a
    
    837
    -  = DFFV (VarSet              -- Envt: non-top-level things that are in scope
    
    838
    -                              -- we don't want to record these as free vars
    
    839
    -      -> (VarSet, [Var])      -- Input State: (set, list) of free vars so far
    
    840
    -      -> ((VarSet,[Var]),a))  -- Output state
    
    841
    -    deriving (Functor)
    
    842
    -
    
    843
    -instance Applicative DFFV where
    
    844
    -    pure a = DFFV $ \_ st -> (st, a)
    
    845
    -    (<*>) = ap
    
    846
    -
    
    847
    -instance Monad DFFV where
    
    848
    -  (DFFV m) >>= k = DFFV $ \env st ->
    
    849
    -    case m env st of
    
    850
    -       (st',a) -> case k a of
    
    851
    -                     DFFV f -> f env st'
    
    852
    -
    
    853
    -extendScope :: Var -> DFFV a -> DFFV a
    
    854
    -extendScope v (DFFV f) = DFFV (\env st -> f (extendVarSet env v) st)
    
    855
    -
    
    856
    -extendScopeList :: [Var] -> DFFV a -> DFFV a
    
    857
    -extendScopeList vs (DFFV f) = DFFV (\env st -> f (extendVarSetList env vs) st)
    
    858
    -
    
    859
    -insert :: Var -> DFFV ()
    
    860
    -insert v = DFFV $ \ env (set, ids) ->
    
    861
    -           let keep_me = isLocalId v &&
    
    862
    -                         not (v `elemVarSet` env) &&
    
    863
    -                           not (v `elemVarSet` set)
    
    864
    -           in if keep_me
    
    865
    -              then ((extendVarSet set v, v:ids), ())
    
    866
    -              else ((set,                ids),   ())
    
    867
    -
    
    868
    -
    
    869
    -dffvExpr :: CoreExpr -> DFFV ()
    
    870
    -dffvExpr (Var v)              = insert v
    
    871
    -dffvExpr (App e1 e2)          = dffvExpr e1 >> dffvExpr e2
    
    872
    -dffvExpr (Lam v e)            = extendScope v (dffvExpr e)
    
    873
    -dffvExpr (Tick (Breakpoint _ _ ids) e) = mapM_ insert ids >> dffvExpr e
    
    874
    -dffvExpr (Tick _other e)    = dffvExpr e
    
    875
    -dffvExpr (Cast e _)           = dffvExpr e
    
    876
    -dffvExpr (Let (NonRec x r) e) = dffvBind (x,r) >> extendScope x (dffvExpr e)
    
    877
    -dffvExpr (Let (Rec prs) e)    = extendScopeList (map fst prs) $
    
    878
    -                                (mapM_ dffvBind prs >> dffvExpr e)
    
    879
    -dffvExpr (Case e b _ as)      = dffvExpr e >> extendScope b (mapM_ dffvAlt as)
    
    880
    -dffvExpr _other               = return ()
    
    881
    -
    
    882
    -dffvAlt :: CoreAlt -> DFFV ()
    
    883
    -dffvAlt (Alt _ xs r) = extendScopeList xs (dffvExpr r)
    
    884
    -
    
    885
    -dffvBind :: (Id, CoreExpr) -> DFFV ()
    
    886
    -dffvBind(x,r)
    
    887
    -  | not (isId x) = dffvExpr r
    
    888
    -  | otherwise    = dffvLetBndr False x >> dffvExpr r
    
    889
    -                -- Pass False because we are doing the RHS right here
    
    890
    -                -- If you say True you'll get *exponential* behaviour!
    
    891
    -
    
    892
    -dffvLetBndr :: Bool -> Id -> DFFV ()
    
    893
    --- Gather the free vars of the RULES and unfolding of a binder
    
    829
    +-- Gather the free vars of the type, RULES and unfolding of an Id bindeb
    
    894 830
     -- We always get the free vars of a *stable* unfolding, but
    
    895 831
     -- for a *vanilla* one (VanillaSrc), the flag controls what happens:
    
    896 832
     --   True <=> get fvs of even a *vanilla* unfolding
    
    ... ... @@ -899,24 +835,21 @@ dffvLetBndr :: Bool -> Id -> DFFV ()
    899 835
     --       we are taking the fvs of the RHS anyway
    
    900 836
     -- For top-level bindings (call from addExternal, via bndrFvsInOrder)
    
    901 837
     --       we say "True" if we are exposing that unfolding
    
    902
    -dffvLetBndr vanilla_unfold id
    
    903
    -  = do { go_unf (realUnfoldingInfo idinfo)
    
    904
    -       ; mapM_ go_rule (ruleInfoRules (ruleInfo idinfo)) }
    
    838
    +bndrFvsInOrder show_unfold id
    
    839
    +  = fvVarList $
    
    840
    +    filterFV isId $   -- Include CoVars, which can be top-level bound
    
    841
    +    tyCoFVsOfType (idType id) `unionFV`
    
    842
    +    unf_fvs                   `unionFV`
    
    843
    +    rules_fvs
    
    905 844
       where
    
    906 845
         idinfo = idInfo id
    
    907 846
     
    
    908
    -    go_unf (CoreUnfolding { uf_tmpl = rhs, uf_src = src })
    
    909
    -       | isStableSource src = dffvExpr rhs
    
    910
    -       | vanilla_unfold     = dffvExpr rhs
    
    911
    -       | otherwise          = return ()
    
    912
    -
    
    913
    -    go_unf (DFunUnfolding { df_bndrs = bndrs, df_args = args })
    
    914
    -             = extendScopeList bndrs $ mapM_ dffvExpr args
    
    915
    -    go_unf _ = return ()
    
    847
    +    unf_fvs :: FV
    
    848
    +    unf_fvs | show_unfold = unfoldingFVs (realUnfoldingInfo idinfo)
    
    849
    +            | otherwise   = emptyFV
    
    916 850
     
    
    917
    -    go_rule (BuiltinRule {}) = return ()
    
    918
    -    go_rule (Rule { ru_bndrs = bndrs, ru_rhs = rhs })
    
    919
    -      = extendScopeList bndrs (dffvExpr rhs)
    
    851
    +    rules_fvs :: FV
    
    852
    +    rules_fvs = rulesFVs RhsOnly (ruleInfoRules (ruleInfo idinfo))
    
    920 853
     
    
    921 854
     {-
    
    922 855
     ************************************************************************