summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Klebinger <klebinger.andreas@gmx.at>2021-05-10 16:00:24 +0200
committerAndreas Klebinger <klebinger.andreas@gmx.at>2021-05-11 15:13:50 +0200
commitd2f226b771e672af730f47bad3cb93a45b21bc12 (patch)
tree5fd21d66f15d2d78a109d4ff826e6afa87bdf134
parent32367cac4e586fb5aedaa021b257388392d976c4 (diff)
downloadhaskell-wip/andreask/ww_noop_zapping.tar.gz
W/W: Always zap useless idInfos.wip/andreask/ww_noop_zapping
tryWW used to always returns an Id with a zapped: * DmdEnv * Used Once info except in the case where the ID was guaranteed to be inlined. We now also zap the info in that case. Fixes #19818.
-rw-r--r--compiler/GHC/Core/Opt/WorkWrap.hs30
1 files changed, 28 insertions, 2 deletions
diff --git a/compiler/GHC/Core/Opt/WorkWrap.hs b/compiler/GHC/Core/Opt/WorkWrap.hs
index 34198bad88..65f07703b2 100644
--- a/compiler/GHC/Core/Opt/WorkWrap.hs
+++ b/compiler/GHC/Core/Opt/WorkWrap.hs
@@ -495,12 +495,12 @@ tryWW dflags fam_envs is_rec fn_id rhs
-- See Note [Worker/wrapper for NOINLINE functions]
| Just stable_unf <- certainlyWillInline uf_opts fn_info
- = return [ (fn_id `setIdUnfolding` stable_unf, rhs) ]
+ = return [ (new_fn_id `setIdUnfolding` stable_unf, rhs) ]
-- See Note [Don't w/w INLINE things]
-- See Note [Don't w/w inline small non-loop-breaker things]
| isRecordSelector fn_id -- See Note [No worker/wrapper for record selectors]
- = return [ (fn_id, rhs ) ]
+ = return [ (new_fn_id, rhs ) ]
| is_fun && is_eta_exp
= splitFun dflags fam_envs new_fn_id fn_info wrap_dmds div cpr rhs
@@ -572,6 +572,32 @@ want to _keep_ the info for the code generator).
We do not do it in the demand analyser for the same reasons outlined in
Note [Zapping DmdEnv after Demand Analyzer] above.
+For example, consider
+ let y = factorial v in
+ let x = y in
+ x + x
+
+Demand analysis will conclude, correctly, that `y` is demanded once. But if we inline `x` we get
+ let y = factorial v in
+ y + y
+
+Similarly for
+ f y = let x = y in x+x
+where we will put a used-once demand on y, and hence also in f's demand signature.
+
+And recursively
+ f y = case y of (p,q) -> let p2 = p in p2+p2
+ Here we'll get a used-once demand on p; but that is not robust to inlining p2.
+
+Conclusion: "demanded once" info is fragile.
+* We want it after the final immediately-before-code-gen demand analysis, so we can identify single-entry thunks.
+* But we don't want it otherwise because it is not robust.
+
+Conclusion: kill it during worker/wrapper, using `zapUsedOnceInfo`. Both the *demand signature* of
+the binder, and the *demand-info* of the binder. Moreover, do so recursively.
+
+(NB THE pre-code-gen demand analysis is not followed by worker/wrapper.)
+
Note [Don't eta expand in w/w]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
A binding where the manifestArity of the RHS is less than idArity of the binder