summaryrefslogtreecommitdiff
path: root/compiler/GHC/Core/Unfold/Make.hs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/GHC/Core/Unfold/Make.hs')
-rw-r--r--compiler/GHC/Core/Unfold/Make.hs59
1 files changed, 35 insertions, 24 deletions
diff --git a/compiler/GHC/Core/Unfold/Make.hs b/compiler/GHC/Core/Unfold/Make.hs
index adbbdec763..479187005b 100644
--- a/compiler/GHC/Core/Unfold/Make.hs
+++ b/compiler/GHC/Core/Unfold/Make.hs
@@ -6,6 +6,7 @@ module GHC.Core.Unfold.Make
, mkUnfolding
, mkCoreUnfolding
, mkFinalUnfolding
+ , mkFinalUnfolding'
, mkSimpleUnfolding
, mkWorkerUnfolding
, mkInlineUnfoldingWithArity, mkInlineUnfoldingNoArity
@@ -35,6 +36,8 @@ import GHC.Utils.Outputable
import GHC.Utils.Misc
import GHC.Utils.Panic
+import Data.Maybe ( fromMaybe )
+
-- the very simple optimiser is used to optimise unfoldings
import {-# SOURCE #-} GHC.Core.SimpleOpt
@@ -43,7 +46,14 @@ import {-# SOURCE #-} GHC.Core.SimpleOpt
mkFinalUnfolding :: UnfoldingOpts -> UnfoldingSource -> DmdSig -> CoreExpr -> Unfolding
-- "Final" in the sense that this is a GlobalId that will not be further
-- simplified; so the unfolding should be occurrence-analysed
-mkFinalUnfolding opts src strict_sig expr
+mkFinalUnfolding opts src strict_sig expr = mkFinalUnfolding' opts src strict_sig expr Nothing
+
+-- See Note [Tying the 'CoreUnfolding' knot] for why interfaces need
+-- to pass a precomputed 'UnfoldingCache'
+mkFinalUnfolding' :: UnfoldingOpts -> UnfoldingSource -> DmdSig -> CoreExpr -> Maybe UnfoldingCache -> Unfolding
+-- "Final" in the sense that this is a GlobalId that will not be further
+-- simplified; so the unfolding should be occurrence-analysed
+mkFinalUnfolding' opts src strict_sig expr
= mkUnfolding opts src
True {- Top level -}
(isDeadEndSig strict_sig)
@@ -57,7 +67,7 @@ mkCompulsoryUnfolding' opts expr = mkCompulsoryUnfolding (simpleOptExpr opts exp
mkCompulsoryUnfolding :: CoreExpr -> Unfolding
mkCompulsoryUnfolding expr
= mkCoreUnfolding CompulsorySrc True
- expr
+ expr Nothing
(UnfWhen { ug_arity = 0 -- Arity of unfolding doesn't matter
, ug_unsat_ok = unSaturatedOk, ug_boring_ok = boringCxtOk })
@@ -69,7 +79,7 @@ mkCompulsoryUnfolding expr
mkSimpleUnfolding :: UnfoldingOpts -> CoreExpr -> Unfolding
mkSimpleUnfolding !opts rhs
- = mkUnfolding opts VanillaSrc False False rhs
+ = mkUnfolding opts VanillaSrc False False rhs Nothing
mkDFunUnfolding :: [Var] -> DataCon -> [CoreExpr] -> Unfolding
mkDFunUnfolding bndrs con ops
@@ -81,7 +91,7 @@ mkDFunUnfolding bndrs con ops
mkDataConUnfolding :: CoreExpr -> Unfolding
-- Used for non-newtype data constructors with non-trivial wrappers
mkDataConUnfolding expr
- = mkCoreUnfolding StableSystemSrc True expr guide
+ = mkCoreUnfolding StableSystemSrc True expr Nothing guide
-- No need to simplify the expression
where
guide = UnfWhen { ug_arity = manifestArity expr
@@ -93,7 +103,7 @@ mkWrapperUnfolding :: SimpleOpts -> CoreExpr -> Arity -> Unfolding
-- after demand/CPR analysis
mkWrapperUnfolding opts expr arity
= mkCoreUnfolding StableSystemSrc True
- (simpleOptExpr opts expr)
+ (simpleOptExpr opts expr) Nothing
(UnfWhen { ug_arity = arity
, ug_unsat_ok = unSaturatedOk
, ug_boring_ok = boringCxtNotOk })
@@ -104,7 +114,7 @@ mkWorkerUnfolding opts work_fn
(CoreUnfolding { uf_src = src, uf_tmpl = tmpl
, uf_is_top = top_lvl })
| isStableSource src
- = mkCoreUnfolding src top_lvl new_tmpl guidance
+ = mkCoreUnfolding src top_lvl new_tmpl Nothing guidance
where
new_tmpl = simpleOptExpr opts (work_fn tmpl)
guidance = calcUnfoldingGuidance (so_uf_opts opts) False new_tmpl
@@ -119,7 +129,7 @@ mkInlineUnfoldingNoArity :: SimpleOpts -> UnfoldingSource -> CoreExpr -> Unfoldi
mkInlineUnfoldingNoArity opts src expr
= mkCoreUnfolding src
True -- Note [Top-level flag on inline rules]
- expr' guide
+ expr' Nothing guide
where
expr' = simpleOptExpr opts expr
guide = UnfWhen { ug_arity = manifestArity expr'
@@ -133,7 +143,7 @@ mkInlineUnfoldingWithArity :: SimpleOpts -> UnfoldingSource -> Arity -> CoreExpr
mkInlineUnfoldingWithArity opts src arity expr
= mkCoreUnfolding src
True -- Note [Top-level flag on inline rules]
- expr' guide
+ expr' Nothing guide
where
expr' = simpleOptExpr opts expr
guide = UnfWhen { ug_arity = arity
@@ -146,7 +156,7 @@ mkInlineUnfoldingWithArity opts src arity expr
mkInlinableUnfolding :: SimpleOpts -> UnfoldingSource -> CoreExpr -> Unfolding
mkInlinableUnfolding opts src expr
- = mkUnfolding (so_uf_opts opts) src False False expr'
+ = mkUnfolding (so_uf_opts opts) src False False expr' Nothing
where
expr' = simpleOptExpr opts expr
@@ -180,7 +190,7 @@ specUnfolding opts spec_bndrs spec_app rule_lhs_args
, uf_guidance = old_guidance })
| isStableSource src -- See Note [Specialising unfoldings]
, UnfWhen { ug_arity = old_arity } <- old_guidance
- = mkCoreUnfolding src top_lvl new_tmpl
+ = mkCoreUnfolding src top_lvl new_tmpl Nothing
(old_guidance { ug_arity = old_arity - arity_decrease })
where
new_tmpl = simpleOptExpr opts $
@@ -310,11 +320,12 @@ mkUnfolding :: UnfoldingOpts
-> Bool -- Definitely a bottoming binding
-- (only relevant for top-level bindings)
-> CoreExpr
+ -> Maybe UnfoldingCache
-> Unfolding
-- Calculates unfolding guidance
-- Occurrence-analyses the expression before capturing it
-mkUnfolding opts src top_lvl is_bottoming expr
- = mkCoreUnfolding src top_lvl expr guidance
+mkUnfolding opts src top_lvl is_bottoming expr cache
+ = mkCoreUnfolding src top_lvl expr cache guidance
where
is_top_bottoming = top_lvl && is_bottoming
guidance = calcUnfoldingGuidance opts is_top_bottoming expr
@@ -322,26 +333,20 @@ mkUnfolding opts src top_lvl is_bottoming expr
-- See Note [Calculate unfolding guidance on the non-occ-anal'd expression]
mkCoreUnfolding :: UnfoldingSource -> Bool -> CoreExpr
- -> UnfoldingGuidance -> Unfolding
+ -> Maybe UnfoldingCache -> UnfoldingGuidance -> Unfolding
-- Occurrence-analyses the expression before capturing it
-mkCoreUnfolding src top_lvl expr guidance
- = CoreUnfolding { uf_tmpl = is_value `seq`
- is_conlike `seq`
- is_work_free `seq`
- is_expandable `seq`
+mkCoreUnfolding src top_lvl expr precomputed_cache guidance
+ = CoreUnfolding { uf_tmpl = cache `seq`
occurAnalyseExpr expr
-- occAnalyseExpr: see Note [Occurrence analysis of unfoldings]
- -- See #20905 for what a discussion of these 'seq's
+ -- See #20905 for what a discussion of this 'seq'.
-- We are careful to make sure we only
-- have one copy of an unfolding around at once.
-- Note [Thoughtful forcing in mkCoreUnfolding]
, uf_src = src
, uf_is_top = top_lvl
- , uf_is_value = is_value
- , uf_is_conlike = is_conlike
- , uf_is_work_free = is_work_free
- , uf_expandable = is_expandable
+ , uf_cache = cache
, uf_guidance = guidance }
where
is_value = exprIsHNF expr
@@ -349,6 +354,13 @@ mkCoreUnfolding src top_lvl expr guidance
is_work_free = exprIsWorkFree expr
is_expandable = exprIsExpandable expr
+ recomputed_cache = UnfoldingCache { uf_is_value = is_value
+ , uf_is_conlike = is_conlike
+ , uf_is_work_free = is_work_free
+ , uf_expandable = is_expandable }
+
+ cache = fromMaybe recomputed_cache precomputed_cache
+
----------------
certainlyWillInline :: UnfoldingOpts -> IdInfo -> CoreExpr -> Maybe Unfolding
-- ^ Sees if the unfolding is pretty certain to inline.
@@ -476,4 +488,3 @@ reducing memory pressure.
The result of fixing this led to a 1G reduction in peak memory usage (12G -> 11G) when
compiling a very large module (peak 3 million terms). For more discussion see #20905.
-}
-