Safe Haskell | Safe-Inferred |
---|---|
Language | Haskell2010 |
Synopsis
- data StrDmd
- data UseDmd
- data Count
- type Demand = JointDmd ArgStr ArgUse
- type DmdShell = JointDmd (Str ()) (Use ())
- type CleanDemand = JointDmd StrDmd UseDmd
- getStrDmd :: JointDmd s u -> s
- getUseDmd :: JointDmd s u -> u
- mkProdDmd :: [Demand] -> CleanDemand
- mkOnceUsedDmd :: CleanDemand -> Demand
- mkManyUsedDmd :: CleanDemand -> Demand
- mkHeadStrict :: CleanDemand -> CleanDemand
- oneifyDmd :: JointDmd s (Use u) -> JointDmd s (Use u)
- toCleanDmd :: Demand -> (DmdShell, CleanDemand)
- absDmd :: Demand
- topDmd :: Demand
- botDmd :: Demand
- seqDmd :: Demand
- lubDmd :: Demand -> Demand -> Demand
- bothDmd :: Demand -> Demand -> Demand
- lazyApply1Dmd :: Demand
- lazyApply2Dmd :: Demand
- strictApply1Dmd :: Demand
- isTopDmd :: Demand -> Bool
- isAbsDmd :: JointDmd (Str s) (Use u) -> Bool
- isSeqDmd :: Demand -> Bool
- peelUseCall :: UseDmd -> Maybe (Count, UseDmd)
- cleanUseDmd_maybe :: Demand -> Maybe UseDmd
- strictenDmd :: Demand -> Demand
- bothCleanDmd :: CleanDemand -> CleanDemand -> CleanDemand
- addCaseBndrDmd :: Demand -> [Demand] -> [Demand]
- data DmdType = DmdType DmdEnv [Demand] Divergence
- dmdTypeDepth :: DmdType -> Arity
- lubDmdType :: DmdType -> DmdType -> DmdType
- bothDmdType :: DmdType -> BothDmdArg -> DmdType
- type BothDmdArg = (DmdEnv, Divergence)
- mkBothDmdArg :: DmdEnv -> BothDmdArg
- toBothDmdArg :: DmdType -> BothDmdArg
- nopDmdType :: DmdType
- botDmdType :: DmdType
- addDemand :: Demand -> DmdType -> DmdType
- type DmdEnv = VarEnv Demand
- emptyDmdEnv :: VarEnv Demand
- keepAliveDmdEnv :: DmdEnv -> IdSet -> DmdEnv
- peelFV :: DmdType -> Var -> (DmdType, Demand)
- findIdDemand :: DmdType -> Var -> Demand
- data Divergence
- lubDivergence :: Divergence -> Divergence -> Divergence
- isDeadEndDiv :: Divergence -> Bool
- topDiv :: Divergence
- botDiv :: Divergence
- exnDiv :: Divergence
- appIsDeadEnd :: StrictSig -> Int -> Bool
- isDeadEndSig :: StrictSig -> Bool
- pprIfaceStrictSig :: StrictSig -> SDoc
- newtype StrictSig = StrictSig DmdType
- mkStrictSigForArity :: Arity -> DmdType -> StrictSig
- mkClosedStrictSig :: [Demand] -> Divergence -> StrictSig
- nopSig :: StrictSig
- botSig :: StrictSig
- isTopSig :: StrictSig -> Bool
- hasDemandEnvSig :: StrictSig -> Bool
- splitStrictSig :: StrictSig -> ([Demand], Divergence)
- strictSigDmdEnv :: StrictSig -> DmdEnv
- prependArgsStrictSig :: Int -> StrictSig -> StrictSig
- etaConvertStrictSig :: Arity -> StrictSig -> StrictSig
- seqDemand :: Demand -> ()
- seqDemandList :: [Demand] -> ()
- seqDmdType :: DmdType -> ()
- seqStrictSig :: StrictSig -> ()
- evalDmd :: Demand
- cleanEvalDmd :: CleanDemand
- cleanEvalProdDmd :: Arity -> CleanDemand
- isStrictDmd :: JointDmd (Str s) (Use u) -> Bool
- splitDmdTy :: DmdType -> (Demand, DmdType)
- splitFVs :: Bool -> DmdEnv -> (DmdEnv, DmdEnv)
- deferAfterPreciseException :: DmdType -> DmdType
- postProcessUnsat :: DmdShell -> DmdType -> DmdType
- postProcessDmdType :: DmdShell -> DmdType -> BothDmdArg
- splitProdDmd_maybe :: Demand -> Maybe [Demand]
- peelCallDmd :: CleanDemand -> (CleanDemand, DmdShell)
- peelManyCalls :: Int -> CleanDemand -> DmdShell
- mkCallDmd :: CleanDemand -> CleanDemand
- mkCallDmds :: Arity -> CleanDemand -> CleanDemand
- mkWorkerDemand :: Int -> Demand
- dmdTransformSig :: StrictSig -> CleanDemand -> DmdType
- dmdTransformDataConSig :: Arity -> CleanDemand -> DmdType
- dmdTransformDictSelSig :: StrictSig -> CleanDemand -> DmdType
- argOneShots :: Demand -> [OneShotInfo]
- argsOneShots :: StrictSig -> Arity -> [[OneShotInfo]]
- saturatedByOneShots :: Int -> Demand -> Bool
- data TypeShape
- trimToType :: Demand -> TypeShape -> Demand
- useCount :: Use u -> Count
- isUsedOnce :: JointDmd (Str s) (Use u) -> Bool
- reuseEnv :: DmdEnv -> DmdEnv
- zapUsageDemand :: Demand -> Demand
- zapUsageEnvSig :: StrictSig -> StrictSig
- zapUsedOnceDemand :: Demand -> Demand
- zapUsedOnceSig :: StrictSig -> StrictSig
- strictifyDictDmd :: Type -> Demand -> Demand
- strictifyDmd :: Demand -> Demand
Documentation
Vanilla strictness domain
Domain for genuine usage
UCall Count UseDmd | Call demand for absence. Used only for values of function type |
UProd [ArgUse] | Product. Used only for values of product type See Note [Don't optimise UProd(Used) to Used] Invariant: Not all components are Abs (in that case, use UHead) |
UHead | May be used but its sub-components are definitely *not* used. For product types, UHead is equivalent to U(AAA); see mkUProd. UHead is needed only to express the demand
of Since (UCall _ Abs) is ill-typed, UHead doesn't make sense for lambdas |
Used | May be used and its sub-components may be used. (top of the lattice) |
Abstract counting of usages
type CleanDemand = JointDmd StrDmd UseDmd Source #
mkProdDmd :: [Demand] -> CleanDemand Source #
mkOnceUsedDmd :: CleanDemand -> Demand Source #
mkManyUsedDmd :: CleanDemand -> Demand Source #
toCleanDmd :: Demand -> (DmdShell, CleanDemand) Source #
strictenDmd :: Demand -> Demand Source #
bothCleanDmd :: CleanDemand -> CleanDemand -> CleanDemand Source #
dmdTypeDepth :: DmdType -> Arity Source #
lubDmdType :: DmdType -> DmdType -> DmdType Source #
Compute the least upper bound of two DmdType
s elicited /by the same
incoming demand/!
bothDmdType :: DmdType -> BothDmdArg -> DmdType Source #
type BothDmdArg = (DmdEnv, Divergence) Source #
mkBothDmdArg :: DmdEnv -> BothDmdArg Source #
toBothDmdArg :: DmdType -> BothDmdArg Source #
nopDmdType :: DmdType Source #
The demand type of doing nothing (lazy, absent, no Divergence
information). Note that it is 'not'
the top of the lattice (which would be
"may use everything"), so it is (no longer) called topDmdType.
(SG: I agree, but why is it still topDmd
then?)
botDmdType :: DmdType Source #
data Divergence Source #
Divergence lattice. Models a subset lattice of the following exhaustive set of divergence results:
- n
- nontermination (e.g. loops)
- i
- throws imprecise exception
- p
- throws precise exception
- c
- converges (reduces to WHNF)
The different lattice elements correspond to different subsets, indicated by juxtaposition of indicators (e.g. nc definitely doesn't throw an exception, and may or may not reduce to WHNF).
Dunno (nipc) | ExnOrDiv (nip) | Diverges (ni)
As you can see, we don't distinguish n and i. See Note [Precise exceptions and strictness analysis] for why p is so special compared to i.
Diverges | Definitely throws an imprecise exception or diverges. |
ExnOrDiv | Definitely throws a *precise* exception, an imprecise
exception or diverges. Never converges, hence |
Dunno | Might diverge, throw any kind of exception or converge. |
Instances
Show Divergence Source # | |
Defined in GHC.Types.Demand | |
Binary Divergence Source # | |
Defined in GHC.Types.Demand put_ :: BinHandle -> Divergence -> IO () Source # put :: BinHandle -> Divergence -> IO (Bin Divergence) Source # | |
Outputable Divergence Source # | |
Defined in GHC.Types.Demand | |
Eq Divergence Source # | |
Defined in GHC.Types.Demand (==) :: Divergence -> Divergence -> Bool # (/=) :: Divergence -> Divergence -> Bool # |
lubDivergence :: Divergence -> Divergence -> Divergence Source #
isDeadEndDiv :: Divergence -> Bool Source #
True if the result indicates that evaluation will not return. See Note [Dead ends].
topDiv :: Divergence Source #
botDiv :: Divergence Source #
exnDiv :: Divergence Source #
appIsDeadEnd :: StrictSig -> Int -> Bool Source #
Returns true if an application to n args would diverge or throw an exception. See Note [Unsaturated applications] and Note [Dead ends].
isDeadEndSig :: StrictSig -> Bool Source #
True if the signature diverges or throws an exception in a saturated call. See Note [Dead ends].
pprIfaceStrictSig :: StrictSig -> SDoc Source #
The depth of the wrapped DmdType
encodes the arity at which it is safe
to unleash. Better construct this through mkStrictSigForArity
.
See Note [Understanding DmdType and StrictSig]
mkClosedStrictSig :: [Demand] -> Divergence -> StrictSig Source #
hasDemandEnvSig :: StrictSig -> Bool Source #
splitStrictSig :: StrictSig -> ([Demand], Divergence) Source #
strictSigDmdEnv :: StrictSig -> DmdEnv Source #
prependArgsStrictSig :: Int -> StrictSig -> StrictSig Source #
Add extra (topDmd
) arguments to a strictness signature.
In contrast to etaConvertStrictSig
, this prepends additional argument
demands. This is used by FloatOut.
etaConvertStrictSig :: Arity -> StrictSig -> StrictSig Source #
We are expanding (x y. e) to (x y z. e z) or reducing from the latter to
the former (when the Simplifier identifies a new join points, for example).
In contrast to prependArgsStrictSig
, this appends extra arg demands if
necessary.
This works by looking at the DmdType
(which was produced under a call
demand for the old arity) and trying to transfer as many facts as we can to
the call demand of new arity.
An arity increase (resulting in a stronger incoming demand) can retain much
of the info, while an arity decrease (a weakening of the incoming demand)
must fall back to a conservative default.
seqDemandList :: [Demand] -> () Source #
seqDmdType :: DmdType -> () Source #
seqStrictSig :: StrictSig -> () Source #
cleanEvalProdDmd :: Arity -> CleanDemand Source #
isStrictDmd :: JointDmd (Str s) (Use u) -> Bool Source #
deferAfterPreciseException :: DmdType -> DmdType Source #
When e is evaluated after executing an IO action that may throw a precise
exception, we act as if there is an additional control flow path that is
taken if e throws a precise exception. The demand type of this control flow
path
* is lazy and absent (topDmd
) in all free variables and arguments
* has exnDiv
Divergence
result
So we can simply take a variant of nopDmdType
, exnDmdType
.
Why not nopDmdType
? Because then the result of e
can never be exnDiv
!
That means failure to drop dead-ends, see #18086.
See Note [Precise exceptions and strictness analysis]
postProcessDmdType :: DmdShell -> DmdType -> BothDmdArg Source #
peelCallDmd :: CleanDemand -> (CleanDemand, DmdShell) Source #
peelManyCalls :: Int -> CleanDemand -> DmdShell Source #
mkCallDmd :: CleanDemand -> CleanDemand Source #
Wraps the CleanDemand
with a one-shot call demand: d
-> C1(d)
.
mkCallDmds :: Arity -> CleanDemand -> CleanDemand Source #
mkCallDmds n d
returns C1(C1...(C1 d))
where there are n
C1
's.
mkWorkerDemand :: Int -> Demand Source #
dmdTransformSig :: StrictSig -> CleanDemand -> DmdType Source #
dmdTransformDataConSig :: Arity -> CleanDemand -> DmdType Source #
dmdTransformDictSelSig :: StrictSig -> CleanDemand -> DmdType Source #
argOneShots :: Demand -> [OneShotInfo] Source #
argsOneShots :: StrictSig -> Arity -> [[OneShotInfo]] Source #
isUsedOnce :: JointDmd (Str s) (Use u) -> Bool Source #
zapUsageDemand :: Demand -> Demand Source #
zapUsageEnvSig :: StrictSig -> StrictSig Source #
zapUsedOnceDemand :: Demand -> Demand Source #
Remove all 1* information (but not C1 information) from the demand
zapUsedOnceSig :: StrictSig -> StrictSig Source #
Remove all 1* information (but not C1 information) from the strictness signature
strictifyDmd :: Demand -> Demand Source #