diff options
author | Sebastian Graf <sebastian.graf@kit.edu> | 2023-04-03 22:40:04 +0200 |
---|---|---|
committer | Sebastian Graf <sebastian.graf@kit.edu> | 2023-04-25 20:32:01 +0200 |
commit | 235f907a3a982fefff6e27f5564d0d1ba355c161 (patch) | |
tree | 9fa3cb280aa99b4e9cf9f5243835803cc47dc42c /compiler/GHC/Core/Opt/SpecConstr.hs | |
parent | 43ebd5dcdb7ff65b6afccbdee22d2c27f9df6b1c (diff) | |
download | haskell-wip/T23208.tar.gz |
DmdAnal: Unleash demand signatures of free RULE and unfolding binders (#23208)wip/T23208
In #23208 we observed that the demand signature of a binder occuring in a RULE
wasn't unleashed, leading to a transitively used binder being discarded as
absent. The solution was to use the same code path that we already use for
handling exported bindings.
See the changes to `Note [Absence analysis for stable unfoldings and RULES]`
for more details.
I took the chance to factor out the old notion of a `PlusDmdArg` (a pair of a
`VarEnv Demand` and a `Divergence`) into `DmdEnv`, which fits nicely into our
existing framework. As a result, I had to touch quite a few places in the code.
This refactoring exposed a few small bugs around correct handling of bottoming
demand environments. As a result, some strictness signatures now mention uniques
that weren't there before which caused test output changes to T13143, T19969 and
T22112. But these tests compared whole -ddump-simpl listings which is a very
fragile thing to begin with. I changed what exactly they test for based on the
symptoms in the corresponding issues.
There is a single regression in T18894 because we are more conservative around
stable unfoldings now. Unfortunately it is not easily fixed; let's wait until
there is a concrete motivation before invest more time.
Fixes #23208.
Diffstat (limited to 'compiler/GHC/Core/Opt/SpecConstr.hs')
-rw-r--r-- | compiler/GHC/Core/Opt/SpecConstr.hs | 15 |
1 files changed, 8 insertions, 7 deletions
diff --git a/compiler/GHC/Core/Opt/SpecConstr.hs b/compiler/GHC/Core/Opt/SpecConstr.hs index 81c2816334..6b01d1fb50 100644 --- a/compiler/GHC/Core/Opt/SpecConstr.hs +++ b/compiler/GHC/Core/Opt/SpecConstr.hs @@ -2096,15 +2096,16 @@ calcSpecInfo :: Id -- The original function calcSpecInfo fn arg_bndrs (CP { cp_qvars = qvars, cp_args = pats }) extra_bndrs = ( spec_lam_bndrs_w_dmds , spec_call_args - , mkClosedDmdSig [idDemandInfo b | b <- spec_lam_bndrs_w_dmds, isId b] div ) + , zapDmdEnvSig (DmdSig (dt{dt_args = spec_fn_dmds})) ) where - DmdSig (DmdType _ fn_dmds div) = idDmdSig fn + DmdSig dt@DmdType{dt_args=fn_dmds} = idDmdSig fn + spec_fn_dmds = [idDemandInfo b | b <- spec_lam_bndrs_w_dmds, isId b] val_pats = filterOut isTypeArg pats -- Value args at call sites, used to determine how many demands to drop - -- from the original functions demand and for setting up dmd_env. - dmd_env = go emptyVarEnv fn_dmds val_pats - qvar_dmds = [ lookupVarEnv dmd_env qv `orElse` topDmd | qv <- qvars, isId qv ] + -- from the original functions demand and for setting up arg_dmd_env. + arg_dmd_env = go emptyVarEnv fn_dmds val_pats + qvar_dmds = [ lookupVarEnv arg_dmd_env qv `orElse` topDmd | qv <- qvars, isId qv ] extra_dmds = dropList val_pats fn_dmds -- Annotate the variables with the strictness information from @@ -2128,12 +2129,12 @@ calcSpecInfo fn arg_bndrs (CP { cp_qvars = qvars, cp_args = pats }) extra_bndrs set_dmds (v:vs) ds@(d:ds') | isTyVar v = v : set_dmds vs ds | otherwise = setIdDemandInfo v d : set_dmds vs ds' - go :: DmdEnv -> [Demand] -> [CoreExpr] -> DmdEnv + go :: VarEnv Demand -> [Demand] -> [CoreExpr] -> VarEnv Demand -- We've filtered out all the type patterns already go env (d:ds) (pat : pats) = go (go_one env d pat) ds pats go env _ _ = env - go_one :: DmdEnv -> Demand -> CoreExpr -> DmdEnv + go_one :: VarEnv Demand -> Demand -> CoreExpr -> VarEnv Demand go_one env d (Var v) = extendVarEnv_C plusDmd env v d go_one env (_n :* cd) e -- NB: _n does not have to be strict | (Var _, args) <- collectArgs e |