summaryrefslogtreecommitdiff
path: root/compiler/GHC/Core/Opt/SpecConstr.hs
diff options
context:
space:
mode:
authorSebastian Graf <sebastian.graf@kit.edu>2020-10-30 17:20:37 +0100
committerMarge Bot <ben+marge-bot@smart-cactus.org>2020-11-20 02:09:51 -0500
commit0aec78b6c97cee58ba20bfcb959f1369b80c4e4c (patch)
tree3e48861640dbeb7a9d7784f0f02c2bc564af50ec /compiler/GHC/Core/Opt/SpecConstr.hs
parent321d1bd8a79ab39c3c9e8697fffb0107c43f83cf (diff)
downloadhaskell-0aec78b6c97cee58ba20bfcb959f1369b80c4e4c.tar.gz
Demand: Interleave usage and strictness demands (#18903)
As outlined in #18903, interleaving usage and strictness demands not only means a more compact demand representation, but also allows us to express demands that we weren't easily able to express before. Call demands are *relative* in the sense that a call demand `Cn(cd)` on `g` says "`g` is called `n` times. *Whenever `g` is called*, the result is used according to `cd`". Example from #18903: ```hs h :: Int -> Int h m = let g :: Int -> (Int,Int) g 1 = (m, 0) g n = (2 * n, 2 `div` n) {-# NOINLINE g #-} in case m of 1 -> 0 2 -> snd (g m) _ -> uncurry (+) (g m) ``` Without the interleaved representation, we would just get `L` for the strictness demand on `g`. Now we are able to express that whenever `g` is called, its second component is used strictly in denoting `g` by `1C1(P(1P(U),SP(U)))`. This would allow Nested CPR to unbox the division, for example. Fixes #18903. While fixing regressions, I also discovered and fixed #18957. Metric Decrease: T13253-spj
Diffstat (limited to 'compiler/GHC/Core/Opt/SpecConstr.hs')
-rw-r--r--compiler/GHC/Core/Opt/SpecConstr.hs11
1 files changed, 6 insertions, 5 deletions
diff --git a/compiler/GHC/Core/Opt/SpecConstr.hs b/compiler/GHC/Core/Opt/SpecConstr.hs
index 4601407723..1abe9f7ab3 100644
--- a/compiler/GHC/Core/Opt/SpecConstr.hs
+++ b/compiler/GHC/Core/Opt/SpecConstr.hs
@@ -1724,11 +1724,12 @@ calcSpecStrictness fn qvars pats
go env _ _ = env
go_one :: DmdEnv -> Demand -> CoreExpr -> DmdEnv
- go_one env d (Var v) = extendVarEnv_C bothDmd env v d
- go_one env d e
- | Just ds <- splitProdDmd_maybe d -- NB: d does not have to be strict
- , (Var _, args) <- collectArgs e = go env ds args
- go_one env _ _ = env
+ 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
+ , Just ds <- viewProd (length args) cd
+ = go env ds args
+ go_one env _ _ = env
{-
Note [spec_usg includes rhs_usg]