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

Commits:

4 changed files:

Changes:

  • compiler/GHC/Core/Opt/OccurAnal.hs
    ... ... @@ -33,7 +33,7 @@ import GHC.Prelude hiding ( head, init, last, tail )
    33 33
     
    
    34 34
     import GHC.Core
    
    35 35
     import GHC.Core.FVs
    
    36
    -import GHC.Core.Utils   ( exprIsTrivial, isDefaultAlt, isExpandableApp,
    
    36
    +import GHC.Core.Utils   ( exprIsTrivial, isExpandableApp,
    
    37 37
                               mkCastMCo, mkTicks )
    
    38 38
     import GHC.Core.Opt.Arity   ( joinRhsArity, isOneShotBndr )
    
    39 39
     import GHC.Core.Coercion
    
    ... ... @@ -2605,9 +2605,9 @@ occAnalArgs !env fun args !one_shots
    2605 2605
     
    
    2606 2606
         -- Make bottoming functions interesting
    
    2607 2607
         -- See Note [Bottoming function calls]
    
    2608
    ---    encl | Var f <- fun, isDeadEndSig (idDmdSig f) = OccScrut
    
    2609
    ---         | otherwise                               = OccVanilla
    
    2610
    -    encl = OccVanilla
    
    2608
    +    encl | Var f <- fun, isDeadEndId f = OccBot
    
    2609
    +         | otherwise                   = OccVanilla
    
    2610
    +--    encl = OccVanilla
    
    2611 2611
     
    
    2612 2612
         go uds fun [] _ = WUD uds fun
    
    2613 2613
         go uds fun (arg:args) one_shots
    
    ... ... @@ -2680,7 +2680,7 @@ occAnalApp !env (Var fun, args, ticks)
    2680 2680
     occAnalApp env (Var fun_id, args, ticks)
    
    2681 2681
       = WUD all_uds (mkTicks ticks app')
    
    2682 2682
       where
    
    2683
    -    -- Lots of banged bindings: this is a very heavily bit of code,
    
    2683
    +    -- Lots of banged bindings: this is a very heavily-used bit of code,
    
    2684 2684
         -- so it pays not to make lots of thunks here, all of which
    
    2685 2685
         -- will ultimately be forced.
    
    2686 2686
         !(fun', fun_id')  = lookupBndrSwap env fun_id
    
    ... ... @@ -2709,7 +2709,7 @@ occAnalApp env (Var fun_id, args, ticks)
    2709 2709
         !n_val_args = valArgCount args
    
    2710 2710
         !n_args     = length args
    
    2711 2711
         !int_cxt    = case occ_encl env of
    
    2712
    -                   OccScrut -> IsInteresting
    
    2712
    +                   OccBot                    -> IsInteresting
    
    2713 2713
                        _other   | n_val_args > 0 -> IsInteresting
    
    2714 2714
                                 | otherwise      -> NotInteresting
    
    2715 2715
     
    
    ... ... @@ -2893,14 +2893,20 @@ OccEncl is used to control whether to inline into constructor arguments.
    2893 2893
     
    
    2894 2894
     data OccEncl -- See Note [OccEncl]
    
    2895 2895
       = OccRhs         -- RHS of let(rec), albeit perhaps inside a type lambda
    
    2896
    -  | OccScrut       -- Scrutintee of a case
    
    2896
    +  | OccBot         -- We are in a bottoming expression
    
    2897 2897
       | OccVanilla     -- Everything else
    
    2898 2898
     
    
    2899 2899
     instance Outputable OccEncl where
    
    2900 2900
       ppr OccRhs     = text "occRhs"
    
    2901
    -  ppr OccScrut   = text "occScrut"
    
    2901
    +  ppr OccBot     = text "occBot"
    
    2902 2902
       ppr OccVanilla = text "occVanilla"
    
    2903 2903
     
    
    2904
    +setOccEncl :: OccEncl -> OccEncl -> OccEncl
    
    2905
    +-- (outer_encl `setOccEncl` inner_encl)
    
    2906
    +-- If we are in a bottoming context, don't forget it!
    
    2907
    +setOccEncl OccBot _          = OccBot
    
    2908
    +setOccEncl _      inner_encl = inner_encl
    
    2909
    +
    
    2904 2910
     -- See Note [OneShots]
    
    2905 2911
     type OneShots = [OneShotInfo]
    
    2906 2912
     
    
    ... ... @@ -2922,16 +2928,17 @@ noBinderSwaps :: OccEnv -> Bool
    2922 2928
     noBinderSwaps (OccEnv { occ_bs_env = bs_env }) = isEmptyVarEnv bs_env
    
    2923 2929
     
    
    2924 2930
     setScrutCtxt :: OccEnv -> [CoreAlt] -> OccEnv
    
    2925
    -setScrutCtxt !env alts
    
    2931
    +setScrutCtxt !env _alts
    
    2926 2932
       = setNonTailCtxt encl env
    
    2927 2933
       where
    
    2928
    -    encl | interesting_alts = OccScrut
    
    2929
    -         | otherwise        = OccVanilla
    
    2934
    +    encl = OccVanilla
    
    2935
    +--    encl | interesting_alts = OccScrut
    
    2936
    +--         | otherwise        = OccVanilla
    
    2930 2937
     
    
    2931
    -    interesting_alts = case alts of
    
    2932
    -                         []    -> False
    
    2933
    -                         [alt] -> not (isDefaultAlt alt)
    
    2934
    -                         _     -> True
    
    2938
    +--    interesting_alts = case alts of
    
    2939
    +--                         []    -> False
    
    2940
    +--                         [alt] -> not (isDefaultAlt alt)
    
    2941
    +--                         _     -> True
    
    2935 2942
          -- 'interesting_alts' is True if the case has at least one
    
    2936 2943
          -- non-default alternative.  That in turn influences
    
    2937 2944
          -- pre/postInlineUnconditionally.  Grep for "occ_int_cxt"!
    
    ... ... @@ -2974,13 +2981,14 @@ For a join point binding, j x = rhs
    2974 2981
     -}
    
    2975 2982
     
    
    2976 2983
     setNonTailCtxt :: OccEncl -> OccEnv -> OccEnv
    
    2977
    -setNonTailCtxt ctxt !env
    
    2978
    -  = env { occ_encl        = ctxt
    
    2984
    +setNonTailCtxt inner_encl env@(OccEnv { occ_encl = outer_encl })
    
    2985
    +  = env { occ_encl        = outer_encl `setOccEncl` inner_encl
    
    2979 2986
             , occ_one_shots   = []
    
    2980 2987
             , occ_join_points = zapJoinPointInfo (occ_join_points env) }
    
    2981 2988
     
    
    2982 2989
     setTailCtxt :: OccEnv -> OccEnv
    
    2983
    -setTailCtxt !env = env { occ_encl = OccVanilla }
    
    2990
    +setTailCtxt env@(OccEnv { occ_encl = outer_encl })
    
    2991
    +  = env { occ_encl = outer_encl `setOccEncl` OccVanilla }
    
    2984 2992
         -- Preserve occ_one_shots, occ_join points
    
    2985 2993
         -- Do not use OccRhs for the RHS of a join point (which is a tail ctxt):
    
    2986 2994
     
    
    ... ... @@ -3619,7 +3627,7 @@ data LocalOcc -- See Note [LocalOcc]
    3619 3627
                    , lo_tail  :: !TailCallInfo
    
    3620 3628
                        -- Combining (AlwaysTailCalled 2) and (AlwaysTailCalled 3)
    
    3621 3629
                        -- gives NoTailCallInfo
    
    3622
    -              , lo_int_cxt :: !InterestingCxt }
    
    3630
    +              , lo_int_cxt :: !OccCtxt }
    
    3623 3631
         | ManyOccL !TailCallInfo
    
    3624 3632
     
    
    3625 3633
     instance Outputable LocalOcc where
    
    ... ... @@ -3676,7 +3684,7 @@ andUDs, orUDs
    3676 3684
     andUDs = combineUsageDetailsWith andLocalOcc
    
    3677 3685
     orUDs  = combineUsageDetailsWith orLocalOcc
    
    3678 3686
     
    
    3679
    -mkOneOcc :: OccEnv -> Id -> InterestingCxt -> JoinArity -> UsageDetails
    
    3687
    +mkOneOcc :: OccEnv -> Id -> OccCtxt -> JoinArity -> UsageDetails
    
    3680 3688
     mkOneOcc !env id int_cxt arity
    
    3681 3689
       | not (isLocalId id)
    
    3682 3690
       = emptyDetails
    
    ... ... @@ -4087,7 +4095,7 @@ orLocalOcc :: LocalOcc -> LocalOcc -> LocalOcc
    4087 4095
     orLocalOcc (OneOccL { lo_n_br = nbr1, lo_int_cxt = int_cxt1, lo_tail = tci1 })
    
    4088 4096
                (OneOccL { lo_n_br = nbr2, lo_int_cxt = int_cxt2, lo_tail = tci2 })
    
    4089 4097
       = OneOccL { lo_n_br    = nbr1 + nbr2
    
    4090
    -            , lo_int_cxt = int_cxt1 `mappend` int_cxt2
    
    4098
    +            , lo_int_cxt = int_cxt1 `orOccCtxt` int_cxt2
    
    4091 4099
                 , lo_tail    = tci1 `andTailCallInfo` tci2 }
    
    4092 4100
     orLocalOcc occ1 occ2 = andLocalOcc occ1 occ2
    
    4093 4101
     
    

  • compiler/GHC/Core/Opt/Simplify/Iteration.hs
    ... ... @@ -3940,6 +3940,8 @@ mkDupableContWithDmds env _
    3940 3940
            ; (floats, join_rhs) <- rebuildCall env' (addValArgTo fun (Var arg_bndr) fun_ty) cont
    
    3941 3941
            ; mkDupableStrictBind env' arg_bndr (wrapFloats floats join_rhs) rhs_ty }
    
    3942 3942
       where
    
    3943
    +    thumbsUpPlanA _ = False
    
    3944
    +    {-
    
    3943 3945
         thumbsUpPlanA (StrictArg {})               = False
    
    3944 3946
         thumbsUpPlanA (StrictBind {})              = True
    
    3945 3947
         thumbsUpPlanA (Stop {})                    = True
    
    ... ... @@ -3948,6 +3950,7 @@ mkDupableContWithDmds env _
    3948 3950
         thumbsUpPlanA (TickIt _ k)                 = thumbsUpPlanA k
    
    3949 3951
         thumbsUpPlanA (ApplyToVal { sc_cont = k }) = thumbsUpPlanA k
    
    3950 3952
         thumbsUpPlanA (ApplyToTy  { sc_cont = k }) = thumbsUpPlanA k
    
    3953
    +    -}
    
    3951 3954
     
    
    3952 3955
     mkDupableContWithDmds env dmds
    
    3953 3956
         (ApplyToTy { sc_cont = cont, sc_arg_ty = arg_ty, sc_hole_ty = hole_ty })
    

  • compiler/GHC/Core/Opt/Simplify/Utils.hs
    ... ... @@ -1630,8 +1630,8 @@ postInlineUnconditionally env bind_cxt old_bndr bndr rhs
    1630 1630
         is_demanded = isStrUsedDmd (idDemandInfo bndr)
    
    1631 1631
         occ_info    = idOccInfo old_bndr
    
    1632 1632
         unfolding   = idUnfolding bndr
    
    1633
    -    arity       = idArity bndr
    
    1634
    ---    is_cheap    = isCheapUnfolding unfolding
    
    1633
    +--    arity       = idArity bndr
    
    1634
    +    is_cheap    = isCheapUnfolding unfolding
    
    1635 1635
         uf_opts     = seUnfoldingOpts env
    
    1636 1636
         phase       = sePhase env
    
    1637 1637
         active      = isActive phase (idInlineActivation bndr)
    
    ... ... @@ -1649,7 +1649,7 @@ postInlineUnconditionally env bind_cxt old_bndr bndr rhs
    1649 1649
         check_one_occ NotInsideLam NotInteresting n_br = not is_top_lvl && code_dup_ok n_br
    
    1650 1650
         check_one_occ NotInsideLam IsInteresting  n_br = code_dup_ok n_br
    
    1651 1651
         check_one_occ IsInsideLam  NotInteresting _    = False
    
    1652
    -    check_one_occ IsInsideLam  IsInteresting  n_br = arity > 0 && code_dup_ok n_br
    
    1652
    +    check_one_occ IsInsideLam  IsInteresting  n_br = is_cheap && code_dup_ok n_br
    
    1653 1653
           -- IsInteresting: inlining inside a lambda only with good reason
    
    1654 1654
           --    See the notes on int_cxt in preInlineUnconditionally
    
    1655 1655
           -- arity>0: do not inline data strutures under lambdas, only functions
    

  • compiler/GHC/Types/Basic.hs
    ... ... @@ -75,7 +75,7 @@ module GHC.Types.Basic (
    75 75
     
    
    76 76
             InsideLam(..),
    
    77 77
             BranchCount, oneBranch,
    
    78
    -        InterestingCxt(..),
    
    78
    +        OccCtxt(..), orOccCtxt,
    
    79 79
             TailCallInfo(..), tailCallInfo, zapOccTailCallInfo,
    
    80 80
             isAlwaysTailCalled,
    
    81 81
     
    
    ... ... @@ -1190,7 +1190,7 @@ data OccInfo -- See Note [OccInfo]
    1190 1190
     
    
    1191 1191
       | OneOcc          { occ_in_lam  :: !InsideLam
    
    1192 1192
                         , occ_n_br    :: {-# UNPACK #-} !BranchCount
    
    1193
    -                    , occ_int_cxt :: !InterestingCxt
    
    1193
    +                    , occ_int_cxt :: !OccCtxt
    
    1194 1194
                         , occ_tail    :: !TailCallInfo }
    
    1195 1195
                             -- ^ Occurs exactly once (per branch), not inside a rule
    
    1196 1196
     
    
    ... ... @@ -1241,22 +1241,15 @@ seqOccInfo occ = occ `seq` ()
    1241 1241
     
    
    1242 1242
     -----------------
    
    1243 1243
     -- | Interesting Context
    
    1244
    -data InterestingCxt
    
    1245
    -  = IsInteresting
    
    1246
    -    -- ^ Function: is applied
    
    1247
    -    --   Data value: scrutinised by a case with at least one non-DEFAULT branch
    
    1248
    -  | NotInteresting
    
    1244
    +data OccCtxt
    
    1245
    +  = IsInteresting   -- ^ All occurrences are in a bottoming context
    
    1246
    +                    -- or are applied to a value argument
    
    1247
    +  | NotInteresting  -- ^ Neither of the above
    
    1249 1248
       deriving (Eq)
    
    1250 1249
     
    
    1251
    --- | If there is any 'interesting' identifier occurrence, then the
    
    1252
    --- aggregated occurrence info of that identifier is considered interesting.
    
    1253
    -instance Semi.Semigroup InterestingCxt where
    
    1254
    -  NotInteresting <> x = x
    
    1255
    -  IsInteresting  <> _ = IsInteresting
    
    1256
    -
    
    1257
    -instance Monoid InterestingCxt where
    
    1258
    -  mempty = NotInteresting
    
    1259
    -  mappend = (Semi.<>)
    
    1250
    +orOccCtxt :: OccCtxt -> OccCtxt -> OccCtxt
    
    1251
    +orOccCtxt IsInteresting IsInteresting = IsInteresting
    
    1252
    +orOccCtxt _             _             = NotInteresting
    
    1260 1253
     
    
    1261 1254
     -----------------
    
    1262 1255
     -- | Inside Lambda
    
    ... ... @@ -1340,11 +1333,11 @@ instance Outputable OccInfo where
    1340 1333
       ppr (OneOcc inside_lam one_branch int_cxt tail_info)
    
    1341 1334
             = text "Once" <> pp_lam inside_lam <> ppr one_branch <> pp_args int_cxt <> pp_tail
    
    1342 1335
             where
    
    1343
    -          pp_lam IsInsideLam     = char 'L'
    
    1344
    -          pp_lam NotInsideLam    = empty
    
    1345
    -          pp_args IsInteresting  = char '!'
    
    1346
    -          pp_args NotInteresting = empty
    
    1347
    -          pp_tail                = pprShortTailCallInfo tail_info
    
    1336
    +          pp_lam IsInsideLam  = char 'L'
    
    1337
    +          pp_lam NotInsideLam = empty
    
    1338
    +          pp_args NotInteresting  = empty
    
    1339
    +          pp_args IsInteresting   = char '!'
    
    1340
    +          pp_tail = pprShortTailCallInfo tail_info
    
    1348 1341
     
    
    1349 1342
     pprShortTailCallInfo :: TailCallInfo -> SDoc
    
    1350 1343
     pprShortTailCallInfo (AlwaysTailCalled ar) = char 'T' <> brackets (int ar)
    
    ... ... @@ -2461,4 +2454,4 @@ convImportLevel NotLevelled = NormalLevel
    2461 2454
     
    
    2462 2455
     convImportLevelSpec :: ImportDeclLevel -> ImportLevel
    
    2463 2456
     convImportLevelSpec ImportDeclQuote = QuoteLevel
    
    2464
    -convImportLevelSpec ImportDeclSplice = SpliceLevel
    \ No newline at end of file
    2457
    +convImportLevelSpec ImportDeclSplice = SpliceLevel