Simon Peyton Jones pushed to branch wip/T23109a at Glasgow Haskell Compiler / GHC
Commits:
-
f0432100
by Simon Peyton Jones at 2025-05-08T17:23:19+01:00
4 changed files:
- compiler/GHC/Core/Opt/OccurAnal.hs
- compiler/GHC/Core/Opt/Simplify/Iteration.hs
- compiler/GHC/Core/Opt/Simplify/Utils.hs
- compiler/GHC/Types/Basic.hs
Changes:
... | ... | @@ -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 |
... | ... | @@ -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 })
|
... | ... | @@ -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
|
... | ... | @@ -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 |