summaryrefslogtreecommitdiff
path: root/compiler/GHC/Core/Unfold.hs
diff options
context:
space:
mode:
authorSimon Peyton Jones <simonpj@microsoft.com>2020-03-09 10:20:42 +0000
committerBen Gamari <ben@smart-cactus.org>2021-02-12 15:54:08 -0500
commit9a98ecc1a44d5cc200e57db8752de18b2fc3fc6f (patch)
tree6619931f635291041c064fb618a66df48a7c4f53 /compiler/GHC/Core/Unfold.hs
parent40983d2331fe34c0af6925db7588d5ac6a19ae36 (diff)
downloadhaskell-wip/T17917.tar.gz
Avoid useless w/w splitwip/T17917
This patch is just a tidy-up for the post-strictness-analysis worker wrapper split. Consider f x = x Strictnesss analysis does not lead to a w/w split, so the obvious thing is to leave it 100% alone. But actually, because the RHS is small, we ended up adding a StableUnfolding for it. There is some reason to do this if we choose /not/ do to w/w on the grounds that the function is small. See Note [Don't w/w inline small non-loop-breaker things] But there is no reason if we would not have done w/w anyway. This patch just moves the conditional to later. Easy. This does move some -ddump-simpl printouts around a bit. I also discovered that the previous code was overwritten an InlineCompulsory with InlineStable, which is utterly wrong. That in turn meant that some default methods (marked InlineCompulsory) were getting their InlineCompulsory squashed. This patch fixes that bug --- but of course that does mean a bit more inlining! Metric Decrease: T9233 T9675 Metric Increase: T12707 T11374 T3064 T4029 T9872b T9872d haddock.Cabal
Diffstat (limited to 'compiler/GHC/Core/Unfold.hs')
-rw-r--r--compiler/GHC/Core/Unfold.hs29
1 files changed, 17 insertions, 12 deletions
diff --git a/compiler/GHC/Core/Unfold.hs b/compiler/GHC/Core/Unfold.hs
index 8a61eec3c7..27510cf1ab 100644
--- a/compiler/GHC/Core/Unfold.hs
+++ b/compiler/GHC/Core/Unfold.hs
@@ -956,11 +956,21 @@ certainlyWillInline :: UnfoldingOpts -> IdInfo -> Maybe Unfolding
-- ^ Sees if the unfolding is pretty certain to inline.
-- If so, return a *stable* unfolding for it, that will always inline.
certainlyWillInline opts fn_info
- = case unfoldingInfo fn_info of
- CoreUnfolding { uf_tmpl = e, uf_guidance = g }
- | loop_breaker -> Nothing -- Won't inline, so try w/w
- | noinline -> Nothing -- See Note [Worker-wrapper for NOINLINE functions]
- | otherwise -> do_cunf e g -- Depends on size, so look at that
+ = case fn_unf of
+ CoreUnfolding { uf_tmpl = expr, uf_guidance = guidance, uf_src = src }
+ | loop_breaker -> Nothing -- Won't inline, so try w/w
+ | noinline -> Nothing -- See Note [Worker-wrapper for NOINLINE functions]
+ | otherwise
+ -> case guidance of
+ UnfNever -> Nothing
+ UnfWhen {} -> Just (fn_unf { uf_src = src' })
+ -- INLINE functions have UnfWhen
+ UnfIfGoodArgs { ug_size = size, ug_args = args }
+ -> do_cunf expr size args src'
+ where
+ src' = case src of
+ InlineRhs -> InlineStable
+ _ -> src -- Do not change InlineCompulsory!
DFunUnfolding {} -> Just fn_unf -- Don't w/w DFuns; it never makes sense
-- to do so, and even if it is currently a
@@ -973,17 +983,12 @@ certainlyWillInline opts fn_info
noinline = inlinePragmaSpec (inlinePragInfo fn_info) == NoInline
fn_unf = unfoldingInfo fn_info
- do_cunf :: CoreExpr -> UnfoldingGuidance -> Maybe Unfolding
- do_cunf _ UnfNever = Nothing
- do_cunf _ (UnfWhen {}) = Just (fn_unf { uf_src = InlineStable })
- -- INLINE functions have UnfWhen
-
-- The UnfIfGoodArgs case seems important. If we w/w small functions
-- binary sizes go up by 10%! (This is with SplitObjs.)
-- I'm not totally sure why.
-- INLINABLE functions come via this path
-- See Note [certainlyWillInline: INLINABLE]
- do_cunf expr (UnfIfGoodArgs { ug_size = size, ug_args = args })
+ do_cunf expr size args src'
| arityInfo fn_info > 0 -- See Note [certainlyWillInline: be careful of thunks]
, not (isDeadEndSig (strictnessInfo fn_info))
-- Do not unconditionally inline a bottoming functions even if
@@ -991,7 +996,7 @@ certainlyWillInline opts fn_info
-- so we don't want to re-inline it.
, let unf_arity = length args
, size - (10 * (unf_arity + 1)) <= unfoldingUseThreshold opts
- = Just (fn_unf { uf_src = InlineStable
+ = Just (fn_unf { uf_src = src'
, uf_guidance = UnfWhen { ug_arity = unf_arity
, ug_unsat_ok = unSaturatedOk
, ug_boring_ok = inlineBoringOk expr } })