Simon Peyton Jones pushed to branch wip/T27737 at Glasgow Haskell Compiler / GHC

Commits:

4 changed files:

Changes:

  • compiler/GHC/Core/Opt/Simplify/Env.hs
    ... ... @@ -43,8 +43,7 @@ module GHC.Core.Opt.Simplify.Env (
    43 43
             extendFloats, isEmptyJoinFloats,
    
    44 44
             doFloatFromRhs, getTopFloatBinds,
    
    45 45
     
    
    46
    -        -- * LetFloats
    
    47
    -        LetFloats, FloatEnable(..), emptyLetFloats, mapLetFloats,
    
    46
    +        FloatEnable(..), mapLetFloats,
    
    48 47
     
    
    49 48
             -- * JoinFloats
    
    50 49
             JoinFloat, JoinFloats, emptyJoinFloats,
    
    ... ... @@ -452,8 +451,8 @@ isEmptyFloats :: SimplFloats -> Bool
    452 451
     -- Precondition: used only when sfJoins is empty
    
    453 452
     isEmptyFloats (SimplFloats { sfBinds = fs
    
    454 453
                                , sfJoins = js })
    
    455
    -  = assertPpr (isNilOL js) (ppr js ) $
    
    456
    -    isNilOL fs
    
    454
    +  = assertPpr (isEmptyJoinFloats js) (ppr js ) $
    
    455
    +    isEmptyFloatBinds fs
    
    457 456
     
    
    458 457
     pprSimplEnv :: SimplEnv -> SDoc
    
    459 458
     -- Used for debugging; selective
    
    ... ... @@ -738,7 +737,7 @@ setSubstEnv env tvs cvs ids = env { seTvSubst = tvs, seCvSubst = cvs, seIdSubst
    738 737
     {-
    
    739 738
     ************************************************************************
    
    740 739
     *                                                                      *
    
    741
    -\subsection{LetFloats}
    
    740
    +\subsection{Floats}
    
    742 741
     *                                                                      *
    
    743 742
     ************************************************************************
    
    744 743
     
    
    ... ... @@ -891,15 +890,13 @@ let-bindings that can, and wrap the rest back around the RHS. We tried this
    891 890
     difference to compile time, so we did not keep it.
    
    892 891
     -}
    
    893 892
     
    
    894
    -type LetFloats = OrdList OutBind
    
    895
    -  -- Let-bindings only: no case-floats or tick-floats
    
    896
    -  -- Invariant: every binding satisfies the let-can-float invariant
    
    897
    -
    
    898 893
     type JoinFloat  = OutBind
    
    899 894
     type JoinFloats = OrdList JoinFloat
    
    900 895
     
    
    901 896
     doFloatFromRhs :: SimplEnv -> TopLevelFlag -> RecFlag
    
    902
    -               -> SimplFloats -> LetFloats
    
    897
    +               -> SimplFloats
    
    898
    +               -> OrdList OutBind  -- Let-bindings only (from prepareRhs); they
    
    899
    +                                   -- satisfy the let-can-float invariant
    
    903 900
                    -> OutExpr
    
    904 901
                    -> Maybe SimplFloats   -- Contains let-bindings only
    
    905 902
     -- See Note [doFloatFromRhs]
    
    ... ... @@ -908,10 +905,11 @@ doFloatFromRhs :: SimplEnv -> TopLevelFlag -> RecFlag
    908 905
     --
    
    909 906
     -- If you change this function look also at FloatIn.noFloatIntoRhs
    
    910 907
     doFloatFromRhs env lvl rec floats anf_lets rhs
    
    911
    -  | not float_enabled = Nothing
    
    912
    -  | not want_to_float = Nothing
    
    913
    -  | not can_float     = Nothing
    
    914
    -  | otherwise         = Just new_floats
    
    908
    +  | isNilOL fs, isNilOL anf_lets = Nothing  -- Short cut only
    
    909
    +  | not float_enabled            = Nothing
    
    910
    +  | not want_to_float            = Nothing
    
    911
    +  | not can_float                = Nothing
    
    912
    +  | otherwise                    = Just new_floats
    
    915 913
       where
    
    916 914
         !(SimplFloats { sfBinds = fs, sfJoins = jfs, sfInScope = in_scope }) = floats
    
    917 915
         new_floats = assertPpr (isNilOL jfs) (ppr jfs) $
    
    ... ... @@ -952,9 +950,6 @@ doFloatFromRhs env lvl rec floats anf_lets rhs
    952 950
                            FloatNestedOnly -> not (isTopLevel lvl)
    
    953 951
                            FloatEnabled    -> True
    
    954 952
     
    
    955
    -emptyLetFloats :: LetFloats
    
    956
    -emptyLetFloats = nilOL
    
    957
    -
    
    958 953
     emptyJoinFloats :: JoinFloats
    
    959 954
     emptyJoinFloats = nilOL
    
    960 955
     
    
    ... ... @@ -1023,11 +1018,11 @@ extendFloats floats@(SimplFloats { sfJoins = jfloats, sfInScope = in_scope }) bi
    1023 1018
       | otherwise
    
    1024 1019
       = floats `addLetFloat` bind
    
    1025 1020
     
    
    1026
    -addLetFloats :: SimplFloats -> LetFloats -> SimplFloats
    
    1021
    +addLetFloats :: SimplFloats -> OrdList OutBind -> SimplFloats
    
    1027 1022
     -- Add the let-bindings /inside/ the existing floats,
    
    1028 1023
     -- and extend the in-scope set
    
    1029
    --- No need for addLetFloat's needsCaseBinding test: LetFloats satisfy the
    
    1030
    --- let-can-float invariant (see the declaration of LetFloats)
    
    1024
    +-- Precondition: the bindings satisfy the let-can-float invariant,
    
    1025
    +-- so there is no need for addLetFloat's needsCaseBinding test
    
    1031 1026
     addLetFloats floats binds = foldlOL add floats binds
    
    1032 1027
       where
    
    1033 1028
         add fs bind = assertPpr (okLetFloat bind) (ppr bind) $
    
    ... ... @@ -1091,7 +1086,7 @@ addJoinFlts = appOL
    1091 1086
     
    
    1092 1087
     mkRecFloats :: SimplFloats -> SimplFloats
    
    1093 1088
     -- Flattens the floats into a single Rec group,
    
    1094
    --- They must either all be lifted LetFloats or all JoinFloats
    
    1089
    +-- They must either all be lifted let-floats or all JoinFloats
    
    1095 1090
     mkRecFloats floats@(SimplFloats { sfBinds   = bs
    
    1096 1091
                                     , sfJoins   = jbs
    
    1097 1092
                                     , sfInScope = in_scope })
    
    ... ... @@ -1125,7 +1120,7 @@ getTopFloatBinds floats@(SimplFloats { sfJoins = jbs })
    1125 1120
         letFloatBinds floats
    
    1126 1121
     
    
    1127 1122
     {-# INLINE mapLetFloats #-}
    
    1128
    -mapLetFloats :: LetFloats -> ((Id,CoreExpr) -> (Id,CoreExpr)) -> LetFloats
    
    1123
    +mapLetFloats :: OrdList OutBind -> ((Id,CoreExpr) -> (Id,CoreExpr)) -> OrdList OutBind
    
    1129 1124
     mapLetFloats binds fun
    
    1130 1125
        = binds1
    
    1131 1126
        where
    

  • compiler/GHC/Core/Opt/Simplify/Iteration.hs
    ... ... @@ -64,7 +64,7 @@ import GHC.Builtin.WiredIn.Ids( seqId )
    64 64
     import qualified GHC.Data.List.Infinite as Inf
    
    65 65
     import GHC.Data.Maybe   ( isNothing, orElse, mapMaybe )
    
    66 66
     import GHC.Data.FastString
    
    67
    -import GHC.Data.OrdList ( unitOL, isNilOL, appOL, snocOL )
    
    67
    +import GHC.Data.OrdList ( OrdList, nilOL, unitOL, isNilOL, appOL, snocOL )
    
    68 68
     import GHC.Unit.Module ( moduleName )
    
    69 69
     import GHC.Utils.Outputable
    
    70 70
     import GHC.Utils.Panic
    
    ... ... @@ -764,7 +764,7 @@ prepareRhs :: HasDebugCallStack
    764 764
                => SimplEnvIS -> TopLevelFlag
    
    765 765
                -> FastString    -- Base for any new variables
    
    766 766
                -> OutExpr
    
    767
    -           -> SimplM (LetFloats, OutExpr)
    
    767
    +           -> SimplM (OrdList OutBind, OutExpr)
    
    768 768
     -- Transforms a RHS into a better RHS by ANF'ing args
    
    769 769
     -- for expandable RHSs: constructors and PAPs
    
    770 770
     -- e.g        x = Just e
    
    ... ... @@ -773,7 +773,7 @@ prepareRhs :: HasDebugCallStack
    773 773
     -- See Note [prepareRhs]
    
    774 774
     prepareRhs env top_lvl occ rhs0
    
    775 775
       | is_expandable = anfise rhs0
    
    776
    -  | otherwise     = return (emptyLetFloats, rhs0)
    
    776
    +  | otherwise     = return (nilOL, rhs0)
    
    777 777
       where
    
    778 778
         -- We can't use exprIsExpandable because the WHOLE POINT is that
    
    779 779
         -- we want to treat (K <big>) as expandable, because we are just
    
    ... ... @@ -789,7 +789,7 @@ prepareRhs env top_lvl occ rhs0
    789 789
              go (Tick _ rhs)  n_val_args   = go rhs n_val_args
    
    790 790
              go _             _            = False
    
    791 791
     
    
    792
    -    anfise :: OutExpr -> SimplM (LetFloats, OutExpr)
    
    792
    +    anfise :: OutExpr -> SimplM (OrdList OutBind, OutExpr)
    
    793 793
         anfise (Cast rhs co)
    
    794 794
             = do { (floats, rhs') <- anfise rhs
    
    795 795
                  ; return (floats, Cast rhs' co) }
    
    ... ... @@ -801,7 +801,7 @@ prepareRhs env top_lvl occ rhs0
    801 801
                  ; (floats2, arg') <- makeTrivial env top_lvl topDmd occ arg
    
    802 802
                  ; return (floats1 `appOL` floats2, App fun' arg') }
    
    803 803
         anfise (Var fun)
    
    804
    -        = return (emptyLetFloats, Var fun)
    
    804
    +        = return (nilOL, Var fun)
    
    805 805
     
    
    806 806
         anfise (Tick t rhs)
    
    807 807
             -- We want to be able to float bindings past this tick.
    
    ... ... @@ -819,28 +819,28 @@ prepareRhs env top_lvl occ rhs0
    819 819
                        floats' = mapLetFloats floats tickIt
    
    820 820
                  ; return (floats', Tick t rhs') }
    
    821 821
     
    
    822
    -    anfise other = return (emptyLetFloats, other)
    
    822
    +    anfise other = return (nilOL, other)
    
    823 823
     
    
    824 824
     makeTrivialArg :: HasDebugCallStack => SimplEnvIS -> ArgSpec
    
    825
    -               -> SimplM (LetFloats, ArgSpec)
    
    825
    +               -> SimplM (OrdList OutBind, ArgSpec)
    
    826 826
     makeTrivialArg env arg@(ValArg { as_arg = e, as_dmd = dmd })
    
    827 827
       = do { (floats, e') <- makeTrivial env NotTopLevel dmd (fsLit "arg") e
    
    828 828
            ; return (floats, arg { as_arg = e' }) }
    
    829 829
     makeTrivialArg _ arg@(TyArg {})
    
    830
    -  = return (emptyLetFloats, arg)
    
    830
    +  = return (nilOL, arg)
    
    831 831
     
    
    832 832
     makeTrivial :: HasDebugCallStack
    
    833 833
                 => SimplEnvIS -> TopLevelFlag -> Demand
    
    834 834
                 -> FastString  -- ^ A "friendly name" to build the new binder from
    
    835 835
                 -> OutExpr
    
    836
    -            -> SimplM (LetFloats, OutExpr)
    
    836
    +            -> SimplM (OrdList OutBind, OutExpr)
    
    837 837
     -- Binds the expression to a variable, if it's not trivial, returning the variable
    
    838 838
     -- For the Demand argument, see Note [Keeping demand info in StrictArg Plan A]
    
    839 839
     makeTrivial env top_lvl dmd occ_fs expr
    
    840 840
       | exprIsTrivial expr                          -- Already trivial
    
    841 841
       || not (bindingOk top_lvl expr expr_ty)       -- Cannot trivialise
    
    842 842
                                                     --   See Note [Cannot trivialise]
    
    843
    -  = return (emptyLetFloats, expr)
    
    843
    +  = return (nilOL, expr)
    
    844 844
     
    
    845 845
       | Cast expr' co <- expr
    
    846 846
       = do { (floats, triv_expr) <- makeTrivial env top_lvl dmd occ_fs expr'
    
    ... ... @@ -889,7 +889,7 @@ into
    889 889
     and thence, by floating, into
    
    890 890
         z = f y
    
    891 891
         x = Just z
    
    892
    -so that x is bound to a value.  It returns only let-bindings (LetFloats), so
    
    892
    +so that x is bound to a value.  It returns only let-bindings, so
    
    893 893
     sometimes it cannot trivialise its argument, and must return it unchanged.
    
    894 894
     
    
    895 895
     (CT1) Nested bindings.  Suppose that (f y) had type Int#, with a different data
    
    ... ... @@ -2015,7 +2015,13 @@ simpl_lam env bndr body cont
    2015 2015
             ; (env', bndrs') <- simplLamBndrs env (bndr:inner_bndrs)
    
    2016 2016
             ; body'   <- simplExpr env' inner_body
    
    2017 2017
             ; new_lam <- rebuildLam env' bndrs' body' cont
    
    2018
    -        ; rebuild env' new_lam cont }
    
    2018
    +        ; rebuild env new_lam cont }
    
    2019
    +  -- Subtle point: rebuild with env, not env': the lambda binders are not in
    
    2020
    +  -- scope outside the lambda, and should not end up in the in-scope set of the
    
    2021
    +  -- floats we return.  Why not?  Because a too-large in-scope set can lead to
    
    2022
    +  -- gratuitous renaming, and a non-empty substitution makes `substTy` do real
    
    2023
    +  -- work.  This happens, for example, if the function has a stable unfolding
    
    2024
    +  -- that uses the same binders, and cost 9% in compile time in T14683.
    
    2019 2025
     
    
    2020 2026
     -------------
    
    2021 2027
     simplLamBndr :: SimplEnv -> InBndr -> SimplM (SimplEnv, OutBndr)
    

  • compiler/GHC/Core/Opt/Simplify/Utils.hs
    ... ... @@ -74,6 +74,7 @@ import GHC.Types.InlinePragma
    74 74
     import GHC.Types.Tickish
    
    75 75
     import GHC.Types.Demand
    
    76 76
     import GHC.Types.Var.Set
    
    77
    +import GHC.Types.Var.Env ( extendInScopeSetList )
    
    77 78
     import GHC.Types.Basic
    
    78 79
     import GHC.Types.Name.Env
    
    79 80
     
    
    ... ... @@ -2518,7 +2519,8 @@ new binding is abstracted. Several points worth noting
    2518 2519
           manifestly a literal string.
    
    2519 2520
     -}
    
    2520 2521
     
    
    2521
    -abstractFloats :: SimplEnv -> TopLevelFlag -> [OutTyVar]
    
    2522
    +abstractFloats :: SimplEnv    -- Env outside the whole binding
    
    2523
    +               -> TopLevelFlag -> [OutTyVar]
    
    2522 2524
                    -> SimplFloats -- Let-bindings only: postcondition of `prepareBinding`
    
    2523 2525
                    -> OutExpr     -- The right-hand side of the binding
    
    2524 2526
                    -> SimplM (SimplFloats, OutExpr)
    
    ... ... @@ -2535,16 +2537,19 @@ abstractFloats env top_lvl main_tvs floats rhs
    2535 2537
     
    
    2536 2538
             ; return ( SimplFloats { sfBinds   = foldr (consOL . FloatLet) nilOL poly_binds
    
    2537 2539
                                    , sfJoins   = emptyJoinFloats
    
    2538
    -                               , sfInScope = substInScopeSet subst }
    
    2540
    +                               , sfInScope = foldl' extendInScopeSetBind in_scope poly_binds }
    
    2539 2541
                      , GHC.Core.Subst.substExpr subst rhs) }
    
    2540
    -        -- NB: the returned in-scope set includes `env` and all the
    
    2542
    +        -- NB: the returned in-scope set is the outer `in_scope` and all the
    
    2541 2543
             --     new floated bindings; but not main_tvs, nor the original floats
    
    2542
    -        -- The caller will used the returned in-scope set to cover the body of the let,
    
    2543
    -        -- and main_tvs and original floats are not in scope there
    
    2544
    +        -- The caller will use the returned in-scope set to cover the body of the let,
    
    2545
    +        -- and `main_tvs` and original floats are not in scope there
    
    2544 2546
             -- That reduces unnecessary renaming (see !7777 and test T16577)
    
    2545 2547
       where
    
    2546 2548
         !(SimplFloats { sfBinds = float_binds, sfJoins = jfs }) = floats
    
    2547
    -    empty_subst = GHC.Core.Subst.mkEmptySubst (seInScope env)
    
    2549
    +    in_scope    = seInScope env
    
    2550
    +    empty_subst = GHC.Core.Subst.mkEmptySubst (in_scope `extendInScopeSetList` main_tvs)
    
    2551
    +        -- main_tvs: the RHSs of the floats mention the main_tvs, so they must be
    
    2552
    +        -- in scope for substExpr (the original float binders are in the substitution)
    
    2548 2553
         is_top_lvl  = isTopLevel top_lvl
    
    2549 2554
         uf_opts     = seUnfoldingOpts env
    
    2550 2555
     
    

  • compiler/GHC/Core/SimpleOpt.hs
    ... ... @@ -1712,8 +1712,7 @@ exprIsConApp_maybe ise@(ISE in_scope id_unf) expr
    1712 1712
         subst_co (Right s) co = GHC.Core.Subst.substCo s co
    
    1713 1713
     
    
    1714 1714
         subst_expr (Left {}) e = e
    
    1715
    -    subst_expr (Right s) e = -- pprTrace "subst_expr" (text "subst" <+> ppr s $$ text "expr" <+> ppr e) $
    
    1716
    -                             substExpr s e
    
    1715
    +    subst_expr (Right s) e = substExpr s e
    
    1717 1716
     
    
    1718 1717
         subst_bndrs subst bs = mapAccumL subst_bndr subst bs
    
    1719 1718
     
    
    ... ... @@ -1723,8 +1722,7 @@ exprIsConApp_maybe ise@(ISE in_scope id_unf) expr
    1723 1722
         subst_bndr (Right subst) bndr = subst_bndr1 subst bndr
    
    1724 1723
     
    
    1725 1724
         subst_bndr1 subst bndr
    
    1726
    -      = -- pprTrace "subst_bndr1" (ppr bndr <+> ppr bndr' $$ ppr subst) $
    
    1727
    -        (Right subst', bndr')
    
    1725
    +      = (Right subst', bndr')
    
    1728 1726
           where
    
    1729 1727
             (subst', bndr') = substBndr subst bndr
    
    1730 1728