diff options
author | Sebastian Graf <sebastian.graf@kit.edu> | 2020-10-30 17:20:37 +0100 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2020-11-20 02:09:51 -0500 |
commit | 0aec78b6c97cee58ba20bfcb959f1369b80c4e4c (patch) | |
tree | 3e48861640dbeb7a9d7784f0f02c2bc564af50ec /compiler/GHC/Builtin/primops.txt.pp | |
parent | 321d1bd8a79ab39c3c9e8697fffb0107c43f83cf (diff) | |
download | haskell-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/Builtin/primops.txt.pp')
-rw-r--r-- | compiler/GHC/Builtin/primops.txt.pp | 10 |
1 files changed, 5 insertions, 5 deletions
diff --git a/compiler/GHC/Builtin/primops.txt.pp b/compiler/GHC/Builtin/primops.txt.pp index 74abca2927..ecc71baa69 100644 --- a/compiler/GHC/Builtin/primops.txt.pp +++ b/compiler/GHC/Builtin/primops.txt.pp @@ -2283,7 +2283,7 @@ section "Exceptions" -- DEFAULT -> case ma of MVar a -> ... -- 0# -> maskAsyncExceptions# (\st -> case ma of MVar a -> ...) -- The outer case just decides whether to mask exceptions, but we don't want --- thereby to hide the strictness in 'ma'! Hence the use of strictApply1Dmd +-- thereby to hide the strictness in 'ma'! Hence the use of strictOnceApply1Dmd -- in mask and unmask. But catch really is lazy in its first argument, see -- #11555. So for IO actions 'ma' we often use a wrapper around it that is -- head-strict in 'ma': GHC.IO.catchException. @@ -2329,7 +2329,7 @@ primop MaskAsyncExceptionsOp "maskAsyncExceptions#" GenPrimOp (State# RealWorld -> (# State# RealWorld, a #)) -> (State# RealWorld -> (# State# RealWorld, a #)) with - strictness = { \ _arity -> mkClosedStrictSig [strictApply1Dmd,topDmd] topDiv } + strictness = { \ _arity -> mkClosedStrictSig [strictOnceApply1Dmd,topDmd] topDiv } -- See Note [Strictness for mask/unmask/catch] out_of_line = True has_side_effects = True @@ -2338,7 +2338,7 @@ primop MaskUninterruptibleOp "maskUninterruptible#" GenPrimOp (State# RealWorld -> (# State# RealWorld, a #)) -> (State# RealWorld -> (# State# RealWorld, a #)) with - strictness = { \ _arity -> mkClosedStrictSig [strictApply1Dmd,topDmd] topDiv } + strictness = { \ _arity -> mkClosedStrictSig [strictOnceApply1Dmd,topDmd] topDiv } out_of_line = True has_side_effects = True @@ -2346,7 +2346,7 @@ primop UnmaskAsyncExceptionsOp "unmaskAsyncExceptions#" GenPrimOp (State# RealWorld -> (# State# RealWorld, a #)) -> (State# RealWorld -> (# State# RealWorld, a #)) with - strictness = { \ _arity -> mkClosedStrictSig [strictApply1Dmd,topDmd] topDiv } + strictness = { \ _arity -> mkClosedStrictSig [strictOnceApply1Dmd,topDmd] topDiv } -- See Note [Strictness for mask/unmask/catch] out_of_line = True has_side_effects = True @@ -2367,7 +2367,7 @@ primop AtomicallyOp "atomically#" GenPrimOp (State# RealWorld -> (# State# RealWorld, a #) ) -> State# RealWorld -> (# State# RealWorld, a #) with - strictness = { \ _arity -> mkClosedStrictSig [strictApply1Dmd,topDmd] topDiv } + strictness = { \ _arity -> mkClosedStrictSig [strictManyApply1Dmd,topDmd] topDiv } -- See Note [Strictness for mask/unmask/catch] out_of_line = True has_side_effects = True |