{-# LANGUAGE CPP, FlexibleInstances, TypeSynonymInstances, RecordWildCards #-}
{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}
module GHC.Types.Demand (
StrDmd, UseDmd(..), Count,
Demand, DmdShell, CleanDemand, getStrDmd, getUseDmd,
mkProdDmd, mkOnceUsedDmd, mkManyUsedDmd, mkHeadStrict, oneifyDmd,
toCleanDmd,
absDmd, topDmd, botDmd, seqDmd,
lubDmd, bothDmd,
lazyApply1Dmd, lazyApply2Dmd, strictApply1Dmd,
isTopDmd, isAbsDmd, isSeqDmd,
peelUseCall, cleanUseDmd_maybe, strictenDmd, bothCleanDmd,
addCaseBndrDmd,
DmdType(..), dmdTypeDepth, lubDmdType, bothDmdType,
BothDmdArg, mkBothDmdArg, toBothDmdArg,
nopDmdType, botDmdType, addDemand,
DmdEnv, emptyDmdEnv, keepAliveDmdEnv,
peelFV, findIdDemand,
Divergence(..), lubDivergence, isDeadEndDiv,
topDiv, botDiv, exnDiv,
appIsDeadEnd, isDeadEndSig, pprIfaceStrictSig,
StrictSig(..), mkStrictSigForArity, mkClosedStrictSig,
nopSig, botSig,
isTopSig, hasDemandEnvSig,
splitStrictSig, strictSigDmdEnv,
prependArgsStrictSig, etaConvertStrictSig,
seqDemand, seqDemandList, seqDmdType, seqStrictSig,
evalDmd, cleanEvalDmd, cleanEvalProdDmd, isStrictDmd,
splitDmdTy, splitFVs, deferAfterPreciseException,
postProcessUnsat, postProcessDmdType,
splitProdDmd_maybe, peelCallDmd, peelManyCalls, mkCallDmd, mkCallDmds,
mkWorkerDemand, dmdTransformSig, dmdTransformDataConSig,
dmdTransformDictSelSig, argOneShots, argsOneShots, saturatedByOneShots,
TypeShape(..), trimToType,
useCount, isUsedOnce, reuseEnv,
zapUsageDemand, zapUsageEnvSig,
zapUsedOnceDemand, zapUsedOnceSig,
strictifyDictDmd, strictifyDmd
) where
#include "HsVersions.h"
import GHC.Prelude
import GHC.Utils.Outputable
import GHC.Types.Var ( Var, Id )
import GHC.Types.Var.Env
import GHC.Types.Var.Set
import GHC.Types.Unique.FM
import GHC.Utils.Misc
import GHC.Types.Basic
import GHC.Utils.Binary
import GHC.Data.Maybe ( orElse )
import GHC.Core.Type ( Type )
import GHC.Core.TyCon ( isNewTyCon, isClassTyCon )
import GHC.Core.DataCon ( splitDataProductType_maybe )
import GHC.Core.Multiplicity ( scaledThing )
data JointDmd s u = JD { forall s u. JointDmd s u -> s
sd :: s, forall s u. JointDmd s u -> u
ud :: u }
deriving ( JointDmd s u -> JointDmd s u -> Bool
(JointDmd s u -> JointDmd s u -> Bool)
-> (JointDmd s u -> JointDmd s u -> Bool) -> Eq (JointDmd s u)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall s u. (Eq s, Eq u) => JointDmd s u -> JointDmd s u -> Bool
/= :: JointDmd s u -> JointDmd s u -> Bool
$c/= :: forall s u. (Eq s, Eq u) => JointDmd s u -> JointDmd s u -> Bool
== :: JointDmd s u -> JointDmd s u -> Bool
$c== :: forall s u. (Eq s, Eq u) => JointDmd s u -> JointDmd s u -> Bool
Eq, Int -> JointDmd s u -> ShowS
[JointDmd s u] -> ShowS
JointDmd s u -> String
(Int -> JointDmd s u -> ShowS)
-> (JointDmd s u -> String)
-> ([JointDmd s u] -> ShowS)
-> Show (JointDmd s u)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall s u. (Show s, Show u) => Int -> JointDmd s u -> ShowS
forall s u. (Show s, Show u) => [JointDmd s u] -> ShowS
forall s u. (Show s, Show u) => JointDmd s u -> String
showList :: [JointDmd s u] -> ShowS
$cshowList :: forall s u. (Show s, Show u) => [JointDmd s u] -> ShowS
show :: JointDmd s u -> String
$cshow :: forall s u. (Show s, Show u) => JointDmd s u -> String
showsPrec :: Int -> JointDmd s u -> ShowS
$cshowsPrec :: forall s u. (Show s, Show u) => Int -> JointDmd s u -> ShowS
Show )
getStrDmd :: JointDmd s u -> s
getStrDmd :: forall s u. JointDmd s u -> s
getStrDmd = JointDmd s u -> s
forall s u. JointDmd s u -> s
sd
getUseDmd :: JointDmd s u -> u
getUseDmd :: forall s u. JointDmd s u -> u
getUseDmd = JointDmd s u -> u
forall s u. JointDmd s u -> u
ud
instance (Outputable s, Outputable u) => Outputable (JointDmd s u) where
ppr :: JointDmd s u -> SDoc
ppr (JD {sd :: forall s u. JointDmd s u -> s
sd = s
s, ud :: forall s u. JointDmd s u -> u
ud = u
u}) = SDoc -> SDoc
angleBrackets (s -> SDoc
forall a. Outputable a => a -> SDoc
ppr s
s SDoc -> SDoc -> SDoc
<> Char -> SDoc
char Char
',' SDoc -> SDoc -> SDoc
<> u -> SDoc
forall a. Outputable a => a -> SDoc
ppr u
u)
mkJointDmd :: s -> u -> JointDmd s u
mkJointDmd :: forall s u. s -> u -> JointDmd s u
mkJointDmd s
s u
u = JD :: forall s u. s -> u -> JointDmd s u
JD { sd :: s
sd = s
s, ud :: u
ud = u
u }
mkJointDmds :: [s] -> [u] -> [JointDmd s u]
mkJointDmds :: forall s u. [s] -> [u] -> [JointDmd s u]
mkJointDmds [s]
ss [u]
as = String -> (s -> u -> JointDmd s u) -> [s] -> [u] -> [JointDmd s u]
forall a b c. String -> (a -> b -> c) -> [a] -> [b] -> [c]
zipWithEqual String
"mkJointDmds" s -> u -> JointDmd s u
forall s u. s -> u -> JointDmd s u
mkJointDmd [s]
ss [u]
as
data StrDmd
= HyperStr
| SCall StrDmd
| SProd [ArgStr]
| HeadStr
deriving ( StrDmd -> StrDmd -> Bool
(StrDmd -> StrDmd -> Bool)
-> (StrDmd -> StrDmd -> Bool) -> Eq StrDmd
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: StrDmd -> StrDmd -> Bool
$c/= :: StrDmd -> StrDmd -> Bool
== :: StrDmd -> StrDmd -> Bool
$c== :: StrDmd -> StrDmd -> Bool
Eq, Int -> StrDmd -> ShowS
[StrDmd] -> ShowS
StrDmd -> String
(Int -> StrDmd -> ShowS)
-> (StrDmd -> String) -> ([StrDmd] -> ShowS) -> Show StrDmd
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [StrDmd] -> ShowS
$cshowList :: [StrDmd] -> ShowS
show :: StrDmd -> String
$cshow :: StrDmd -> String
showsPrec :: Int -> StrDmd -> ShowS
$cshowsPrec :: Int -> StrDmd -> ShowS
Show )
type ArgStr = Str StrDmd
data Str s = Lazy
| Str s
deriving ( Str s -> Str s -> Bool
(Str s -> Str s -> Bool) -> (Str s -> Str s -> Bool) -> Eq (Str s)
forall s. Eq s => Str s -> Str s -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Str s -> Str s -> Bool
$c/= :: forall s. Eq s => Str s -> Str s -> Bool
== :: Str s -> Str s -> Bool
$c== :: forall s. Eq s => Str s -> Str s -> Bool
Eq, Int -> Str s -> ShowS
[Str s] -> ShowS
Str s -> String
(Int -> Str s -> ShowS)
-> (Str s -> String) -> ([Str s] -> ShowS) -> Show (Str s)
forall s. Show s => Int -> Str s -> ShowS
forall s. Show s => [Str s] -> ShowS
forall s. Show s => Str s -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Str s] -> ShowS
$cshowList :: forall s. Show s => [Str s] -> ShowS
show :: Str s -> String
$cshow :: forall s. Show s => Str s -> String
showsPrec :: Int -> Str s -> ShowS
$cshowsPrec :: forall s. Show s => Int -> Str s -> ShowS
Show )
strBot, strTop :: ArgStr
strBot :: ArgStr
strBot = StrDmd -> ArgStr
forall s. s -> Str s
Str StrDmd
HyperStr
strTop :: ArgStr
strTop = ArgStr
forall s. Str s
Lazy
mkSCall :: StrDmd -> StrDmd
mkSCall :: StrDmd -> StrDmd
mkSCall StrDmd
HyperStr = StrDmd
HyperStr
mkSCall StrDmd
s = StrDmd -> StrDmd
SCall StrDmd
s
mkSProd :: [ArgStr] -> StrDmd
mkSProd :: [ArgStr] -> StrDmd
mkSProd [ArgStr]
sx
| (ArgStr -> Bool) -> [ArgStr] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any ArgStr -> Bool
isHyperStr [ArgStr]
sx = StrDmd
HyperStr
| (ArgStr -> Bool) -> [ArgStr] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all ArgStr -> Bool
isLazy [ArgStr]
sx = StrDmd
HeadStr
| Bool
otherwise = [ArgStr] -> StrDmd
SProd [ArgStr]
sx
isLazy :: ArgStr -> Bool
isLazy :: ArgStr -> Bool
isLazy ArgStr
Lazy = Bool
True
isLazy (Str {}) = Bool
False
isHyperStr :: ArgStr -> Bool
isHyperStr :: ArgStr -> Bool
isHyperStr (Str StrDmd
HyperStr) = Bool
True
isHyperStr ArgStr
_ = Bool
False
instance Outputable StrDmd where
ppr :: StrDmd -> SDoc
ppr StrDmd
HyperStr = Char -> SDoc
char Char
'B'
ppr (SCall StrDmd
s) = Char -> SDoc
char Char
'C' SDoc -> SDoc -> SDoc
<> SDoc -> SDoc
parens (StrDmd -> SDoc
forall a. Outputable a => a -> SDoc
ppr StrDmd
s)
ppr StrDmd
HeadStr = Char -> SDoc
char Char
'S'
ppr (SProd [ArgStr]
sx) = Char -> SDoc
char Char
'S' SDoc -> SDoc -> SDoc
<> SDoc -> SDoc
parens ([SDoc] -> SDoc
hcat ((ArgStr -> SDoc) -> [ArgStr] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map ArgStr -> SDoc
forall a. Outputable a => a -> SDoc
ppr [ArgStr]
sx))
instance Outputable ArgStr where
ppr :: ArgStr -> SDoc
ppr (Str StrDmd
s) = StrDmd -> SDoc
forall a. Outputable a => a -> SDoc
ppr StrDmd
s
ppr ArgStr
Lazy = Char -> SDoc
char Char
'L'
lubArgStr :: ArgStr -> ArgStr -> ArgStr
lubArgStr :: ArgStr -> ArgStr -> ArgStr
lubArgStr ArgStr
Lazy ArgStr
_ = ArgStr
forall s. Str s
Lazy
lubArgStr ArgStr
_ ArgStr
Lazy = ArgStr
forall s. Str s
Lazy
lubArgStr (Str StrDmd
s1) (Str StrDmd
s2) = StrDmd -> ArgStr
forall s. s -> Str s
Str (StrDmd
s1 StrDmd -> StrDmd -> StrDmd
`lubStr` StrDmd
s2)
lubStr :: StrDmd -> StrDmd -> StrDmd
lubStr :: StrDmd -> StrDmd -> StrDmd
lubStr StrDmd
HyperStr StrDmd
s = StrDmd
s
lubStr (SCall StrDmd
s1) StrDmd
HyperStr = StrDmd -> StrDmd
SCall StrDmd
s1
lubStr (SCall StrDmd
_) StrDmd
HeadStr = StrDmd
HeadStr
lubStr (SCall StrDmd
s1) (SCall StrDmd
s2) = StrDmd -> StrDmd
SCall (StrDmd
s1 StrDmd -> StrDmd -> StrDmd
`lubStr` StrDmd
s2)
lubStr (SCall StrDmd
_) (SProd [ArgStr]
_) = StrDmd
HeadStr
lubStr (SProd [ArgStr]
sx) StrDmd
HyperStr = [ArgStr] -> StrDmd
SProd [ArgStr]
sx
lubStr (SProd [ArgStr]
_) StrDmd
HeadStr = StrDmd
HeadStr
lubStr (SProd [ArgStr]
s1) (SProd [ArgStr]
s2)
| [ArgStr]
s1 [ArgStr] -> [ArgStr] -> Bool
forall a b. [a] -> [b] -> Bool
`equalLength` [ArgStr]
s2 = [ArgStr] -> StrDmd
mkSProd ((ArgStr -> ArgStr -> ArgStr) -> [ArgStr] -> [ArgStr] -> [ArgStr]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith ArgStr -> ArgStr -> ArgStr
lubArgStr [ArgStr]
s1 [ArgStr]
s2)
| Bool
otherwise = StrDmd
HeadStr
lubStr (SProd [ArgStr]
_) (SCall StrDmd
_) = StrDmd
HeadStr
lubStr StrDmd
HeadStr StrDmd
_ = StrDmd
HeadStr
bothArgStr :: ArgStr -> ArgStr -> ArgStr
bothArgStr :: ArgStr -> ArgStr -> ArgStr
bothArgStr ArgStr
Lazy ArgStr
s = ArgStr
s
bothArgStr ArgStr
s ArgStr
Lazy = ArgStr
s
bothArgStr (Str StrDmd
s1) (Str StrDmd
s2) = StrDmd -> ArgStr
forall s. s -> Str s
Str (StrDmd
s1 StrDmd -> StrDmd -> StrDmd
`bothStr` StrDmd
s2)
bothStr :: StrDmd -> StrDmd -> StrDmd
bothStr :: StrDmd -> StrDmd -> StrDmd
bothStr StrDmd
HyperStr StrDmd
_ = StrDmd
HyperStr
bothStr StrDmd
HeadStr StrDmd
s = StrDmd
s
bothStr (SCall StrDmd
_) StrDmd
HyperStr = StrDmd
HyperStr
bothStr (SCall StrDmd
s1) StrDmd
HeadStr = StrDmd -> StrDmd
SCall StrDmd
s1
bothStr (SCall StrDmd
s1) (SCall StrDmd
s2) = StrDmd -> StrDmd
SCall (StrDmd
s1 StrDmd -> StrDmd -> StrDmd
`bothStr` StrDmd
s2)
bothStr (SCall StrDmd
_) (SProd [ArgStr]
_) = StrDmd
HyperStr
bothStr (SProd [ArgStr]
_) StrDmd
HyperStr = StrDmd
HyperStr
bothStr (SProd [ArgStr]
s1) StrDmd
HeadStr = [ArgStr] -> StrDmd
SProd [ArgStr]
s1
bothStr (SProd [ArgStr]
s1) (SProd [ArgStr]
s2)
| [ArgStr]
s1 [ArgStr] -> [ArgStr] -> Bool
forall a b. [a] -> [b] -> Bool
`equalLength` [ArgStr]
s2 = [ArgStr] -> StrDmd
mkSProd ((ArgStr -> ArgStr -> ArgStr) -> [ArgStr] -> [ArgStr] -> [ArgStr]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith ArgStr -> ArgStr -> ArgStr
bothArgStr [ArgStr]
s1 [ArgStr]
s2)
| Bool
otherwise = StrDmd
HyperStr
bothStr (SProd [ArgStr]
_) (SCall StrDmd
_) = StrDmd
HyperStr
seqStrDmd :: StrDmd -> ()
seqStrDmd :: StrDmd -> ()
seqStrDmd (SProd [ArgStr]
ds) = [ArgStr] -> ()
seqStrDmdList [ArgStr]
ds
seqStrDmd (SCall StrDmd
s) = StrDmd -> ()
seqStrDmd StrDmd
s
seqStrDmd StrDmd
_ = ()
seqStrDmdList :: [ArgStr] -> ()
seqStrDmdList :: [ArgStr] -> ()
seqStrDmdList [] = ()
seqStrDmdList (ArgStr
d:[ArgStr]
ds) = ArgStr -> ()
seqArgStr ArgStr
d () -> () -> ()
`seq` [ArgStr] -> ()
seqStrDmdList [ArgStr]
ds
seqArgStr :: ArgStr -> ()
seqArgStr :: ArgStr -> ()
seqArgStr ArgStr
Lazy = ()
seqArgStr (Str StrDmd
s) = StrDmd -> ()
seqStrDmd StrDmd
s
splitArgStrProdDmd :: Int -> ArgStr -> Maybe [ArgStr]
splitArgStrProdDmd :: Int -> ArgStr -> Maybe [ArgStr]
splitArgStrProdDmd Int
n ArgStr
Lazy = [ArgStr] -> Maybe [ArgStr]
forall a. a -> Maybe a
Just (Int -> ArgStr -> [ArgStr]
forall a. Int -> a -> [a]
replicate Int
n ArgStr
forall s. Str s
Lazy)
splitArgStrProdDmd Int
n (Str StrDmd
s) = Int -> StrDmd -> Maybe [ArgStr]
splitStrProdDmd Int
n StrDmd
s
splitStrProdDmd :: Int -> StrDmd -> Maybe [ArgStr]
splitStrProdDmd :: Int -> StrDmd -> Maybe [ArgStr]
splitStrProdDmd Int
n StrDmd
HyperStr = [ArgStr] -> Maybe [ArgStr]
forall a. a -> Maybe a
Just (Int -> ArgStr -> [ArgStr]
forall a. Int -> a -> [a]
replicate Int
n ArgStr
strBot)
splitStrProdDmd Int
n StrDmd
HeadStr = [ArgStr] -> Maybe [ArgStr]
forall a. a -> Maybe a
Just (Int -> ArgStr -> [ArgStr]
forall a. Int -> a -> [a]
replicate Int
n ArgStr
strTop)
splitStrProdDmd Int
n (SProd [ArgStr]
ds) = WARN( not (ds `lengthIs` n),
text "splitStrProdDmd" $$ ppr n $$ ppr ds )
[ArgStr] -> Maybe [ArgStr]
forall a. a -> Maybe a
Just [ArgStr]
ds
splitStrProdDmd Int
_ (SCall {}) = Maybe [ArgStr]
forall a. Maybe a
Nothing
data UseDmd
= UCall Count UseDmd
| UProd [ArgUse]
| UHead
| Used
deriving ( UseDmd -> UseDmd -> Bool
(UseDmd -> UseDmd -> Bool)
-> (UseDmd -> UseDmd -> Bool) -> Eq UseDmd
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: UseDmd -> UseDmd -> Bool
$c/= :: UseDmd -> UseDmd -> Bool
== :: UseDmd -> UseDmd -> Bool
$c== :: UseDmd -> UseDmd -> Bool
Eq, Int -> UseDmd -> ShowS
[UseDmd] -> ShowS
UseDmd -> String
(Int -> UseDmd -> ShowS)
-> (UseDmd -> String) -> ([UseDmd] -> ShowS) -> Show UseDmd
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [UseDmd] -> ShowS
$cshowList :: [UseDmd] -> ShowS
show :: UseDmd -> String
$cshow :: UseDmd -> String
showsPrec :: Int -> UseDmd -> ShowS
$cshowsPrec :: Int -> UseDmd -> ShowS
Show )
type ArgUse = Use UseDmd
data Use u
= Abs
| Use Count u
deriving ( Use u -> Use u -> Bool
(Use u -> Use u -> Bool) -> (Use u -> Use u -> Bool) -> Eq (Use u)
forall u. Eq u => Use u -> Use u -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Use u -> Use u -> Bool
$c/= :: forall u. Eq u => Use u -> Use u -> Bool
== :: Use u -> Use u -> Bool
$c== :: forall u. Eq u => Use u -> Use u -> Bool
Eq, Int -> Use u -> ShowS
[Use u] -> ShowS
Use u -> String
(Int -> Use u -> ShowS)
-> (Use u -> String) -> ([Use u] -> ShowS) -> Show (Use u)
forall u. Show u => Int -> Use u -> ShowS
forall u. Show u => [Use u] -> ShowS
forall u. Show u => Use u -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Use u] -> ShowS
$cshowList :: forall u. Show u => [Use u] -> ShowS
show :: Use u -> String
$cshow :: forall u. Show u => Use u -> String
showsPrec :: Int -> Use u -> ShowS
$cshowsPrec :: forall u. Show u => Int -> Use u -> ShowS
Show )
data Count = One | Many
deriving ( Count -> Count -> Bool
(Count -> Count -> Bool) -> (Count -> Count -> Bool) -> Eq Count
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Count -> Count -> Bool
$c/= :: Count -> Count -> Bool
== :: Count -> Count -> Bool
$c== :: Count -> Count -> Bool
Eq, Int -> Count -> ShowS
[Count] -> ShowS
Count -> String
(Int -> Count -> ShowS)
-> (Count -> String) -> ([Count] -> ShowS) -> Show Count
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Count] -> ShowS
$cshowList :: [Count] -> ShowS
show :: Count -> String
$cshow :: Count -> String
showsPrec :: Int -> Count -> ShowS
$cshowsPrec :: Int -> Count -> ShowS
Show )
instance Outputable ArgUse where
ppr :: ArgUse -> SDoc
ppr ArgUse
Abs = Char -> SDoc
char Char
'A'
ppr (Use Count
Many UseDmd
a) = UseDmd -> SDoc
forall a. Outputable a => a -> SDoc
ppr UseDmd
a
ppr (Use Count
One UseDmd
a) = Char -> SDoc
char Char
'1' SDoc -> SDoc -> SDoc
<> Char -> SDoc
char Char
'*' SDoc -> SDoc -> SDoc
<> UseDmd -> SDoc
forall a. Outputable a => a -> SDoc
ppr UseDmd
a
instance Outputable UseDmd where
ppr :: UseDmd -> SDoc
ppr UseDmd
Used = Char -> SDoc
char Char
'U'
ppr (UCall Count
c UseDmd
a) = Char -> SDoc
char Char
'C' SDoc -> SDoc -> SDoc
<> Count -> SDoc
forall a. Outputable a => a -> SDoc
ppr Count
c SDoc -> SDoc -> SDoc
<> SDoc -> SDoc
parens (UseDmd -> SDoc
forall a. Outputable a => a -> SDoc
ppr UseDmd
a)
ppr UseDmd
UHead = Char -> SDoc
char Char
'H'
ppr (UProd [ArgUse]
as) = Char -> SDoc
char Char
'U' SDoc -> SDoc -> SDoc
<> SDoc -> SDoc
parens ([SDoc] -> SDoc
hcat (SDoc -> [SDoc] -> [SDoc]
punctuate (Char -> SDoc
char Char
',') ((ArgUse -> SDoc) -> [ArgUse] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map ArgUse -> SDoc
forall a. Outputable a => a -> SDoc
ppr [ArgUse]
as)))
instance Outputable Count where
ppr :: Count -> SDoc
ppr Count
One = Char -> SDoc
char Char
'1'
ppr Count
Many = String -> SDoc
text String
""
useBot, useTop :: ArgUse
useBot :: ArgUse
useBot = ArgUse
forall u. Use u
Abs
useTop :: ArgUse
useTop = Count -> UseDmd -> ArgUse
forall u. Count -> u -> Use u
Use Count
Many UseDmd
Used
mkUCall :: Count -> UseDmd -> UseDmd
mkUCall :: Count -> UseDmd -> UseDmd
mkUCall Count
c UseDmd
a = Count -> UseDmd -> UseDmd
UCall Count
c UseDmd
a
mkUProd :: [ArgUse] -> UseDmd
mkUProd :: [ArgUse] -> UseDmd
mkUProd [ArgUse]
ux
| (ArgUse -> Bool) -> [ArgUse] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (ArgUse -> ArgUse -> Bool
forall a. Eq a => a -> a -> Bool
== ArgUse
forall u. Use u
Abs) [ArgUse]
ux = UseDmd
UHead
| Bool
otherwise = [ArgUse] -> UseDmd
UProd [ArgUse]
ux
lubCount :: Count -> Count -> Count
lubCount :: Count -> Count -> Count
lubCount Count
_ Count
Many = Count
Many
lubCount Count
Many Count
_ = Count
Many
lubCount Count
x Count
_ = Count
x
lubArgUse :: ArgUse -> ArgUse -> ArgUse
lubArgUse :: ArgUse -> ArgUse -> ArgUse
lubArgUse ArgUse
Abs ArgUse
x = ArgUse
x
lubArgUse ArgUse
x ArgUse
Abs = ArgUse
x
lubArgUse (Use Count
c1 UseDmd
a1) (Use Count
c2 UseDmd
a2) = Count -> UseDmd -> ArgUse
forall u. Count -> u -> Use u
Use (Count -> Count -> Count
lubCount Count
c1 Count
c2) (UseDmd -> UseDmd -> UseDmd
lubUse UseDmd
a1 UseDmd
a2)
lubUse :: UseDmd -> UseDmd -> UseDmd
lubUse :: UseDmd -> UseDmd -> UseDmd
lubUse UseDmd
UHead UseDmd
u = UseDmd
u
lubUse (UCall Count
c UseDmd
u) UseDmd
UHead = Count -> UseDmd -> UseDmd
UCall Count
c UseDmd
u
lubUse (UCall Count
c1 UseDmd
u1) (UCall Count
c2 UseDmd
u2) = Count -> UseDmd -> UseDmd
UCall (Count -> Count -> Count
lubCount Count
c1 Count
c2) (UseDmd -> UseDmd -> UseDmd
lubUse UseDmd
u1 UseDmd
u2)
lubUse (UCall Count
_ UseDmd
_) UseDmd
_ = UseDmd
Used
lubUse (UProd [ArgUse]
ux) UseDmd
UHead = [ArgUse] -> UseDmd
UProd [ArgUse]
ux
lubUse (UProd [ArgUse]
ux1) (UProd [ArgUse]
ux2)
| [ArgUse]
ux1 [ArgUse] -> [ArgUse] -> Bool
forall a b. [a] -> [b] -> Bool
`equalLength` [ArgUse]
ux2 = [ArgUse] -> UseDmd
UProd ([ArgUse] -> UseDmd) -> [ArgUse] -> UseDmd
forall a b. (a -> b) -> a -> b
$ (ArgUse -> ArgUse -> ArgUse) -> [ArgUse] -> [ArgUse] -> [ArgUse]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith ArgUse -> ArgUse -> ArgUse
lubArgUse [ArgUse]
ux1 [ArgUse]
ux2
| Bool
otherwise = UseDmd
Used
lubUse (UProd {}) (UCall {}) = UseDmd
Used
lubUse (UProd [ArgUse]
ux) UseDmd
Used = [ArgUse] -> UseDmd
UProd ((ArgUse -> ArgUse) -> [ArgUse] -> [ArgUse]
forall a b. (a -> b) -> [a] -> [b]
map (ArgUse -> ArgUse -> ArgUse
`lubArgUse` ArgUse
useTop) [ArgUse]
ux)
lubUse UseDmd
Used (UProd [ArgUse]
ux) = [ArgUse] -> UseDmd
UProd ((ArgUse -> ArgUse) -> [ArgUse] -> [ArgUse]
forall a b. (a -> b) -> [a] -> [b]
map (ArgUse -> ArgUse -> ArgUse
`lubArgUse` ArgUse
useTop) [ArgUse]
ux)
lubUse UseDmd
Used UseDmd
_ = UseDmd
Used
bothArgUse :: ArgUse -> ArgUse -> ArgUse
bothArgUse :: ArgUse -> ArgUse -> ArgUse
bothArgUse ArgUse
Abs ArgUse
x = ArgUse
x
bothArgUse ArgUse
x ArgUse
Abs = ArgUse
x
bothArgUse (Use Count
_ UseDmd
a1) (Use Count
_ UseDmd
a2) = Count -> UseDmd -> ArgUse
forall u. Count -> u -> Use u
Use Count
Many (UseDmd -> UseDmd -> UseDmd
bothUse UseDmd
a1 UseDmd
a2)
bothUse :: UseDmd -> UseDmd -> UseDmd
bothUse :: UseDmd -> UseDmd -> UseDmd
bothUse UseDmd
UHead UseDmd
u = UseDmd
u
bothUse (UCall Count
c UseDmd
u) UseDmd
UHead = Count -> UseDmd -> UseDmd
UCall Count
c UseDmd
u
bothUse (UCall Count
_ UseDmd
u1) (UCall Count
_ UseDmd
u2) = Count -> UseDmd -> UseDmd
UCall Count
Many (UseDmd
u1 UseDmd -> UseDmd -> UseDmd
`lubUse` UseDmd
u2)
bothUse (UCall {}) UseDmd
_ = UseDmd
Used
bothUse (UProd [ArgUse]
ux) UseDmd
UHead = [ArgUse] -> UseDmd
UProd [ArgUse]
ux
bothUse (UProd [ArgUse]
ux1) (UProd [ArgUse]
ux2)
| [ArgUse]
ux1 [ArgUse] -> [ArgUse] -> Bool
forall a b. [a] -> [b] -> Bool
`equalLength` [ArgUse]
ux2 = [ArgUse] -> UseDmd
UProd ([ArgUse] -> UseDmd) -> [ArgUse] -> UseDmd
forall a b. (a -> b) -> a -> b
$ (ArgUse -> ArgUse -> ArgUse) -> [ArgUse] -> [ArgUse] -> [ArgUse]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith ArgUse -> ArgUse -> ArgUse
bothArgUse [ArgUse]
ux1 [ArgUse]
ux2
| Bool
otherwise = UseDmd
Used
bothUse (UProd {}) (UCall {}) = UseDmd
Used
bothUse UseDmd
Used (UProd [ArgUse]
ux) = [ArgUse] -> UseDmd
UProd ((ArgUse -> ArgUse) -> [ArgUse] -> [ArgUse]
forall a b. (a -> b) -> [a] -> [b]
map (ArgUse -> ArgUse -> ArgUse
`bothArgUse` ArgUse
useTop) [ArgUse]
ux)
bothUse (UProd [ArgUse]
ux) UseDmd
Used = [ArgUse] -> UseDmd
UProd ((ArgUse -> ArgUse) -> [ArgUse] -> [ArgUse]
forall a b. (a -> b) -> [a] -> [b]
map (ArgUse -> ArgUse -> ArgUse
`bothArgUse` ArgUse
useTop) [ArgUse]
ux)
bothUse UseDmd
Used UseDmd
_ = UseDmd
Used
peelUseCall :: UseDmd -> Maybe (Count, UseDmd)
peelUseCall :: UseDmd -> Maybe (Count, UseDmd)
peelUseCall (UCall Count
c UseDmd
u) = (Count, UseDmd) -> Maybe (Count, UseDmd)
forall a. a -> Maybe a
Just (Count
c,UseDmd
u)
peelUseCall UseDmd
_ = Maybe (Count, UseDmd)
forall a. Maybe a
Nothing
addCaseBndrDmd :: Demand
-> [Demand]
-> [Demand]
addCaseBndrDmd :: Demand -> [Demand] -> [Demand]
addCaseBndrDmd (JD { sd :: forall s u. JointDmd s u -> s
sd = ArgStr
ms, ud :: forall s u. JointDmd s u -> u
ud = ArgUse
mu }) [Demand]
alt_dmds
= case ArgUse
mu of
ArgUse
Abs -> [Demand]
alt_dmds
Use Count
_ UseDmd
u -> (Demand -> Demand -> Demand) -> [Demand] -> [Demand] -> [Demand]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Demand -> Demand -> Demand
bothDmd [Demand]
alt_dmds ([ArgStr] -> [ArgUse] -> [Demand]
forall s u. [s] -> [u] -> [JointDmd s u]
mkJointDmds [ArgStr]
ss [ArgUse]
us)
where
Just [ArgStr]
ss = Int -> ArgStr -> Maybe [ArgStr]
splitArgStrProdDmd Int
arity ArgStr
ms
Just [ArgUse]
us = Int -> UseDmd -> Maybe [ArgUse]
splitUseProdDmd Int
arity UseDmd
u
where
arity :: Int
arity = [Demand] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Demand]
alt_dmds
markReusedDmd :: ArgUse -> ArgUse
markReusedDmd :: ArgUse -> ArgUse
markReusedDmd ArgUse
Abs = ArgUse
forall u. Use u
Abs
markReusedDmd (Use Count
_ UseDmd
a) = Count -> UseDmd -> ArgUse
forall u. Count -> u -> Use u
Use Count
Many (UseDmd -> UseDmd
markReused UseDmd
a)
markReused :: UseDmd -> UseDmd
markReused :: UseDmd -> UseDmd
markReused (UCall Count
_ UseDmd
u) = Count -> UseDmd -> UseDmd
UCall Count
Many UseDmd
u
markReused (UProd [ArgUse]
ux) = [ArgUse] -> UseDmd
UProd ((ArgUse -> ArgUse) -> [ArgUse] -> [ArgUse]
forall a b. (a -> b) -> [a] -> [b]
map ArgUse -> ArgUse
markReusedDmd [ArgUse]
ux)
markReused UseDmd
u = UseDmd
u
isUsedMU :: ArgUse -> Bool
isUsedMU :: ArgUse -> Bool
isUsedMU ArgUse
Abs = Bool
True
isUsedMU (Use Count
One UseDmd
_) = Bool
False
isUsedMU (Use Count
Many UseDmd
u) = UseDmd -> Bool
isUsedU UseDmd
u
isUsedU :: UseDmd -> Bool
isUsedU :: UseDmd -> Bool
isUsedU UseDmd
Used = Bool
True
isUsedU UseDmd
UHead = Bool
True
isUsedU (UProd [ArgUse]
us) = (ArgUse -> Bool) -> [ArgUse] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all ArgUse -> Bool
isUsedMU [ArgUse]
us
isUsedU (UCall Count
One UseDmd
_) = Bool
False
isUsedU (UCall Count
Many UseDmd
_) = Bool
True
seqUseDmd :: UseDmd -> ()
seqUseDmd :: UseDmd -> ()
seqUseDmd (UProd [ArgUse]
ds) = [ArgUse] -> ()
seqArgUseList [ArgUse]
ds
seqUseDmd (UCall Count
c UseDmd
d) = Count
c Count -> () -> ()
`seq` UseDmd -> ()
seqUseDmd UseDmd
d
seqUseDmd UseDmd
_ = ()
seqArgUseList :: [ArgUse] -> ()
seqArgUseList :: [ArgUse] -> ()
seqArgUseList [] = ()
seqArgUseList (ArgUse
d:[ArgUse]
ds) = ArgUse -> ()
seqArgUse ArgUse
d () -> () -> ()
`seq` [ArgUse] -> ()
seqArgUseList [ArgUse]
ds
seqArgUse :: ArgUse -> ()
seqArgUse :: ArgUse -> ()
seqArgUse (Use Count
c UseDmd
u) = Count
c Count -> () -> ()
`seq` UseDmd -> ()
seqUseDmd UseDmd
u
seqArgUse ArgUse
_ = ()
splitUseProdDmd :: Int -> UseDmd -> Maybe [ArgUse]
splitUseProdDmd :: Int -> UseDmd -> Maybe [ArgUse]
splitUseProdDmd Int
n UseDmd
Used = [ArgUse] -> Maybe [ArgUse]
forall a. a -> Maybe a
Just (Int -> ArgUse -> [ArgUse]
forall a. Int -> a -> [a]
replicate Int
n ArgUse
useTop)
splitUseProdDmd Int
n UseDmd
UHead = [ArgUse] -> Maybe [ArgUse]
forall a. a -> Maybe a
Just (Int -> ArgUse -> [ArgUse]
forall a. Int -> a -> [a]
replicate Int
n ArgUse
forall u. Use u
Abs)
splitUseProdDmd Int
n (UProd [ArgUse]
ds) = WARN( not (ds `lengthIs` n),
text "splitUseProdDmd" $$ ppr n
$$ ppr ds )
[ArgUse] -> Maybe [ArgUse]
forall a. a -> Maybe a
Just [ArgUse]
ds
splitUseProdDmd Int
_ (UCall Count
_ UseDmd
_) = Maybe [ArgUse]
forall a. Maybe a
Nothing
useCount :: Use u -> Count
useCount :: forall u. Use u -> Count
useCount Use u
Abs = Count
One
useCount (Use Count
One u
_) = Count
One
useCount Use u
_ = Count
Many
type CleanDemand = JointDmd StrDmd UseDmd
bothCleanDmd :: CleanDemand -> CleanDemand -> CleanDemand
bothCleanDmd :: CleanDemand -> CleanDemand -> CleanDemand
bothCleanDmd (JD { sd :: forall s u. JointDmd s u -> s
sd = StrDmd
s1, ud :: forall s u. JointDmd s u -> u
ud = UseDmd
a1}) (JD { sd :: forall s u. JointDmd s u -> s
sd = StrDmd
s2, ud :: forall s u. JointDmd s u -> u
ud = UseDmd
a2})
= JD :: forall s u. s -> u -> JointDmd s u
JD { sd :: StrDmd
sd = StrDmd
s1 StrDmd -> StrDmd -> StrDmd
`bothStr` StrDmd
s2, ud :: UseDmd
ud = UseDmd
a1 UseDmd -> UseDmd -> UseDmd
`bothUse` UseDmd
a2 }
mkHeadStrict :: CleanDemand -> CleanDemand
mkHeadStrict :: CleanDemand -> CleanDemand
mkHeadStrict CleanDemand
cd = CleanDemand
cd { sd :: StrDmd
sd = StrDmd
HeadStr }
mkOnceUsedDmd, mkManyUsedDmd :: CleanDemand -> Demand
mkOnceUsedDmd :: CleanDemand -> Demand
mkOnceUsedDmd (JD {sd :: forall s u. JointDmd s u -> s
sd = StrDmd
s,ud :: forall s u. JointDmd s u -> u
ud = UseDmd
a}) = JD :: forall s u. s -> u -> JointDmd s u
JD { sd :: ArgStr
sd = StrDmd -> ArgStr
forall s. s -> Str s
Str StrDmd
s, ud :: ArgUse
ud = Count -> UseDmd -> ArgUse
forall u. Count -> u -> Use u
Use Count
One UseDmd
a }
mkManyUsedDmd :: CleanDemand -> Demand
mkManyUsedDmd (JD {sd :: forall s u. JointDmd s u -> s
sd = StrDmd
s,ud :: forall s u. JointDmd s u -> u
ud = UseDmd
a}) = JD :: forall s u. s -> u -> JointDmd s u
JD { sd :: ArgStr
sd = StrDmd -> ArgStr
forall s. s -> Str s
Str StrDmd
s, ud :: ArgUse
ud = Count -> UseDmd -> ArgUse
forall u. Count -> u -> Use u
Use Count
Many UseDmd
a }
evalDmd :: Demand
evalDmd :: Demand
evalDmd = JD :: forall s u. s -> u -> JointDmd s u
JD { sd :: ArgStr
sd = StrDmd -> ArgStr
forall s. s -> Str s
Str StrDmd
HeadStr, ud :: ArgUse
ud = ArgUse
useTop }
mkProdDmd :: [Demand] -> CleanDemand
mkProdDmd :: [Demand] -> CleanDemand
mkProdDmd [Demand]
dx
= JD :: forall s u. s -> u -> JointDmd s u
JD { sd :: StrDmd
sd = [ArgStr] -> StrDmd
mkSProd ([ArgStr] -> StrDmd) -> [ArgStr] -> StrDmd
forall a b. (a -> b) -> a -> b
$ (Demand -> ArgStr) -> [Demand] -> [ArgStr]
forall a b. (a -> b) -> [a] -> [b]
map Demand -> ArgStr
forall s u. JointDmd s u -> s
getStrDmd [Demand]
dx
, ud :: UseDmd
ud = [ArgUse] -> UseDmd
mkUProd ([ArgUse] -> UseDmd) -> [ArgUse] -> UseDmd
forall a b. (a -> b) -> a -> b
$ (Demand -> ArgUse) -> [Demand] -> [ArgUse]
forall a b. (a -> b) -> [a] -> [b]
map Demand -> ArgUse
forall s u. JointDmd s u -> u
getUseDmd [Demand]
dx }
mkCallDmd :: CleanDemand -> CleanDemand
mkCallDmd :: CleanDemand -> CleanDemand
mkCallDmd (JD {sd :: forall s u. JointDmd s u -> s
sd = StrDmd
d, ud :: forall s u. JointDmd s u -> u
ud = UseDmd
u})
= JD :: forall s u. s -> u -> JointDmd s u
JD { sd :: StrDmd
sd = StrDmd -> StrDmd
mkSCall StrDmd
d, ud :: UseDmd
ud = Count -> UseDmd -> UseDmd
mkUCall Count
One UseDmd
u }
mkCallDmds :: Arity -> CleanDemand -> CleanDemand
mkCallDmds :: Int -> CleanDemand -> CleanDemand
mkCallDmds Int
arity CleanDemand
cd = (CleanDemand -> CleanDemand) -> CleanDemand -> [CleanDemand]
forall a. (a -> a) -> a -> [a]
iterate CleanDemand -> CleanDemand
mkCallDmd CleanDemand
cd [CleanDemand] -> Int -> CleanDemand
forall a. [a] -> Int -> a
!! Int
arity
mkWorkerDemand :: Int -> Demand
mkWorkerDemand :: Int -> Demand
mkWorkerDemand Int
n = JD :: forall s u. s -> u -> JointDmd s u
JD { sd :: ArgStr
sd = ArgStr
forall s. Str s
Lazy, ud :: ArgUse
ud = Count -> UseDmd -> ArgUse
forall u. Count -> u -> Use u
Use Count
One (Int -> UseDmd
forall {t}. (Eq t, Num t) => t -> UseDmd
go Int
n) }
where go :: t -> UseDmd
go t
0 = UseDmd
Used
go t
n = Count -> UseDmd -> UseDmd
mkUCall Count
One (UseDmd -> UseDmd) -> UseDmd -> UseDmd
forall a b. (a -> b) -> a -> b
$ t -> UseDmd
go (t
nt -> t -> t
forall a. Num a => a -> a -> a
-t
1)
cleanEvalDmd :: CleanDemand
cleanEvalDmd :: CleanDemand
cleanEvalDmd = JD :: forall s u. s -> u -> JointDmd s u
JD { sd :: StrDmd
sd = StrDmd
HeadStr, ud :: UseDmd
ud = UseDmd
Used }
cleanEvalProdDmd :: Arity -> CleanDemand
cleanEvalProdDmd :: Int -> CleanDemand
cleanEvalProdDmd Int
n = JD :: forall s u. s -> u -> JointDmd s u
JD { sd :: StrDmd
sd = StrDmd
HeadStr, ud :: UseDmd
ud = [ArgUse] -> UseDmd
UProd (Int -> ArgUse -> [ArgUse]
forall a. Int -> a -> [a]
replicate Int
n ArgUse
useTop) }
type Demand = JointDmd ArgStr ArgUse
lubDmd :: Demand -> Demand -> Demand
lubDmd :: Demand -> Demand -> Demand
lubDmd (JD {sd :: forall s u. JointDmd s u -> s
sd = ArgStr
s1, ud :: forall s u. JointDmd s u -> u
ud = ArgUse
a1}) (JD {sd :: forall s u. JointDmd s u -> s
sd = ArgStr
s2, ud :: forall s u. JointDmd s u -> u
ud = ArgUse
a2})
= JD :: forall s u. s -> u -> JointDmd s u
JD { sd :: ArgStr
sd = ArgStr
s1 ArgStr -> ArgStr -> ArgStr
`lubArgStr` ArgStr
s2
, ud :: ArgUse
ud = ArgUse
a1 ArgUse -> ArgUse -> ArgUse
`lubArgUse` ArgUse
a2 }
bothDmd :: Demand -> Demand -> Demand
bothDmd :: Demand -> Demand -> Demand
bothDmd (JD {sd :: forall s u. JointDmd s u -> s
sd = ArgStr
s1, ud :: forall s u. JointDmd s u -> u
ud = ArgUse
a1}) (JD {sd :: forall s u. JointDmd s u -> s
sd = ArgStr
s2, ud :: forall s u. JointDmd s u -> u
ud = ArgUse
a2})
= JD :: forall s u. s -> u -> JointDmd s u
JD { sd :: ArgStr
sd = ArgStr
s1 ArgStr -> ArgStr -> ArgStr
`bothArgStr` ArgStr
s2
, ud :: ArgUse
ud = ArgUse
a1 ArgUse -> ArgUse -> ArgUse
`bothArgUse` ArgUse
a2 }
lazyApply1Dmd, lazyApply2Dmd, strictApply1Dmd :: Demand
strictApply1Dmd :: Demand
strictApply1Dmd = JD :: forall s u. s -> u -> JointDmd s u
JD { sd :: ArgStr
sd = StrDmd -> ArgStr
forall s. s -> Str s
Str (StrDmd -> StrDmd
SCall StrDmd
HeadStr)
, ud :: ArgUse
ud = Count -> UseDmd -> ArgUse
forall u. Count -> u -> Use u
Use Count
Many (Count -> UseDmd -> UseDmd
UCall Count
One UseDmd
Used) }
lazyApply1Dmd :: Demand
lazyApply1Dmd = JD :: forall s u. s -> u -> JointDmd s u
JD { sd :: ArgStr
sd = ArgStr
forall s. Str s
Lazy
, ud :: ArgUse
ud = Count -> UseDmd -> ArgUse
forall u. Count -> u -> Use u
Use Count
One (Count -> UseDmd -> UseDmd
UCall Count
One UseDmd
Used) }
lazyApply2Dmd :: Demand
lazyApply2Dmd = JD :: forall s u. s -> u -> JointDmd s u
JD { sd :: ArgStr
sd = ArgStr
forall s. Str s
Lazy
, ud :: ArgUse
ud = Count -> UseDmd -> ArgUse
forall u. Count -> u -> Use u
Use Count
One (Count -> UseDmd -> UseDmd
UCall Count
One (Count -> UseDmd -> UseDmd
UCall Count
One UseDmd
Used)) }
absDmd :: Demand
absDmd :: Demand
absDmd = JD :: forall s u. s -> u -> JointDmd s u
JD { sd :: ArgStr
sd = ArgStr
forall s. Str s
Lazy, ud :: ArgUse
ud = ArgUse
forall u. Use u
Abs }
topDmd :: Demand
topDmd :: Demand
topDmd = JD :: forall s u. s -> u -> JointDmd s u
JD { sd :: ArgStr
sd = ArgStr
forall s. Str s
Lazy, ud :: ArgUse
ud = ArgUse
useTop }
botDmd :: Demand
botDmd :: Demand
botDmd = JD :: forall s u. s -> u -> JointDmd s u
JD { sd :: ArgStr
sd = ArgStr
strBot, ud :: ArgUse
ud = ArgUse
useBot }
seqDmd :: Demand
seqDmd :: Demand
seqDmd = JD :: forall s u. s -> u -> JointDmd s u
JD { sd :: ArgStr
sd = StrDmd -> ArgStr
forall s. s -> Str s
Str StrDmd
HeadStr, ud :: ArgUse
ud = Count -> UseDmd -> ArgUse
forall u. Count -> u -> Use u
Use Count
One UseDmd
UHead }
oneifyDmd :: JointDmd s (Use u) -> JointDmd s (Use u)
oneifyDmd :: forall s u. JointDmd s (Use u) -> JointDmd s (Use u)
oneifyDmd (JD { sd :: forall s u. JointDmd s u -> s
sd = s
s, ud :: forall s u. JointDmd s u -> u
ud = Use Count
_ u
a }) = JD :: forall s u. s -> u -> JointDmd s u
JD { sd :: s
sd = s
s, ud :: Use u
ud = Count -> u -> Use u
forall u. Count -> u -> Use u
Use Count
One u
a }
oneifyDmd JointDmd s (Use u)
jd = JointDmd s (Use u)
jd
isTopDmd :: Demand -> Bool
isTopDmd :: Demand -> Bool
isTopDmd (JD {sd :: forall s u. JointDmd s u -> s
sd = ArgStr
Lazy, ud :: forall s u. JointDmd s u -> u
ud = Use Count
Many UseDmd
Used}) = Bool
True
isTopDmd Demand
_ = Bool
False
isAbsDmd :: JointDmd (Str s) (Use u) -> Bool
isAbsDmd :: forall s u. JointDmd (Str s) (Use u) -> Bool
isAbsDmd (JD {ud :: forall s u. JointDmd s u -> u
ud = Use u
Abs}) = Bool
True
isAbsDmd JointDmd (Str s) (Use u)
_ = Bool
False
isSeqDmd :: Demand -> Bool
isSeqDmd :: Demand -> Bool
isSeqDmd (JD {sd :: forall s u. JointDmd s u -> s
sd = Str StrDmd
HeadStr, ud :: forall s u. JointDmd s u -> u
ud = Use Count
_ UseDmd
UHead}) = Bool
True
isSeqDmd Demand
_ = Bool
False
isUsedOnce :: JointDmd (Str s) (Use u) -> Bool
isUsedOnce :: forall s u. JointDmd (Str s) (Use u) -> Bool
isUsedOnce (JD { ud :: forall s u. JointDmd s u -> u
ud = Use u
a }) = case Use u -> Count
forall u. Use u -> Count
useCount Use u
a of
Count
One -> Bool
True
Count
Many -> Bool
False
seqDemand :: Demand -> ()
seqDemand :: Demand -> ()
seqDemand (JD {sd :: forall s u. JointDmd s u -> s
sd = ArgStr
s, ud :: forall s u. JointDmd s u -> u
ud = ArgUse
u}) = ArgStr -> ()
seqArgStr ArgStr
s () -> () -> ()
`seq` ArgUse -> ()
seqArgUse ArgUse
u
seqDemandList :: [Demand] -> ()
seqDemandList :: [Demand] -> ()
seqDemandList [] = ()
seqDemandList (Demand
d:[Demand]
ds) = Demand -> ()
seqDemand Demand
d () -> () -> ()
`seq` [Demand] -> ()
seqDemandList [Demand]
ds
isStrictDmd :: JointDmd (Str s) (Use u) -> Bool
isStrictDmd :: forall s u. JointDmd (Str s) (Use u) -> Bool
isStrictDmd (JD {ud :: forall s u. JointDmd s u -> u
ud = Use u
Abs}) = Bool
False
isStrictDmd (JD {sd :: forall s u. JointDmd s u -> s
sd = Str s
Lazy}) = Bool
False
isStrictDmd JointDmd (Str s) (Use u)
_ = Bool
True
isWeakDmd :: Demand -> Bool
isWeakDmd :: Demand -> Bool
isWeakDmd (JD {sd :: forall s u. JointDmd s u -> s
sd = ArgStr
s, ud :: forall s u. JointDmd s u -> u
ud = ArgUse
a}) = ArgStr -> Bool
isLazy ArgStr
s Bool -> Bool -> Bool
&& ArgUse -> Bool
isUsedMU ArgUse
a
cleanUseDmd_maybe :: Demand -> Maybe UseDmd
cleanUseDmd_maybe :: Demand -> Maybe UseDmd
cleanUseDmd_maybe (JD { ud :: forall s u. JointDmd s u -> u
ud = Use Count
_ UseDmd
u }) = UseDmd -> Maybe UseDmd
forall a. a -> Maybe a
Just UseDmd
u
cleanUseDmd_maybe Demand
_ = Maybe UseDmd
forall a. Maybe a
Nothing
splitFVs :: Bool
-> DmdEnv -> (DmdEnv, DmdEnv)
splitFVs :: Bool -> DmdEnv -> (DmdEnv, DmdEnv)
splitFVs Bool
is_thunk DmdEnv
rhs_fvs
| Bool
is_thunk = StrictPair DmdEnv DmdEnv -> (DmdEnv, DmdEnv)
forall a b. StrictPair a b -> (a, b)
strictPairToTuple (StrictPair DmdEnv DmdEnv -> (DmdEnv, DmdEnv))
-> StrictPair DmdEnv DmdEnv -> (DmdEnv, DmdEnv)
forall a b. (a -> b) -> a -> b
$
(Unique
-> Demand -> StrictPair DmdEnv DmdEnv -> StrictPair DmdEnv DmdEnv)
-> StrictPair DmdEnv DmdEnv -> DmdEnv -> StrictPair DmdEnv DmdEnv
forall elt a key.
(Unique -> elt -> a -> a) -> a -> UniqFM key elt -> a
nonDetStrictFoldUFM_Directly Unique
-> Demand -> StrictPair DmdEnv DmdEnv -> StrictPair DmdEnv DmdEnv
forall {s} {u} {key} {key} {u}.
Unique
-> JointDmd (Str s) u
-> StrictPair
(UniqFM key (JointDmd (Str s) u))
(UniqFM key (JointDmd (Str s) (Use u)))
-> StrictPair
(UniqFM key (JointDmd (Str s) u))
(UniqFM key (JointDmd (Str s) (Use u)))
add (DmdEnv
forall a. VarEnv a
emptyVarEnv DmdEnv -> DmdEnv -> StrictPair DmdEnv DmdEnv
forall a b. a -> b -> StrictPair a b
:*: DmdEnv
forall a. VarEnv a
emptyVarEnv) DmdEnv
rhs_fvs
| Bool
otherwise = (Demand -> Bool) -> DmdEnv -> (DmdEnv, DmdEnv)
forall a. (a -> Bool) -> VarEnv a -> (VarEnv a, VarEnv a)
partitionVarEnv Demand -> Bool
isWeakDmd DmdEnv
rhs_fvs
where
add :: Unique
-> JointDmd (Str s) u
-> StrictPair
(UniqFM key (JointDmd (Str s) u))
(UniqFM key (JointDmd (Str s) (Use u)))
-> StrictPair
(UniqFM key (JointDmd (Str s) u))
(UniqFM key (JointDmd (Str s) (Use u)))
add Unique
uniq dmd :: JointDmd (Str s) u
dmd@(JD { sd :: forall s u. JointDmd s u -> s
sd = Str s
s, ud :: forall s u. JointDmd s u -> u
ud = u
u }) (UniqFM key (JointDmd (Str s) u)
lazy_fv :*: UniqFM key (JointDmd (Str s) (Use u))
sig_fv)
| Str s
Lazy <- Str s
s = UniqFM key (JointDmd (Str s) u)
-> Unique -> JointDmd (Str s) u -> UniqFM key (JointDmd (Str s) u)
forall key elt. UniqFM key elt -> Unique -> elt -> UniqFM key elt
addToUFM_Directly UniqFM key (JointDmd (Str s) u)
lazy_fv Unique
uniq JointDmd (Str s) u
dmd UniqFM key (JointDmd (Str s) u)
-> UniqFM key (JointDmd (Str s) (Use u))
-> StrictPair
(UniqFM key (JointDmd (Str s) u))
(UniqFM key (JointDmd (Str s) (Use u)))
forall a b. a -> b -> StrictPair a b
:*: UniqFM key (JointDmd (Str s) (Use u))
sig_fv
| Bool
otherwise = UniqFM key (JointDmd (Str s) u)
-> Unique -> JointDmd (Str s) u -> UniqFM key (JointDmd (Str s) u)
forall key elt. UniqFM key elt -> Unique -> elt -> UniqFM key elt
addToUFM_Directly UniqFM key (JointDmd (Str s) u)
lazy_fv Unique
uniq (JD :: forall s u. s -> u -> JointDmd s u
JD { sd :: Str s
sd = Str s
forall s. Str s
Lazy, ud :: u
ud = u
u })
UniqFM key (JointDmd (Str s) u)
-> UniqFM key (JointDmd (Str s) (Use u))
-> StrictPair
(UniqFM key (JointDmd (Str s) u))
(UniqFM key (JointDmd (Str s) (Use u)))
forall a b. a -> b -> StrictPair a b
:*:
UniqFM key (JointDmd (Str s) (Use u))
-> Unique
-> JointDmd (Str s) (Use u)
-> UniqFM key (JointDmd (Str s) (Use u))
forall key elt. UniqFM key elt -> Unique -> elt -> UniqFM key elt
addToUFM_Directly UniqFM key (JointDmd (Str s) (Use u))
sig_fv Unique
uniq (JD :: forall s u. s -> u -> JointDmd s u
JD { sd :: Str s
sd = Str s
s, ud :: Use u
ud = Use u
forall u. Use u
Abs })
keepAliveDmdEnv :: DmdEnv -> IdSet -> DmdEnv
keepAliveDmdEnv :: DmdEnv -> IdSet -> DmdEnv
keepAliveDmdEnv DmdEnv
env IdSet
vs
= (Var -> DmdEnv -> DmdEnv) -> DmdEnv -> IdSet -> DmdEnv
forall a. (Var -> a -> a) -> a -> IdSet -> a
nonDetStrictFoldVarSet Var -> DmdEnv -> DmdEnv
add DmdEnv
env IdSet
vs
where
add :: Id -> DmdEnv -> DmdEnv
add :: Var -> DmdEnv -> DmdEnv
add Var
v DmdEnv
env = (Demand -> Demand -> Demand) -> DmdEnv -> Var -> Demand -> DmdEnv
forall a. (a -> a -> a) -> VarEnv a -> Var -> a -> VarEnv a
extendVarEnv_C Demand -> Demand -> Demand
add_dmd DmdEnv
env Var
v Demand
topDmd
add_dmd :: Demand -> Demand -> Demand
add_dmd :: Demand -> Demand -> Demand
add_dmd Demand
dmd Demand
_ | Demand -> Bool
forall s u. JointDmd (Str s) (Use u) -> Bool
isAbsDmd Demand
dmd = Demand
topDmd
| Bool
otherwise = Demand
dmd
splitProdDmd_maybe :: Demand -> Maybe [Demand]
splitProdDmd_maybe :: Demand -> Maybe [Demand]
splitProdDmd_maybe (JD { sd :: forall s u. JointDmd s u -> s
sd = ArgStr
s, ud :: forall s u. JointDmd s u -> u
ud = ArgUse
u })
= case (ArgStr
s,ArgUse
u) of
(Str (SProd [ArgStr]
sx), Use Count
_ UseDmd
u) | Just [ArgUse]
ux <- Int -> UseDmd -> Maybe [ArgUse]
splitUseProdDmd ([ArgStr] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [ArgStr]
sx) UseDmd
u
-> [Demand] -> Maybe [Demand]
forall a. a -> Maybe a
Just ([ArgStr] -> [ArgUse] -> [Demand]
forall s u. [s] -> [u] -> [JointDmd s u]
mkJointDmds [ArgStr]
sx [ArgUse]
ux)
(Str StrDmd
s, Use Count
_ (UProd [ArgUse]
ux)) | Just [ArgStr]
sx <- Int -> StrDmd -> Maybe [ArgStr]
splitStrProdDmd ([ArgUse] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [ArgUse]
ux) StrDmd
s
-> [Demand] -> Maybe [Demand]
forall a. a -> Maybe a
Just ([ArgStr] -> [ArgUse] -> [Demand]
forall s u. [s] -> [u] -> [JointDmd s u]
mkJointDmds [ArgStr]
sx [ArgUse]
ux)
(ArgStr
Lazy, Use Count
_ (UProd [ArgUse]
ux)) -> [Demand] -> Maybe [Demand]
forall a. a -> Maybe a
Just ([ArgStr] -> [ArgUse] -> [Demand]
forall s u. [s] -> [u] -> [JointDmd s u]
mkJointDmds (Int -> ArgStr -> [ArgStr]
forall a. Int -> a -> [a]
replicate ([ArgUse] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [ArgUse]
ux) ArgStr
forall s. Str s
Lazy) [ArgUse]
ux)
(ArgStr, ArgUse)
_ -> Maybe [Demand]
forall a. Maybe a
Nothing
data StrictPair a b = !a :*: !b
strictPairToTuple :: StrictPair a b -> (a, b)
strictPairToTuple :: forall a b. StrictPair a b -> (a, b)
strictPairToTuple (a
x :*: b
y) = (a
x, b
y)
data TypeShape
= TsFun TypeShape
| TsProd [TypeShape]
| TsUnk
trimToType :: Demand -> TypeShape -> Demand
trimToType :: Demand -> TypeShape -> Demand
trimToType (JD { sd :: forall s u. JointDmd s u -> s
sd = ArgStr
ms, ud :: forall s u. JointDmd s u -> u
ud = ArgUse
mu }) TypeShape
ts
= ArgStr -> ArgUse -> Demand
forall s u. s -> u -> JointDmd s u
JD (ArgStr -> TypeShape -> ArgStr
go_ms ArgStr
ms TypeShape
ts) (ArgUse -> TypeShape -> ArgUse
go_mu ArgUse
mu TypeShape
ts)
where
go_ms :: ArgStr -> TypeShape -> ArgStr
go_ms :: ArgStr -> TypeShape -> ArgStr
go_ms ArgStr
Lazy TypeShape
_ = ArgStr
forall s. Str s
Lazy
go_ms (Str StrDmd
s) TypeShape
ts = StrDmd -> ArgStr
forall s. s -> Str s
Str (StrDmd -> TypeShape -> StrDmd
go_s StrDmd
s TypeShape
ts)
go_s :: StrDmd -> TypeShape -> StrDmd
go_s :: StrDmd -> TypeShape -> StrDmd
go_s StrDmd
HyperStr TypeShape
_ = StrDmd
HyperStr
go_s (SCall StrDmd
s) (TsFun TypeShape
ts) = StrDmd -> StrDmd
SCall (StrDmd -> TypeShape -> StrDmd
go_s StrDmd
s TypeShape
ts)
go_s (SProd [ArgStr]
mss) (TsProd [TypeShape]
tss)
| [ArgStr] -> [TypeShape] -> Bool
forall a b. [a] -> [b] -> Bool
equalLength [ArgStr]
mss [TypeShape]
tss = [ArgStr] -> StrDmd
SProd ((ArgStr -> TypeShape -> ArgStr)
-> [ArgStr] -> [TypeShape] -> [ArgStr]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith ArgStr -> TypeShape -> ArgStr
go_ms [ArgStr]
mss [TypeShape]
tss)
go_s StrDmd
_ TypeShape
_ = StrDmd
HeadStr
go_mu :: ArgUse -> TypeShape -> ArgUse
go_mu :: ArgUse -> TypeShape -> ArgUse
go_mu ArgUse
Abs TypeShape
_ = ArgUse
forall u. Use u
Abs
go_mu (Use Count
c UseDmd
u) TypeShape
ts = Count -> UseDmd -> ArgUse
forall u. Count -> u -> Use u
Use Count
c (UseDmd -> TypeShape -> UseDmd
go_u UseDmd
u TypeShape
ts)
go_u :: UseDmd -> TypeShape -> UseDmd
go_u :: UseDmd -> TypeShape -> UseDmd
go_u UseDmd
UHead TypeShape
_ = UseDmd
UHead
go_u (UCall Count
c UseDmd
u) (TsFun TypeShape
ts) = Count -> UseDmd -> UseDmd
UCall Count
c (UseDmd -> TypeShape -> UseDmd
go_u UseDmd
u TypeShape
ts)
go_u (UProd [ArgUse]
mus) (TsProd [TypeShape]
tss)
| [ArgUse] -> [TypeShape] -> Bool
forall a b. [a] -> [b] -> Bool
equalLength [ArgUse]
mus [TypeShape]
tss = [ArgUse] -> UseDmd
UProd ((ArgUse -> TypeShape -> ArgUse)
-> [ArgUse] -> [TypeShape] -> [ArgUse]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith ArgUse -> TypeShape -> ArgUse
go_mu [ArgUse]
mus [TypeShape]
tss)
go_u UseDmd
_ TypeShape
_ = UseDmd
Used
instance Outputable TypeShape where
ppr :: TypeShape -> SDoc
ppr TypeShape
TsUnk = String -> SDoc
text String
"TsUnk"
ppr (TsFun TypeShape
ts) = String -> SDoc
text String
"TsFun" SDoc -> SDoc -> SDoc
<> SDoc -> SDoc
parens (TypeShape -> SDoc
forall a. Outputable a => a -> SDoc
ppr TypeShape
ts)
ppr (TsProd [TypeShape]
tss) = SDoc -> SDoc
parens ([SDoc] -> SDoc
hsep ([SDoc] -> SDoc) -> [SDoc] -> SDoc
forall a b. (a -> b) -> a -> b
$ SDoc -> [SDoc] -> [SDoc]
punctuate SDoc
comma ([SDoc] -> [SDoc]) -> [SDoc] -> [SDoc]
forall a b. (a -> b) -> a -> b
$ (TypeShape -> SDoc) -> [TypeShape] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map TypeShape -> SDoc
forall a. Outputable a => a -> SDoc
ppr [TypeShape]
tss)
data Divergence
= Diverges
| ExnOrDiv
| Dunno
deriving( Divergence -> Divergence -> Bool
(Divergence -> Divergence -> Bool)
-> (Divergence -> Divergence -> Bool) -> Eq Divergence
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Divergence -> Divergence -> Bool
$c/= :: Divergence -> Divergence -> Bool
== :: Divergence -> Divergence -> Bool
$c== :: Divergence -> Divergence -> Bool
Eq, Int -> Divergence -> ShowS
[Divergence] -> ShowS
Divergence -> String
(Int -> Divergence -> ShowS)
-> (Divergence -> String)
-> ([Divergence] -> ShowS)
-> Show Divergence
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Divergence] -> ShowS
$cshowList :: [Divergence] -> ShowS
show :: Divergence -> String
$cshow :: Divergence -> String
showsPrec :: Int -> Divergence -> ShowS
$cshowsPrec :: Int -> Divergence -> ShowS
Show )
lubDivergence :: Divergence -> Divergence -> Divergence
lubDivergence :: Divergence -> Divergence -> Divergence
lubDivergence Divergence
Diverges Divergence
div = Divergence
div
lubDivergence Divergence
div Divergence
Diverges = Divergence
div
lubDivergence Divergence
ExnOrDiv Divergence
ExnOrDiv = Divergence
ExnOrDiv
lubDivergence Divergence
_ Divergence
_ = Divergence
Dunno
bothDivergence :: Divergence -> Divergence -> Divergence
bothDivergence :: Divergence -> Divergence -> Divergence
bothDivergence Divergence
Dunno Divergence
Dunno = Divergence
Dunno
bothDivergence Divergence
Diverges Divergence
_ = Divergence
Diverges
bothDivergence Divergence
_ Divergence
Diverges = Divergence
Diverges
bothDivergence Divergence
_ Divergence
_ = Divergence
ExnOrDiv
instance Outputable Divergence where
ppr :: Divergence -> SDoc
ppr Divergence
Diverges = Char -> SDoc
char Char
'b'
ppr Divergence
ExnOrDiv = Char -> SDoc
char Char
'x'
ppr Divergence
Dunno = SDoc
empty
topDiv, exnDiv, botDiv :: Divergence
topDiv :: Divergence
topDiv = Divergence
Dunno
exnDiv :: Divergence
exnDiv = Divergence
ExnOrDiv
botDiv :: Divergence
botDiv = Divergence
Diverges
isDeadEndDiv :: Divergence -> Bool
isDeadEndDiv :: Divergence -> Bool
isDeadEndDiv Divergence
Diverges = Bool
True
isDeadEndDiv Divergence
ExnOrDiv = Bool
True
isDeadEndDiv Divergence
Dunno = Bool
False
defaultFvDmd :: Divergence -> Demand
defaultFvDmd :: Divergence -> Demand
defaultFvDmd Divergence
Dunno = Demand
absDmd
defaultFvDmd Divergence
ExnOrDiv = Demand
absDmd
defaultFvDmd Divergence
Diverges = Demand
botDmd
defaultArgDmd :: Divergence -> Demand
defaultArgDmd :: Divergence -> Demand
defaultArgDmd Divergence
Dunno = Demand
topDmd
defaultArgDmd Divergence
ExnOrDiv = Demand
absDmd
defaultArgDmd Divergence
Diverges = Demand
botDmd
type DmdEnv = VarEnv Demand
data DmdType = DmdType
DmdEnv
[Demand]
Divergence
instance Eq DmdType where
== :: DmdType -> DmdType -> Bool
(==) (DmdType DmdEnv
fv1 [Demand]
ds1 Divergence
div1)
(DmdType DmdEnv
fv2 [Demand]
ds2 Divergence
div2) = DmdEnv -> [(Unique, Demand)]
forall key elt. UniqFM key elt -> [(Unique, elt)]
nonDetUFMToList DmdEnv
fv1 [(Unique, Demand)] -> [(Unique, Demand)] -> Bool
forall a. Eq a => a -> a -> Bool
== DmdEnv -> [(Unique, Demand)]
forall key elt. UniqFM key elt -> [(Unique, elt)]
nonDetUFMToList DmdEnv
fv2
Bool -> Bool -> Bool
&& [Demand]
ds1 [Demand] -> [Demand] -> Bool
forall a. Eq a => a -> a -> Bool
== [Demand]
ds2 Bool -> Bool -> Bool
&& Divergence
div1 Divergence -> Divergence -> Bool
forall a. Eq a => a -> a -> Bool
== Divergence
div2
lubDmdType :: DmdType -> DmdType -> DmdType
lubDmdType :: DmdType -> DmdType -> DmdType
lubDmdType DmdType
d1 DmdType
d2
= DmdEnv -> [Demand] -> Divergence -> DmdType
DmdType DmdEnv
lub_fv [Demand]
lub_ds Divergence
lub_div
where
n :: Int
n = Int -> Int -> Int
forall a. Ord a => a -> a -> a
max (DmdType -> Int
dmdTypeDepth DmdType
d1) (DmdType -> Int
dmdTypeDepth DmdType
d2)
(DmdType DmdEnv
fv1 [Demand]
ds1 Divergence
r1) = Int -> DmdType -> DmdType
etaExpandDmdType Int
n DmdType
d1
(DmdType DmdEnv
fv2 [Demand]
ds2 Divergence
r2) = Int -> DmdType -> DmdType
etaExpandDmdType Int
n DmdType
d2
lub_fv :: DmdEnv
lub_fv = (Demand -> Demand -> Demand)
-> DmdEnv -> Demand -> DmdEnv -> Demand -> DmdEnv
forall a.
(a -> a -> a) -> VarEnv a -> a -> VarEnv a -> a -> VarEnv a
plusVarEnv_CD Demand -> Demand -> Demand
lubDmd DmdEnv
fv1 (Divergence -> Demand
defaultFvDmd Divergence
r1) DmdEnv
fv2 (Divergence -> Demand
defaultFvDmd Divergence
r2)
lub_ds :: [Demand]
lub_ds = String
-> (Demand -> Demand -> Demand) -> [Demand] -> [Demand] -> [Demand]
forall a b c. String -> (a -> b -> c) -> [a] -> [b] -> [c]
zipWithEqual String
"lubDmdType" Demand -> Demand -> Demand
lubDmd [Demand]
ds1 [Demand]
ds2
lub_div :: Divergence
lub_div = Divergence -> Divergence -> Divergence
lubDivergence Divergence
r1 Divergence
r2
type BothDmdArg = (DmdEnv, Divergence)
mkBothDmdArg :: DmdEnv -> BothDmdArg
mkBothDmdArg :: DmdEnv -> BothDmdArg
mkBothDmdArg DmdEnv
env = (DmdEnv
env, Divergence
topDiv)
toBothDmdArg :: DmdType -> BothDmdArg
toBothDmdArg :: DmdType -> BothDmdArg
toBothDmdArg (DmdType DmdEnv
fv [Demand]
_ Divergence
r) = (DmdEnv
fv, Divergence
r)
bothDmdType :: DmdType -> BothDmdArg -> DmdType
bothDmdType :: DmdType -> BothDmdArg -> DmdType
bothDmdType (DmdType DmdEnv
fv1 [Demand]
ds1 Divergence
r1) (DmdEnv
fv2, Divergence
t2)
= DmdEnv -> [Demand] -> Divergence -> DmdType
DmdType ((Demand -> Demand -> Demand)
-> DmdEnv -> Demand -> DmdEnv -> Demand -> DmdEnv
forall a.
(a -> a -> a) -> VarEnv a -> a -> VarEnv a -> a -> VarEnv a
plusVarEnv_CD Demand -> Demand -> Demand
bothDmd DmdEnv
fv1 (Divergence -> Demand
defaultFvDmd Divergence
r1) DmdEnv
fv2 (Divergence -> Demand
defaultFvDmd Divergence
t2))
[Demand]
ds1
(Divergence
r1 Divergence -> Divergence -> Divergence
`bothDivergence` Divergence
t2)
instance Outputable DmdType where
ppr :: DmdType -> SDoc
ppr (DmdType DmdEnv
fv [Demand]
ds Divergence
res)
= [SDoc] -> SDoc
hsep [[SDoc] -> SDoc
hcat ((Demand -> SDoc) -> [Demand] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map Demand -> SDoc
forall a. Outputable a => a -> SDoc
ppr [Demand]
ds) SDoc -> SDoc -> SDoc
<> Divergence -> SDoc
forall a. Outputable a => a -> SDoc
ppr Divergence
res,
if [(Unique, Demand)] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [(Unique, Demand)]
fv_elts then SDoc
empty
else SDoc -> SDoc
braces ([SDoc] -> SDoc
fsep (((Unique, Demand) -> SDoc) -> [(Unique, Demand)] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map (Unique, Demand) -> SDoc
forall {a} {a}. (Outputable a, Outputable a) => (a, a) -> SDoc
pp_elt [(Unique, Demand)]
fv_elts))]
where
pp_elt :: (a, a) -> SDoc
pp_elt (a
uniq, a
dmd) = a -> SDoc
forall a. Outputable a => a -> SDoc
ppr a
uniq SDoc -> SDoc -> SDoc
<> String -> SDoc
text String
"->" SDoc -> SDoc -> SDoc
<> a -> SDoc
forall a. Outputable a => a -> SDoc
ppr a
dmd
fv_elts :: [(Unique, Demand)]
fv_elts = DmdEnv -> [(Unique, Demand)]
forall key elt. UniqFM key elt -> [(Unique, elt)]
nonDetUFMToList DmdEnv
fv
emptyDmdEnv :: VarEnv Demand
emptyDmdEnv :: DmdEnv
emptyDmdEnv = DmdEnv
forall a. VarEnv a
emptyVarEnv
botDmdType :: DmdType
botDmdType :: DmdType
botDmdType = DmdEnv -> [Demand] -> Divergence -> DmdType
DmdType DmdEnv
emptyDmdEnv [] Divergence
botDiv
nopDmdType :: DmdType
nopDmdType :: DmdType
nopDmdType = DmdEnv -> [Demand] -> Divergence -> DmdType
DmdType DmdEnv
emptyDmdEnv [] Divergence
topDiv
isTopDmdType :: DmdType -> Bool
isTopDmdType :: DmdType -> Bool
isTopDmdType (DmdType DmdEnv
env [Demand]
args Divergence
div)
= Divergence
div Divergence -> Divergence -> Bool
forall a. Eq a => a -> a -> Bool
== Divergence
topDiv Bool -> Bool -> Bool
&& [Demand] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Demand]
args Bool -> Bool -> Bool
&& DmdEnv -> Bool
forall a. VarEnv a -> Bool
isEmptyVarEnv DmdEnv
env
exnDmdType :: DmdType
exnDmdType :: DmdType
exnDmdType = DmdEnv -> [Demand] -> Divergence -> DmdType
DmdType DmdEnv
emptyDmdEnv [] Divergence
exnDiv
dmdTypeDepth :: DmdType -> Arity
dmdTypeDepth :: DmdType -> Int
dmdTypeDepth (DmdType DmdEnv
_ [Demand]
ds Divergence
_) = [Demand] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Demand]
ds
etaExpandDmdType :: Arity -> DmdType -> DmdType
etaExpandDmdType :: Int -> DmdType -> DmdType
etaExpandDmdType Int
n DmdType
d
| Int
n Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
depth = DmdType
d
| Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
depth = DmdEnv -> [Demand] -> Divergence -> DmdType
DmdType DmdEnv
fv [Demand]
inc_ds Divergence
div
| Bool
otherwise = String -> SDoc -> DmdType
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"etaExpandDmdType: arity decrease" (Int -> SDoc
forall a. Outputable a => a -> SDoc
ppr Int
n SDoc -> SDoc -> SDoc
$$ DmdType -> SDoc
forall a. Outputable a => a -> SDoc
ppr DmdType
d)
where depth :: Int
depth = DmdType -> Int
dmdTypeDepth DmdType
d
DmdType DmdEnv
fv [Demand]
ds Divergence
div = DmdType
d
inc_ds :: [Demand]
inc_ds = Int -> [Demand] -> [Demand]
forall a. Int -> [a] -> [a]
take Int
n ([Demand]
ds [Demand] -> [Demand] -> [Demand]
forall a. [a] -> [a] -> [a]
++ Demand -> [Demand]
forall a. a -> [a]
repeat (Divergence -> Demand
defaultArgDmd Divergence
div))
decreaseArityDmdType :: DmdType -> DmdType
decreaseArityDmdType :: DmdType -> DmdType
decreaseArityDmdType DmdType
_ = DmdType
nopDmdType
seqDmdType :: DmdType -> ()
seqDmdType :: DmdType -> ()
seqDmdType (DmdType DmdEnv
env [Demand]
ds Divergence
res) =
DmdEnv -> ()
seqDmdEnv DmdEnv
env () -> () -> ()
`seq` [Demand] -> ()
seqDemandList [Demand]
ds () -> () -> ()
`seq` Divergence
res Divergence -> () -> ()
`seq` ()
seqDmdEnv :: DmdEnv -> ()
seqDmdEnv :: DmdEnv -> ()
seqDmdEnv DmdEnv
env = ([Demand] -> ()) -> DmdEnv -> ()
forall elt key. ([elt] -> ()) -> UniqFM key elt -> ()
seqEltsUFM [Demand] -> ()
seqDemandList DmdEnv
env
splitDmdTy :: DmdType -> (Demand, DmdType)
splitDmdTy :: DmdType -> (Demand, DmdType)
splitDmdTy (DmdType DmdEnv
fv (Demand
dmd:[Demand]
dmds) Divergence
res_ty) = (Demand
dmd, DmdEnv -> [Demand] -> Divergence -> DmdType
DmdType DmdEnv
fv [Demand]
dmds Divergence
res_ty)
splitDmdTy ty :: DmdType
ty@(DmdType DmdEnv
_ [] Divergence
res_ty) = (Divergence -> Demand
defaultArgDmd Divergence
res_ty, DmdType
ty)
deferAfterPreciseException :: DmdType -> DmdType
deferAfterPreciseException :: DmdType -> DmdType
deferAfterPreciseException = DmdType -> DmdType -> DmdType
lubDmdType DmdType
exnDmdType
strictenDmd :: Demand -> Demand
strictenDmd :: Demand -> Demand
strictenDmd (JD { sd :: forall s u. JointDmd s u -> s
sd = ArgStr
s, ud :: forall s u. JointDmd s u -> u
ud = ArgUse
u})
= JD :: forall s u. s -> u -> JointDmd s u
JD { sd :: ArgStr
sd = ArgStr -> ArgStr
poke_s ArgStr
s, ud :: ArgUse
ud = ArgUse -> ArgUse
poke_u ArgUse
u }
where
poke_s :: ArgStr -> ArgStr
poke_s ArgStr
Lazy = StrDmd -> ArgStr
forall s. s -> Str s
Str StrDmd
HeadStr
poke_s ArgStr
s = ArgStr
s
poke_u :: ArgUse -> ArgUse
poke_u ArgUse
Abs = ArgUse
useTop
poke_u ArgUse
u = ArgUse
u
type DmdShell
= JointDmd (Str ()) (Use ())
toCleanDmd :: Demand -> (DmdShell, CleanDemand)
toCleanDmd :: Demand -> (DmdShell, CleanDemand)
toCleanDmd (JD { sd :: forall s u. JointDmd s u -> s
sd = ArgStr
s, ud :: forall s u. JointDmd s u -> u
ud = ArgUse
u })
= (JD :: forall s u. s -> u -> JointDmd s u
JD { sd :: Str ()
sd = Str ()
ss, ud :: Use ()
ud = Use ()
us }, JD :: forall s u. s -> u -> JointDmd s u
JD { sd :: StrDmd
sd = StrDmd
s', ud :: UseDmd
ud = UseDmd
u' })
where
(Str ()
ss, StrDmd
s') = case ArgStr
s of
Str StrDmd
s' -> (() -> Str ()
forall s. s -> Str s
Str (), StrDmd
s')
ArgStr
Lazy -> (Str ()
forall s. Str s
Lazy, StrDmd
HeadStr)
(Use ()
us, UseDmd
u') = case ArgUse
u of
Use Count
c UseDmd
u' -> (Count -> () -> Use ()
forall u. Count -> u -> Use u
Use Count
c (), UseDmd
u')
ArgUse
Abs -> (Use ()
forall u. Use u
Abs, UseDmd
Used)
postProcessDmdType :: DmdShell -> DmdType -> BothDmdArg
postProcessDmdType :: DmdShell -> DmdType -> BothDmdArg
postProcessDmdType du :: DmdShell
du@(JD { sd :: forall s u. JointDmd s u -> s
sd = Str ()
ss }) (DmdType DmdEnv
fv [Demand]
_ Divergence
res_ty)
= (DmdShell -> DmdEnv -> DmdEnv
postProcessDmdEnv DmdShell
du DmdEnv
fv, Str () -> Divergence -> Divergence
postProcessDivergence Str ()
ss Divergence
res_ty)
postProcessDivergence :: Str () -> Divergence -> Divergence
postProcessDivergence :: Str () -> Divergence -> Divergence
postProcessDivergence Str ()
Lazy Divergence
_ = Divergence
Dunno
postProcessDivergence Str ()
_ Divergence
d = Divergence
d
postProcessDmdEnv :: DmdShell -> DmdEnv -> DmdEnv
postProcessDmdEnv :: DmdShell -> DmdEnv -> DmdEnv
postProcessDmdEnv ds :: DmdShell
ds@(JD { sd :: forall s u. JointDmd s u -> s
sd = Str ()
ss, ud :: forall s u. JointDmd s u -> u
ud = Use ()
us }) DmdEnv
env
| Use ()
Abs <- Use ()
us = DmdEnv
emptyDmdEnv
| Str ()
_ <- Str ()
ss
, Use Count
One ()
_ <- Use ()
us = DmdEnv
env
| Bool
otherwise = (Demand -> Demand) -> DmdEnv -> DmdEnv
forall a b. (a -> b) -> VarEnv a -> VarEnv b
mapVarEnv (DmdShell -> Demand -> Demand
postProcessDmd DmdShell
ds) DmdEnv
env
reuseEnv :: DmdEnv -> DmdEnv
reuseEnv :: DmdEnv -> DmdEnv
reuseEnv = (Demand -> Demand) -> DmdEnv -> DmdEnv
forall a b. (a -> b) -> VarEnv a -> VarEnv b
mapVarEnv (DmdShell -> Demand -> Demand
postProcessDmd
(JD :: forall s u. s -> u -> JointDmd s u
JD { sd :: Str ()
sd = () -> Str ()
forall s. s -> Str s
Str (), ud :: Use ()
ud = Count -> () -> Use ()
forall u. Count -> u -> Use u
Use Count
Many () }))
postProcessUnsat :: DmdShell -> DmdType -> DmdType
postProcessUnsat :: DmdShell -> DmdType -> DmdType
postProcessUnsat ds :: DmdShell
ds@(JD { sd :: forall s u. JointDmd s u -> s
sd = Str ()
ss }) (DmdType DmdEnv
fv [Demand]
args Divergence
res_ty)
= DmdEnv -> [Demand] -> Divergence -> DmdType
DmdType (DmdShell -> DmdEnv -> DmdEnv
postProcessDmdEnv DmdShell
ds DmdEnv
fv)
((Demand -> Demand) -> [Demand] -> [Demand]
forall a b. (a -> b) -> [a] -> [b]
map (DmdShell -> Demand -> Demand
postProcessDmd DmdShell
ds) [Demand]
args)
(Str () -> Divergence -> Divergence
postProcessDivergence Str ()
ss Divergence
res_ty)
postProcessDmd :: DmdShell -> Demand -> Demand
postProcessDmd :: DmdShell -> Demand -> Demand
postProcessDmd (JD { sd :: forall s u. JointDmd s u -> s
sd = Str ()
ss, ud :: forall s u. JointDmd s u -> u
ud = Use ()
us }) (JD { sd :: forall s u. JointDmd s u -> s
sd = ArgStr
s, ud :: forall s u. JointDmd s u -> u
ud = ArgUse
a})
= JD :: forall s u. s -> u -> JointDmd s u
JD { sd :: ArgStr
sd = ArgStr
s', ud :: ArgUse
ud = ArgUse
a' }
where
s' :: ArgStr
s' = case Str ()
ss of
Str ()
Lazy -> ArgStr
forall s. Str s
Lazy
Str ()
_ -> ArgStr
s
a' :: ArgUse
a' = case Use ()
us of
Use ()
Abs -> ArgUse
forall u. Use u
Abs
Use Count
Many ()
_ -> ArgUse -> ArgUse
markReusedDmd ArgUse
a
Use Count
One ()
_ -> ArgUse
a
peelCallDmd :: CleanDemand -> (CleanDemand, DmdShell)
peelCallDmd :: CleanDemand -> (CleanDemand, DmdShell)
peelCallDmd (JD {sd :: forall s u. JointDmd s u -> s
sd = StrDmd
s, ud :: forall s u. JointDmd s u -> u
ud = UseDmd
u})
= (JD :: forall s u. s -> u -> JointDmd s u
JD { sd :: StrDmd
sd = StrDmd
s', ud :: UseDmd
ud = UseDmd
u' }, JD :: forall s u. s -> u -> JointDmd s u
JD { sd :: Str ()
sd = Str ()
ss, ud :: Use ()
ud = Use ()
us })
where
(StrDmd
s', Str ()
ss) = case StrDmd
s of
SCall StrDmd
s' -> (StrDmd
s', () -> Str ()
forall s. s -> Str s
Str ())
StrDmd
HyperStr -> (StrDmd
HyperStr, () -> Str ()
forall s. s -> Str s
Str ())
StrDmd
_ -> (StrDmd
HeadStr, Str ()
forall s. Str s
Lazy)
(UseDmd
u', Use ()
us) = case UseDmd
u of
UCall Count
c UseDmd
u' -> (UseDmd
u', Count -> () -> Use ()
forall u. Count -> u -> Use u
Use Count
c ())
UseDmd
_ -> (UseDmd
Used, Count -> () -> Use ()
forall u. Count -> u -> Use u
Use Count
Many ())
peelManyCalls :: Int -> CleanDemand -> DmdShell
peelManyCalls :: Int -> CleanDemand -> DmdShell
peelManyCalls Int
n (JD { sd :: forall s u. JointDmd s u -> s
sd = StrDmd
str, ud :: forall s u. JointDmd s u -> u
ud = UseDmd
abs })
= JD :: forall s u. s -> u -> JointDmd s u
JD { sd :: Str ()
sd = Int -> StrDmd -> Str ()
go_str Int
n StrDmd
str, ud :: Use ()
ud = Int -> UseDmd -> Use ()
go_abs Int
n UseDmd
abs }
where
go_str :: Int -> StrDmd -> Str ()
go_str :: Int -> StrDmd -> Str ()
go_str Int
0 StrDmd
_ = () -> Str ()
forall s. s -> Str s
Str ()
go_str Int
_ StrDmd
HyperStr = () -> Str ()
forall s. s -> Str s
Str ()
go_str Int
n (SCall StrDmd
d') = Int -> StrDmd -> Str ()
go_str (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) StrDmd
d'
go_str Int
_ StrDmd
_ = Str ()
forall s. Str s
Lazy
go_abs :: Int -> UseDmd -> Use ()
go_abs :: Int -> UseDmd -> Use ()
go_abs Int
0 UseDmd
_ = Count -> () -> Use ()
forall u. Count -> u -> Use u
Use Count
One ()
go_abs Int
n (UCall Count
One UseDmd
d') = Int -> UseDmd -> Use ()
go_abs (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) UseDmd
d'
go_abs Int
_ UseDmd
_ = Count -> () -> Use ()
forall u. Count -> u -> Use u
Use Count
Many ()
peelFV :: DmdType -> Var -> (DmdType, Demand)
peelFV :: DmdType -> Var -> (DmdType, Demand)
peelFV (DmdType DmdEnv
fv [Demand]
ds Divergence
res) Var
id =
(DmdEnv -> [Demand] -> Divergence -> DmdType
DmdType DmdEnv
fv' [Demand]
ds Divergence
res, Demand
dmd)
where
fv' :: DmdEnv
fv' = DmdEnv
fv DmdEnv -> Var -> DmdEnv
forall a. VarEnv a -> Var -> VarEnv a
`delVarEnv` Var
id
dmd :: Demand
dmd = DmdEnv -> Var -> Maybe Demand
forall a. VarEnv a -> Var -> Maybe a
lookupVarEnv DmdEnv
fv Var
id Maybe Demand -> Demand -> Demand
forall a. Maybe a -> a -> a
`orElse` Divergence -> Demand
defaultFvDmd Divergence
res
addDemand :: Demand -> DmdType -> DmdType
addDemand :: Demand -> DmdType -> DmdType
addDemand Demand
dmd (DmdType DmdEnv
fv [Demand]
ds Divergence
res) = DmdEnv -> [Demand] -> Divergence -> DmdType
DmdType DmdEnv
fv (Demand
dmdDemand -> [Demand] -> [Demand]
forall a. a -> [a] -> [a]
:[Demand]
ds) Divergence
res
findIdDemand :: DmdType -> Var -> Demand
findIdDemand :: DmdType -> Var -> Demand
findIdDemand (DmdType DmdEnv
fv [Demand]
_ Divergence
res) Var
id
= DmdEnv -> Var -> Maybe Demand
forall a. VarEnv a -> Var -> Maybe a
lookupVarEnv DmdEnv
fv Var
id Maybe Demand -> Demand -> Demand
forall a. Maybe a -> a -> a
`orElse` Divergence -> Demand
defaultFvDmd Divergence
res
newtype StrictSig = StrictSig DmdType
deriving( StrictSig -> StrictSig -> Bool
(StrictSig -> StrictSig -> Bool)
-> (StrictSig -> StrictSig -> Bool) -> Eq StrictSig
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: StrictSig -> StrictSig -> Bool
$c/= :: StrictSig -> StrictSig -> Bool
== :: StrictSig -> StrictSig -> Bool
$c== :: StrictSig -> StrictSig -> Bool
Eq )
instance Outputable StrictSig where
ppr :: StrictSig -> SDoc
ppr (StrictSig DmdType
ty) = DmdType -> SDoc
forall a. Outputable a => a -> SDoc
ppr DmdType
ty
pprIfaceStrictSig :: StrictSig -> SDoc
pprIfaceStrictSig :: StrictSig -> SDoc
pprIfaceStrictSig (StrictSig (DmdType DmdEnv
_ [Demand]
dmds Divergence
res))
= [SDoc] -> SDoc
hcat ((Demand -> SDoc) -> [Demand] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map Demand -> SDoc
forall a. Outputable a => a -> SDoc
ppr [Demand]
dmds) SDoc -> SDoc -> SDoc
<> Divergence -> SDoc
forall a. Outputable a => a -> SDoc
ppr Divergence
res
mkStrictSigForArity :: Arity -> DmdType -> StrictSig
mkStrictSigForArity :: Int -> DmdType -> StrictSig
mkStrictSigForArity Int
arity dmd_ty :: DmdType
dmd_ty@(DmdType DmdEnv
fvs [Demand]
args Divergence
div)
| Int
arity Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< DmdType -> Int
dmdTypeDepth DmdType
dmd_ty = DmdType -> StrictSig
StrictSig (DmdEnv -> [Demand] -> Divergence -> DmdType
DmdType DmdEnv
fvs (Int -> [Demand] -> [Demand]
forall a. Int -> [a] -> [a]
take Int
arity [Demand]
args) Divergence
div)
| Bool
otherwise = DmdType -> StrictSig
StrictSig (Int -> DmdType -> DmdType
etaExpandDmdType Int
arity DmdType
dmd_ty)
mkClosedStrictSig :: [Demand] -> Divergence -> StrictSig
mkClosedStrictSig :: [Demand] -> Divergence -> StrictSig
mkClosedStrictSig [Demand]
ds Divergence
res = Int -> DmdType -> StrictSig
mkStrictSigForArity ([Demand] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Demand]
ds) (DmdEnv -> [Demand] -> Divergence -> DmdType
DmdType DmdEnv
emptyDmdEnv [Demand]
ds Divergence
res)
splitStrictSig :: StrictSig -> ([Demand], Divergence)
splitStrictSig :: StrictSig -> ([Demand], Divergence)
splitStrictSig (StrictSig (DmdType DmdEnv
_ [Demand]
dmds Divergence
res)) = ([Demand]
dmds, Divergence
res)
prependArgsStrictSig :: Int -> StrictSig -> StrictSig
prependArgsStrictSig :: Int -> StrictSig -> StrictSig
prependArgsStrictSig Int
new_args sig :: StrictSig
sig@(StrictSig dmd_ty :: DmdType
dmd_ty@(DmdType DmdEnv
env [Demand]
dmds Divergence
res))
| Int
new_args Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 = StrictSig
sig
| DmdType -> Bool
isTopDmdType DmdType
dmd_ty = StrictSig
sig
| Int
new_args Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 = String -> SDoc -> StrictSig
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"prependArgsStrictSig: negative new_args"
(Int -> SDoc
forall a. Outputable a => a -> SDoc
ppr Int
new_args SDoc -> SDoc -> SDoc
$$ StrictSig -> SDoc
forall a. Outputable a => a -> SDoc
ppr StrictSig
sig)
| Bool
otherwise = DmdType -> StrictSig
StrictSig (DmdEnv -> [Demand] -> Divergence -> DmdType
DmdType DmdEnv
env [Demand]
dmds' Divergence
res)
where
dmds' :: [Demand]
dmds' = Int -> Demand -> [Demand]
forall a. Int -> a -> [a]
replicate Int
new_args Demand
topDmd [Demand] -> [Demand] -> [Demand]
forall a. [a] -> [a] -> [a]
++ [Demand]
dmds
etaConvertStrictSig :: Arity -> StrictSig -> StrictSig
etaConvertStrictSig :: Int -> StrictSig -> StrictSig
etaConvertStrictSig Int
arity (StrictSig DmdType
dmd_ty)
| Int
arity Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< DmdType -> Int
dmdTypeDepth DmdType
dmd_ty = DmdType -> StrictSig
StrictSig (DmdType -> StrictSig) -> DmdType -> StrictSig
forall a b. (a -> b) -> a -> b
$ DmdType -> DmdType
decreaseArityDmdType DmdType
dmd_ty
| Bool
otherwise = DmdType -> StrictSig
StrictSig (DmdType -> StrictSig) -> DmdType -> StrictSig
forall a b. (a -> b) -> a -> b
$ Int -> DmdType -> DmdType
etaExpandDmdType Int
arity DmdType
dmd_ty
isTopSig :: StrictSig -> Bool
isTopSig :: StrictSig -> Bool
isTopSig (StrictSig DmdType
ty) = DmdType -> Bool
isTopDmdType DmdType
ty
hasDemandEnvSig :: StrictSig -> Bool
hasDemandEnvSig :: StrictSig -> Bool
hasDemandEnvSig (StrictSig (DmdType DmdEnv
env [Demand]
_ Divergence
_)) = Bool -> Bool
not (DmdEnv -> Bool
forall a. VarEnv a -> Bool
isEmptyVarEnv DmdEnv
env)
strictSigDmdEnv :: StrictSig -> DmdEnv
strictSigDmdEnv :: StrictSig -> DmdEnv
strictSigDmdEnv (StrictSig (DmdType DmdEnv
env [Demand]
_ Divergence
_)) = DmdEnv
env
isDeadEndSig :: StrictSig -> Bool
isDeadEndSig :: StrictSig -> Bool
isDeadEndSig (StrictSig (DmdType DmdEnv
_ [Demand]
_ Divergence
res)) = Divergence -> Bool
isDeadEndDiv Divergence
res
botSig :: StrictSig
botSig :: StrictSig
botSig = DmdType -> StrictSig
StrictSig DmdType
botDmdType
nopSig :: StrictSig
nopSig :: StrictSig
nopSig = DmdType -> StrictSig
StrictSig DmdType
nopDmdType
seqStrictSig :: StrictSig -> ()
seqStrictSig :: StrictSig -> ()
seqStrictSig (StrictSig DmdType
ty) = DmdType -> ()
seqDmdType DmdType
ty
dmdTransformSig :: StrictSig -> CleanDemand -> DmdType
dmdTransformSig :: StrictSig -> CleanDemand -> DmdType
dmdTransformSig (StrictSig dmd_ty :: DmdType
dmd_ty@(DmdType DmdEnv
_ [Demand]
arg_ds Divergence
_)) CleanDemand
cd
= DmdShell -> DmdType -> DmdType
postProcessUnsat (Int -> CleanDemand -> DmdShell
peelManyCalls ([Demand] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Demand]
arg_ds) CleanDemand
cd) DmdType
dmd_ty
dmdTransformDataConSig :: Arity -> CleanDemand -> DmdType
dmdTransformDataConSig :: Int -> CleanDemand -> DmdType
dmdTransformDataConSig Int
arity (JD { sd :: forall s u. JointDmd s u -> s
sd = StrDmd
str, ud :: forall s u. JointDmd s u -> u
ud = UseDmd
abs })
| Just [ArgStr]
str_dmds <- Int -> StrDmd -> Maybe [ArgStr]
forall {a}. (Eq a, Num a) => a -> StrDmd -> Maybe [ArgStr]
go_str Int
arity StrDmd
str
, Just [ArgUse]
abs_dmds <- Int -> UseDmd -> Maybe [ArgUse]
forall {t}. (Eq t, Num t) => t -> UseDmd -> Maybe [ArgUse]
go_abs Int
arity UseDmd
abs
= DmdEnv -> [Demand] -> Divergence -> DmdType
DmdType DmdEnv
emptyDmdEnv ([ArgStr] -> [ArgUse] -> [Demand]
forall s u. [s] -> [u] -> [JointDmd s u]
mkJointDmds [ArgStr]
str_dmds [ArgUse]
abs_dmds) Divergence
topDiv
| Bool
otherwise
= DmdType
nopDmdType
where
go_str :: a -> StrDmd -> Maybe [ArgStr]
go_str a
0 StrDmd
dmd = Int -> StrDmd -> Maybe [ArgStr]
splitStrProdDmd Int
arity StrDmd
dmd
go_str a
n (SCall StrDmd
s') = a -> StrDmd -> Maybe [ArgStr]
go_str (a
na -> a -> a
forall a. Num a => a -> a -> a
-a
1) StrDmd
s'
go_str a
n StrDmd
HyperStr = a -> StrDmd -> Maybe [ArgStr]
go_str (a
na -> a -> a
forall a. Num a => a -> a -> a
-a
1) StrDmd
HyperStr
go_str a
_ StrDmd
_ = Maybe [ArgStr]
forall a. Maybe a
Nothing
go_abs :: t -> UseDmd -> Maybe [ArgUse]
go_abs t
0 UseDmd
dmd = Int -> UseDmd -> Maybe [ArgUse]
splitUseProdDmd Int
arity UseDmd
dmd
go_abs t
n (UCall Count
One UseDmd
u') = t -> UseDmd -> Maybe [ArgUse]
go_abs (t
nt -> t -> t
forall a. Num a => a -> a -> a
-t
1) UseDmd
u'
go_abs t
_ UseDmd
_ = Maybe [ArgUse]
forall a. Maybe a
Nothing
dmdTransformDictSelSig :: StrictSig -> CleanDemand -> DmdType
dmdTransformDictSelSig :: StrictSig -> CleanDemand -> DmdType
dmdTransformDictSelSig (StrictSig (DmdType DmdEnv
_ [Demand
dict_dmd] Divergence
_)) CleanDemand
cd
| (CleanDemand
cd',DmdShell
defer_use) <- CleanDemand -> (CleanDemand, DmdShell)
peelCallDmd CleanDemand
cd
, Just [Demand]
jds <- Demand -> Maybe [Demand]
splitProdDmd_maybe Demand
dict_dmd
= DmdShell -> DmdType -> DmdType
postProcessUnsat DmdShell
defer_use (DmdType -> DmdType) -> DmdType -> DmdType
forall a b. (a -> b) -> a -> b
$
DmdEnv -> [Demand] -> Divergence -> DmdType
DmdType DmdEnv
emptyDmdEnv [CleanDemand -> Demand
mkOnceUsedDmd (CleanDemand -> Demand) -> CleanDemand -> Demand
forall a b. (a -> b) -> a -> b
$ [Demand] -> CleanDemand
mkProdDmd ([Demand] -> CleanDemand) -> [Demand] -> CleanDemand
forall a b. (a -> b) -> a -> b
$ (Demand -> Demand) -> [Demand] -> [Demand]
forall a b. (a -> b) -> [a] -> [b]
map (CleanDemand -> Demand -> Demand
enhance CleanDemand
cd') [Demand]
jds] Divergence
topDiv
| Bool
otherwise
= DmdType
nopDmdType
where
enhance :: CleanDemand -> Demand -> Demand
enhance CleanDemand
cd Demand
old | Demand -> Bool
forall s u. JointDmd (Str s) (Use u) -> Bool
isAbsDmd Demand
old = Demand
old
| Bool
otherwise = CleanDemand -> Demand
mkOnceUsedDmd CleanDemand
cd
dmdTransformDictSelSig StrictSig
_ CleanDemand
_ = String -> DmdType
forall a. String -> a
panic String
"dmdTransformDictSelSig: no args"
argsOneShots :: StrictSig -> Arity -> [[OneShotInfo]]
argsOneShots :: StrictSig -> Int -> [[OneShotInfo]]
argsOneShots (StrictSig (DmdType DmdEnv
_ [Demand]
arg_ds Divergence
_)) Int
n_val_args
| Bool
unsaturated_call = []
| Bool
otherwise = [Demand] -> [[OneShotInfo]]
go [Demand]
arg_ds
where
unsaturated_call :: Bool
unsaturated_call = [Demand]
arg_ds [Demand] -> Int -> Bool
forall a. [a] -> Int -> Bool
`lengthExceeds` Int
n_val_args
go :: [Demand] -> [[OneShotInfo]]
go [] = []
go (Demand
arg_d : [Demand]
arg_ds) = Demand -> [OneShotInfo]
argOneShots Demand
arg_d [OneShotInfo] -> [[OneShotInfo]] -> [[OneShotInfo]]
forall {a}. [a] -> [[a]] -> [[a]]
`cons` [Demand] -> [[OneShotInfo]]
go [Demand]
arg_ds
cons :: [a] -> [[a]] -> [[a]]
cons [] [] = []
cons [a]
a [[a]]
as = [a]
a[a] -> [[a]] -> [[a]]
forall a. a -> [a] -> [a]
:[[a]]
as
saturatedByOneShots :: Int -> Demand -> Bool
saturatedByOneShots :: Int -> Demand -> Bool
saturatedByOneShots Int
n (JD { ud :: forall s u. JointDmd s u -> u
ud = ArgUse
usg })
= case ArgUse
usg of
Use Count
_ UseDmd
arg_usg -> Int -> UseDmd -> Bool
forall {t}. (Eq t, Num t) => t -> UseDmd -> Bool
go Int
n UseDmd
arg_usg
ArgUse
_ -> Bool
False
where
go :: t -> UseDmd -> Bool
go t
0 UseDmd
_ = Bool
True
go t
n (UCall Count
One UseDmd
u) = t -> UseDmd -> Bool
go (t
nt -> t -> t
forall a. Num a => a -> a -> a
-t
1) UseDmd
u
go t
_ UseDmd
_ = Bool
False
argOneShots :: Demand
-> [OneShotInfo]
argOneShots :: Demand -> [OneShotInfo]
argOneShots (JD { ud :: forall s u. JointDmd s u -> u
ud = ArgUse
usg })
= case ArgUse
usg of
Use Count
_ UseDmd
arg_usg -> UseDmd -> [OneShotInfo]
go UseDmd
arg_usg
ArgUse
_ -> []
where
go :: UseDmd -> [OneShotInfo]
go (UCall Count
One UseDmd
u) = OneShotInfo
OneShotLam OneShotInfo -> [OneShotInfo] -> [OneShotInfo]
forall a. a -> [a] -> [a]
: UseDmd -> [OneShotInfo]
go UseDmd
u
go (UCall Count
Many UseDmd
u) = OneShotInfo
NoOneShotInfo OneShotInfo -> [OneShotInfo] -> [OneShotInfo]
forall a. a -> [a] -> [a]
: UseDmd -> [OneShotInfo]
go UseDmd
u
go UseDmd
_ = []
appIsDeadEnd :: StrictSig -> Int -> Bool
appIsDeadEnd :: StrictSig -> Int -> Bool
appIsDeadEnd (StrictSig (DmdType DmdEnv
_ [Demand]
ds Divergence
res)) Int
n
= Divergence -> Bool
isDeadEndDiv Divergence
res Bool -> Bool -> Bool
&& Bool -> Bool
not ([Demand] -> Int -> Bool
forall a. [a] -> Int -> Bool
lengthExceeds [Demand]
ds Int
n)
zapUsageEnvSig :: StrictSig -> StrictSig
zapUsageEnvSig :: StrictSig -> StrictSig
zapUsageEnvSig (StrictSig (DmdType DmdEnv
_ [Demand]
ds Divergence
r)) = [Demand] -> Divergence -> StrictSig
mkClosedStrictSig [Demand]
ds Divergence
r
zapUsageDemand :: Demand -> Demand
zapUsageDemand :: Demand -> Demand
zapUsageDemand = KillFlags -> Demand -> Demand
kill_usage (KillFlags -> Demand -> Demand) -> KillFlags -> Demand -> Demand
forall a b. (a -> b) -> a -> b
$ KillFlags :: Bool -> Bool -> Bool -> KillFlags
KillFlags
{ kf_abs :: Bool
kf_abs = Bool
True
, kf_used_once :: Bool
kf_used_once = Bool
True
, kf_called_once :: Bool
kf_called_once = Bool
True
}
zapUsedOnceDemand :: Demand -> Demand
zapUsedOnceDemand :: Demand -> Demand
zapUsedOnceDemand = KillFlags -> Demand -> Demand
kill_usage (KillFlags -> Demand -> Demand) -> KillFlags -> Demand -> Demand
forall a b. (a -> b) -> a -> b
$ KillFlags :: Bool -> Bool -> Bool -> KillFlags
KillFlags
{ kf_abs :: Bool
kf_abs = Bool
False
, kf_used_once :: Bool
kf_used_once = Bool
True
, kf_called_once :: Bool
kf_called_once = Bool
False
}
zapUsedOnceSig :: StrictSig -> StrictSig
zapUsedOnceSig :: StrictSig -> StrictSig
zapUsedOnceSig (StrictSig (DmdType DmdEnv
env [Demand]
ds Divergence
r))
= DmdType -> StrictSig
StrictSig (DmdEnv -> [Demand] -> Divergence -> DmdType
DmdType DmdEnv
env ((Demand -> Demand) -> [Demand] -> [Demand]
forall a b. (a -> b) -> [a] -> [b]
map Demand -> Demand
zapUsedOnceDemand [Demand]
ds) Divergence
r)
data KillFlags = KillFlags
{ KillFlags -> Bool
kf_abs :: Bool
, KillFlags -> Bool
kf_used_once :: Bool
, KillFlags -> Bool
kf_called_once :: Bool
}
kill_usage :: KillFlags -> Demand -> Demand
kill_usage :: KillFlags -> Demand -> Demand
kill_usage KillFlags
kfs (JD {sd :: forall s u. JointDmd s u -> s
sd = ArgStr
s, ud :: forall s u. JointDmd s u -> u
ud = ArgUse
u}) = JD :: forall s u. s -> u -> JointDmd s u
JD {sd :: ArgStr
sd = ArgStr
s, ud :: ArgUse
ud = KillFlags -> ArgUse -> ArgUse
zap_musg KillFlags
kfs ArgUse
u}
zap_musg :: KillFlags -> ArgUse -> ArgUse
zap_musg :: KillFlags -> ArgUse -> ArgUse
zap_musg KillFlags
kfs ArgUse
Abs
| KillFlags -> Bool
kf_abs KillFlags
kfs = ArgUse
useTop
| Bool
otherwise = ArgUse
forall u. Use u
Abs
zap_musg KillFlags
kfs (Use Count
c UseDmd
u)
| KillFlags -> Bool
kf_used_once KillFlags
kfs = Count -> UseDmd -> ArgUse
forall u. Count -> u -> Use u
Use Count
Many (KillFlags -> UseDmd -> UseDmd
zap_usg KillFlags
kfs UseDmd
u)
| Bool
otherwise = Count -> UseDmd -> ArgUse
forall u. Count -> u -> Use u
Use Count
c (KillFlags -> UseDmd -> UseDmd
zap_usg KillFlags
kfs UseDmd
u)
zap_usg :: KillFlags -> UseDmd -> UseDmd
zap_usg :: KillFlags -> UseDmd -> UseDmd
zap_usg KillFlags
kfs (UCall Count
c UseDmd
u)
| KillFlags -> Bool
kf_called_once KillFlags
kfs = Count -> UseDmd -> UseDmd
UCall Count
Many (KillFlags -> UseDmd -> UseDmd
zap_usg KillFlags
kfs UseDmd
u)
| Bool
otherwise = Count -> UseDmd -> UseDmd
UCall Count
c (KillFlags -> UseDmd -> UseDmd
zap_usg KillFlags
kfs UseDmd
u)
zap_usg KillFlags
kfs (UProd [ArgUse]
us) = [ArgUse] -> UseDmd
UProd ((ArgUse -> ArgUse) -> [ArgUse] -> [ArgUse]
forall a b. (a -> b) -> [a] -> [b]
map (KillFlags -> ArgUse -> ArgUse
zap_musg KillFlags
kfs) [ArgUse]
us)
zap_usg KillFlags
_ UseDmd
u = UseDmd
u
strictifyDictDmd :: Type -> Demand -> Demand
strictifyDictDmd :: Type -> Demand -> Demand
strictifyDictDmd Type
ty Demand
dmd = case Demand -> ArgUse
forall s u. JointDmd s u -> u
getUseDmd Demand
dmd of
Use Count
n UseDmd
_ |
Just (TyCon
tycon, [Type]
_arg_tys, DataCon
_data_con, [Scaled Type]
inst_con_arg_tys)
<- Type -> Maybe (TyCon, [Type], DataCon, [Scaled Type])
splitDataProductType_maybe Type
ty,
Bool -> Bool
not (TyCon -> Bool
isNewTyCon TyCon
tycon), TyCon -> Bool
isClassTyCon TyCon
tycon
-> Demand
seqDmd Demand -> Demand -> Demand
`bothDmd`
case Demand -> Maybe [Demand]
splitProdDmd_maybe Demand
dmd of
Maybe [Demand]
Nothing -> Demand
dmd
Just [Demand]
dmds
| (Demand -> Bool) -> [Demand] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (Bool -> Bool
not (Bool -> Bool) -> (Demand -> Bool) -> Demand -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Demand -> Bool
forall s u. JointDmd (Str s) (Use u) -> Bool
isAbsDmd) [Demand]
dmds -> Demand
evalDmd
| Bool
otherwise -> case [Demand] -> CleanDemand
mkProdDmd ([Demand] -> CleanDemand) -> [Demand] -> CleanDemand
forall a b. (a -> b) -> a -> b
$ (Type -> Demand -> Demand) -> [Type] -> [Demand] -> [Demand]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Type -> Demand -> Demand
strictifyDictDmd ((Scaled Type -> Type) -> [Scaled Type] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map Scaled Type -> Type
forall a. Scaled a -> a
scaledThing [Scaled Type]
inst_con_arg_tys) [Demand]
dmds of
JD {sd :: forall s u. JointDmd s u -> s
sd = StrDmd
s,ud :: forall s u. JointDmd s u -> u
ud = UseDmd
a} -> ArgStr -> ArgUse -> Demand
forall s u. s -> u -> JointDmd s u
JD (StrDmd -> ArgStr
forall s. s -> Str s
Str StrDmd
s) (Count -> UseDmd -> ArgUse
forall u. Count -> u -> Use u
Use Count
n UseDmd
a)
ArgUse
_ -> Demand
dmd
strictifyDmd :: Demand -> Demand
strictifyDmd :: Demand -> Demand
strictifyDmd dmd :: Demand
dmd@(JD { sd :: forall s u. JointDmd s u -> s
sd = ArgStr
str })
= Demand
dmd { sd :: ArgStr
sd = ArgStr
str ArgStr -> ArgStr -> ArgStr
`bothArgStr` StrDmd -> ArgStr
forall s. s -> Str s
Str StrDmd
HeadStr }
instance Binary StrDmd where
put_ :: BinHandle -> StrDmd -> IO ()
put_ BinHandle
bh StrDmd
HyperStr = do BinHandle -> Word8 -> IO ()
putByte BinHandle
bh Word8
0
put_ BinHandle
bh StrDmd
HeadStr = do BinHandle -> Word8 -> IO ()
putByte BinHandle
bh Word8
1
put_ BinHandle
bh (SCall StrDmd
s) = do BinHandle -> Word8 -> IO ()
putByte BinHandle
bh Word8
2
BinHandle -> StrDmd -> IO ()
forall a. Binary a => BinHandle -> a -> IO ()
put_ BinHandle
bh StrDmd
s
put_ BinHandle
bh (SProd [ArgStr]
sx) = do BinHandle -> Word8 -> IO ()
putByte BinHandle
bh Word8
3
BinHandle -> [ArgStr] -> IO ()
forall a. Binary a => BinHandle -> a -> IO ()
put_ BinHandle
bh [ArgStr]
sx
get :: BinHandle -> IO StrDmd
get BinHandle
bh = do
Word8
h <- BinHandle -> IO Word8
getByte BinHandle
bh
case Word8
h of
Word8
0 -> do StrDmd -> IO StrDmd
forall (m :: * -> *) a. Monad m => a -> m a
return StrDmd
HyperStr
Word8
1 -> do StrDmd -> IO StrDmd
forall (m :: * -> *) a. Monad m => a -> m a
return StrDmd
HeadStr
Word8
2 -> do StrDmd
s <- BinHandle -> IO StrDmd
forall a. Binary a => BinHandle -> IO a
get BinHandle
bh
StrDmd -> IO StrDmd
forall (m :: * -> *) a. Monad m => a -> m a
return (StrDmd -> StrDmd
SCall StrDmd
s)
Word8
_ -> do [ArgStr]
sx <- BinHandle -> IO [ArgStr]
forall a. Binary a => BinHandle -> IO a
get BinHandle
bh
StrDmd -> IO StrDmd
forall (m :: * -> *) a. Monad m => a -> m a
return ([ArgStr] -> StrDmd
SProd [ArgStr]
sx)
instance Binary ArgStr where
put_ :: BinHandle -> ArgStr -> IO ()
put_ BinHandle
bh ArgStr
Lazy = do
BinHandle -> Word8 -> IO ()
putByte BinHandle
bh Word8
0
put_ BinHandle
bh (Str StrDmd
s) = do
BinHandle -> Word8 -> IO ()
putByte BinHandle
bh Word8
1
BinHandle -> StrDmd -> IO ()
forall a. Binary a => BinHandle -> a -> IO ()
put_ BinHandle
bh StrDmd
s
get :: BinHandle -> IO ArgStr
get BinHandle
bh = do
Word8
h <- BinHandle -> IO Word8
getByte BinHandle
bh
case Word8
h of
Word8
0 -> ArgStr -> IO ArgStr
forall (m :: * -> *) a. Monad m => a -> m a
return ArgStr
forall s. Str s
Lazy
Word8
_ -> do StrDmd
s <- BinHandle -> IO StrDmd
forall a. Binary a => BinHandle -> IO a
get BinHandle
bh
ArgStr -> IO ArgStr
forall (m :: * -> *) a. Monad m => a -> m a
return (ArgStr -> IO ArgStr) -> ArgStr -> IO ArgStr
forall a b. (a -> b) -> a -> b
$ StrDmd -> ArgStr
forall s. s -> Str s
Str StrDmd
s
instance Binary Count where
put_ :: BinHandle -> Count -> IO ()
put_ BinHandle
bh Count
One = do BinHandle -> Word8 -> IO ()
putByte BinHandle
bh Word8
0
put_ BinHandle
bh Count
Many = do BinHandle -> Word8 -> IO ()
putByte BinHandle
bh Word8
1
get :: BinHandle -> IO Count
get BinHandle
bh = do Word8
h <- BinHandle -> IO Word8
getByte BinHandle
bh
case Word8
h of
Word8
0 -> Count -> IO Count
forall (m :: * -> *) a. Monad m => a -> m a
return Count
One
Word8
_ -> Count -> IO Count
forall (m :: * -> *) a. Monad m => a -> m a
return Count
Many
instance Binary ArgUse where
put_ :: BinHandle -> ArgUse -> IO ()
put_ BinHandle
bh ArgUse
Abs = do
BinHandle -> Word8 -> IO ()
putByte BinHandle
bh Word8
0
put_ BinHandle
bh (Use Count
c UseDmd
u) = do
BinHandle -> Word8 -> IO ()
putByte BinHandle
bh Word8
1
BinHandle -> Count -> IO ()
forall a. Binary a => BinHandle -> a -> IO ()
put_ BinHandle
bh Count
c
BinHandle -> UseDmd -> IO ()
forall a. Binary a => BinHandle -> a -> IO ()
put_ BinHandle
bh UseDmd
u
get :: BinHandle -> IO ArgUse
get BinHandle
bh = do
Word8
h <- BinHandle -> IO Word8
getByte BinHandle
bh
case Word8
h of
Word8
0 -> ArgUse -> IO ArgUse
forall (m :: * -> *) a. Monad m => a -> m a
return ArgUse
forall u. Use u
Abs
Word8
_ -> do Count
c <- BinHandle -> IO Count
forall a. Binary a => BinHandle -> IO a
get BinHandle
bh
UseDmd
u <- BinHandle -> IO UseDmd
forall a. Binary a => BinHandle -> IO a
get BinHandle
bh
ArgUse -> IO ArgUse
forall (m :: * -> *) a. Monad m => a -> m a
return (ArgUse -> IO ArgUse) -> ArgUse -> IO ArgUse
forall a b. (a -> b) -> a -> b
$ Count -> UseDmd -> ArgUse
forall u. Count -> u -> Use u
Use Count
c UseDmd
u
instance Binary UseDmd where
put_ :: BinHandle -> UseDmd -> IO ()
put_ BinHandle
bh UseDmd
Used = do
BinHandle -> Word8 -> IO ()
putByte BinHandle
bh Word8
0
put_ BinHandle
bh UseDmd
UHead = do
BinHandle -> Word8 -> IO ()
putByte BinHandle
bh Word8
1
put_ BinHandle
bh (UCall Count
c UseDmd
u) = do
BinHandle -> Word8 -> IO ()
putByte BinHandle
bh Word8
2
BinHandle -> Count -> IO ()
forall a. Binary a => BinHandle -> a -> IO ()
put_ BinHandle
bh Count
c
BinHandle -> UseDmd -> IO ()
forall a. Binary a => BinHandle -> a -> IO ()
put_ BinHandle
bh UseDmd
u
put_ BinHandle
bh (UProd [ArgUse]
ux) = do
BinHandle -> Word8 -> IO ()
putByte BinHandle
bh Word8
3
BinHandle -> [ArgUse] -> IO ()
forall a. Binary a => BinHandle -> a -> IO ()
put_ BinHandle
bh [ArgUse]
ux
get :: BinHandle -> IO UseDmd
get BinHandle
bh = do
Word8
h <- BinHandle -> IO Word8
getByte BinHandle
bh
case Word8
h of
Word8
0 -> UseDmd -> IO UseDmd
forall (m :: * -> *) a. Monad m => a -> m a
return (UseDmd -> IO UseDmd) -> UseDmd -> IO UseDmd
forall a b. (a -> b) -> a -> b
$ UseDmd
Used
Word8
1 -> UseDmd -> IO UseDmd
forall (m :: * -> *) a. Monad m => a -> m a
return (UseDmd -> IO UseDmd) -> UseDmd -> IO UseDmd
forall a b. (a -> b) -> a -> b
$ UseDmd
UHead
Word8
2 -> do Count
c <- BinHandle -> IO Count
forall a. Binary a => BinHandle -> IO a
get BinHandle
bh
UseDmd
u <- BinHandle -> IO UseDmd
forall a. Binary a => BinHandle -> IO a
get BinHandle
bh
UseDmd -> IO UseDmd
forall (m :: * -> *) a. Monad m => a -> m a
return (Count -> UseDmd -> UseDmd
UCall Count
c UseDmd
u)
Word8
_ -> do [ArgUse]
ux <- BinHandle -> IO [ArgUse]
forall a. Binary a => BinHandle -> IO a
get BinHandle
bh
UseDmd -> IO UseDmd
forall (m :: * -> *) a. Monad m => a -> m a
return ([ArgUse] -> UseDmd
UProd [ArgUse]
ux)
instance (Binary s, Binary u) => Binary (JointDmd s u) where
put_ :: BinHandle -> JointDmd s u -> IO ()
put_ BinHandle
bh (JD { sd :: forall s u. JointDmd s u -> s
sd = s
x, ud :: forall s u. JointDmd s u -> u
ud = u
y }) = do BinHandle -> s -> IO ()
forall a. Binary a => BinHandle -> a -> IO ()
put_ BinHandle
bh s
x; BinHandle -> u -> IO ()
forall a. Binary a => BinHandle -> a -> IO ()
put_ BinHandle
bh u
y
get :: BinHandle -> IO (JointDmd s u)
get BinHandle
bh = do
s
x <- BinHandle -> IO s
forall a. Binary a => BinHandle -> IO a
get BinHandle
bh
u
y <- BinHandle -> IO u
forall a. Binary a => BinHandle -> IO a
get BinHandle
bh
JointDmd s u -> IO (JointDmd s u)
forall (m :: * -> *) a. Monad m => a -> m a
return (JointDmd s u -> IO (JointDmd s u))
-> JointDmd s u -> IO (JointDmd s u)
forall a b. (a -> b) -> a -> b
$ JD :: forall s u. s -> u -> JointDmd s u
JD { sd :: s
sd = s
x, ud :: u
ud = u
y }
instance Binary StrictSig where
put_ :: BinHandle -> StrictSig -> IO ()
put_ BinHandle
bh (StrictSig DmdType
aa) = do
BinHandle -> DmdType -> IO ()
forall a. Binary a => BinHandle -> a -> IO ()
put_ BinHandle
bh DmdType
aa
get :: BinHandle -> IO StrictSig
get BinHandle
bh = do
DmdType
aa <- BinHandle -> IO DmdType
forall a. Binary a => BinHandle -> IO a
get BinHandle
bh
StrictSig -> IO StrictSig
forall (m :: * -> *) a. Monad m => a -> m a
return (DmdType -> StrictSig
StrictSig DmdType
aa)
instance Binary DmdType where
put_ :: BinHandle -> DmdType -> IO ()
put_ BinHandle
bh (DmdType DmdEnv
_ [Demand]
ds Divergence
dr)
= do BinHandle -> [Demand] -> IO ()
forall a. Binary a => BinHandle -> a -> IO ()
put_ BinHandle
bh [Demand]
ds
BinHandle -> Divergence -> IO ()
forall a. Binary a => BinHandle -> a -> IO ()
put_ BinHandle
bh Divergence
dr
get :: BinHandle -> IO DmdType
get BinHandle
bh
= do [Demand]
ds <- BinHandle -> IO [Demand]
forall a. Binary a => BinHandle -> IO a
get BinHandle
bh
Divergence
dr <- BinHandle -> IO Divergence
forall a. Binary a => BinHandle -> IO a
get BinHandle
bh
DmdType -> IO DmdType
forall (m :: * -> *) a. Monad m => a -> m a
return (DmdEnv -> [Demand] -> Divergence -> DmdType
DmdType DmdEnv
emptyDmdEnv [Demand]
ds Divergence
dr)
instance Binary Divergence where
put_ :: BinHandle -> Divergence -> IO ()
put_ BinHandle
bh Divergence
Dunno = BinHandle -> Word8 -> IO ()
putByte BinHandle
bh Word8
0
put_ BinHandle
bh Divergence
ExnOrDiv = BinHandle -> Word8 -> IO ()
putByte BinHandle
bh Word8
1
put_ BinHandle
bh Divergence
Diverges = BinHandle -> Word8 -> IO ()
putByte BinHandle
bh Word8
2
get :: BinHandle -> IO Divergence
get BinHandle
bh = do { Word8
h <- BinHandle -> IO Word8
getByte BinHandle
bh
; case Word8
h of
Word8
0 -> Divergence -> IO Divergence
forall (m :: * -> *) a. Monad m => a -> m a
return Divergence
Dunno
Word8
1 -> Divergence -> IO Divergence
forall (m :: * -> *) a. Monad m => a -> m a
return Divergence
ExnOrDiv
Word8
_ -> Divergence -> IO Divergence
forall (m :: * -> *) a. Monad m => a -> m a
return Divergence
Diverges }