summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Pickering <matthewtpickering@gmail.com>2021-07-21 10:03:42 +0100
committerMatthew Pickering <matthewtpickering@gmail.com>2021-07-21 17:39:47 +0100
commita61cc2c5439f9f41585d8eb455f5f36af269f7b0 (patch)
treea9b82e7fc8f719069f1c4f2cca81b91913f4c1d6
parentae2278a0eefcc77f43cd132da28a601b43fea00d (diff)
downloadhaskell-wip/t20134.tar.gz
Stop ug_boring_info retaining a chain of old CoreExprwip/t20134
It was noticed in #20134 that each simplifier iteration used an increasing amount of memory and that a certain portion of memory was not released until the simplfier had completely finished. I profiled the program using `-hi` profiling and observed that there was a thunk arising in the computation of `ug_boring_ok`. On each iteration `ug_boring_ok` would be updated, but not forced, which would leave a thunk in the shape of ug_boring_ok = inlineBoringOk expr0 || inlineBoringOk expr2 || inlineBoringOk expr3 || ... which would retain all previous `expr` until `ug_boring_ok` was forced or discarded. Forcing this accumulator eagerly results in a flat profile over multiple simplifier runs. This reduces the maximum residency when compiling the test in #20134 from 2GB to 1.3G. ------------------------- Metric Decrease: T11545 -------------------------
-rw-r--r--compiler/GHC/Core/Opt/Simplify.hs27
1 files changed, 19 insertions, 8 deletions
diff --git a/compiler/GHC/Core/Opt/Simplify.hs b/compiler/GHC/Core/Opt/Simplify.hs
index 1bbb728de6..1cecda63b2 100644
--- a/compiler/GHC/Core/Opt/Simplify.hs
+++ b/compiler/GHC/Core/Opt/Simplify.hs
@@ -4003,8 +4003,7 @@ simplLetUnfolding env top_lvl cont_mb id new_rhs rhs_ty arity unf
mkLetUnfolding :: UnfoldingOpts -> TopLevelFlag -> UnfoldingSource
-> InId -> OutExpr -> SimplM Unfolding
mkLetUnfolding !uf_opts top_lvl src id new_rhs
- = is_bottoming `seq` -- See Note [Force bottoming field]
- return (mkUnfolding uf_opts src is_top_lvl is_bottoming new_rhs)
+ = return (mkUnfolding uf_opts src is_top_lvl is_bottoming new_rhs)
-- We make an unfolding *even for loop-breakers*.
-- Reason: (a) It might be useful to know that they are WHNF
-- (b) In GHC.Iface.Tidy we currently assume that, if we want to
@@ -4012,8 +4011,11 @@ mkLetUnfolding !uf_opts top_lvl src id new_rhs
-- to expose. (We could instead use the RHS, but currently
-- we don't.) The simple thing is always to have one.
where
- is_top_lvl = isTopLevel top_lvl
- is_bottoming = isDeadEndId id
+ -- Might as well force this, profiles indicate up to 0.5MB of thunks
+ -- just from this site.
+ !is_top_lvl = isTopLevel top_lvl
+ -- See Note [Force bottoming field]
+ !is_bottoming = isDeadEndId id
-------------------
simplStableUnfolding :: SimplEnv -> TopLevelFlag
@@ -4050,11 +4052,17 @@ simplStableUnfolding env top_lvl mb_cont id rhs_ty id_arity unf
, ug_boring_ok = boring_ok
}
-- Happens for INLINE things
- -> let guide' =
+ -- Really important to force new_boring_ok as otherwise
+ -- `ug_boring_ok` is a thunk chain of
+ -- inlineBoringExprOk expr0
+ -- || inlineBoringExprOk expr1 || ...
+ -- See #20134
+ -> let !new_boring_ok = boring_ok || inlineBoringOk expr'
+ guide' =
UnfWhen { ug_arity = arity
, ug_unsat_ok = sat_ok
- , ug_boring_ok =
- boring_ok || inlineBoringOk expr'
+ , ug_boring_ok = new_boring_ok
+
}
-- Refresh the boring-ok flag, in case expr'
-- has got small. This happens, notably in the inlinings
@@ -4075,7 +4083,9 @@ simplStableUnfolding env top_lvl mb_cont id rhs_ty id_arity unf
| otherwise -> return noUnfolding -- Discard unstable unfoldings
where
uf_opts = seUnfoldingOpts env
- is_top_lvl = isTopLevel top_lvl
+ -- Forcing this can save about 0.5MB of max residency and the result
+ -- is small and easy to compute so might as well force it.
+ !is_top_lvl = isTopLevel top_lvl
act = idInlineActivation id
unf_env = updMode (updModeForStableUnfoldings act) env
-- See Note [Simplifying inside stable unfoldings] in GHC.Core.Opt.Simplify.Utils
@@ -4216,3 +4226,4 @@ for the RHS as well as the LHS, but that seems more conservative
than necesary. Allowing some inlining might, for example, eliminate
a binding.
-}
+