diff options
author | Andreas Klebinger <klebinger.andreas@gmx.at> | 2021-05-10 16:00:24 +0200 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2021-05-12 14:49:23 -0400 |
commit | 55223780a286e10b128acdb89d64d9e59a5becf1 (patch) | |
tree | 45400700e6e91bfce74c236b5b8be5898b8e2189 | |
parent | f0b73ddd8bdb663ab70043e9424a99d2454cdf77 (diff) | |
download | haskell-55223780a286e10b128acdb89d64d9e59a5becf1.tar.gz |
W/W: Always zap useless idInfos.
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.hs | 30 |
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 |