Safe Haskell | Safe-Inferred |
---|---|
Language | Haskell2010 |
Arity and eta expansion
Synopsis
- manifestArity :: CoreExpr -> Arity
- joinRhsArity :: CoreExpr -> JoinArity
- exprArity :: CoreExpr -> Arity
- findRhsArity :: ArityOpts -> RecFlag -> Id -> CoreExpr -> (Bool, SafeArityType)
- cheapArityType :: HasDebugCallStack => CoreExpr -> ArityType
- data ArityOpts = ArityOpts {
- ao_ped_bot :: !Bool
- ao_dicts_cheap :: !Bool
- exprEtaExpandArity :: ArityOpts -> CoreExpr -> Maybe SafeArityType
- etaExpand :: Arity -> CoreExpr -> CoreExpr
- etaExpandAT :: InScopeSet -> SafeArityType -> CoreExpr -> CoreExpr
- tryEtaReduce :: UnVarSet -> [Var] -> CoreExpr -> SubDemand -> Maybe CoreExpr
- data ArityType
- mkBotArityType :: [OneShotInfo] -> ArityType
- arityTypeArity :: SafeArityType -> Arity
- idArityType :: Id -> ArityType
- exprIsDeadEnd :: CoreExpr -> Bool
- exprBotStrictness_maybe :: CoreExpr -> Maybe (Arity, DmdSig, CprSig)
- arityTypeBotSigs_maybe :: ArityType -> Maybe (Arity, DmdSig, CprSig)
- typeArity :: Type -> Arity
- typeOneShots :: Type -> [OneShotInfo]
- typeOneShot :: Type -> OneShotInfo
- isOneShotBndr :: Var -> Bool
- isStateHackType :: Type -> Bool
- zapLamBndrs :: FullArgCount -> [Var] -> [Var]
- etaExpandToJoinPoint :: JoinArity -> CoreExpr -> ([CoreBndr], CoreExpr)
- etaExpandToJoinPointRule :: JoinArity -> CoreRule -> CoreRule
- pushCoArg :: CoercionR -> CoreArg -> Maybe (CoreArg, MCoercion)
- pushCoArgs :: CoercionR -> [CoreArg] -> Maybe ([CoreArg], MCoercion)
- pushCoValArg :: CoercionR -> Maybe (MCoercionR, MCoercionR)
- pushCoTyArg :: CoercionR -> Type -> Maybe (Type, MCoercionR)
- pushCoercionIntoLambda :: HasDebugCallStack => InScopeSet -> Var -> CoreExpr -> CoercionR -> Maybe (Var, CoreExpr)
- pushCoDataCon :: DataCon -> [CoreExpr] -> Coercion -> Maybe (DataCon, [Type], [CoreExpr])
- collectBindersPushingCo :: CoreExpr -> ([Var], CoreExpr)
Documentation
manifestArity :: CoreExpr -> Arity Source #
manifestArity sees how many leading value lambdas there are, after looking through casts
joinRhsArity :: CoreExpr -> JoinArity Source #
exprArity :: CoreExpr -> Arity Source #
An approximate, even faster, version of cheapArityType
Roughly exprArity e = arityTypeArity (cheapArityType e)
But it's a bit less clever about bottoms
We do not guarantee that exprArity e <= typeArity e You may need to do arity trimming after calling exprArity See Note [Arity trimming] Reason: if we do arity trimming here we have take exprType and that can be expensive if there is a large cast
cheapArityType :: HasDebugCallStack => CoreExpr -> ArityType Source #
ArityOpts | |
|
Eta expansion
exprEtaExpandArity :: ArityOpts -> CoreExpr -> Maybe SafeArityType Source #
The Arity returned is the number of value args the expression can be applied to without doing much work
etaExpand :: Arity -> CoreExpr -> CoreExpr Source #
etaExpand n e
returns an expression with
the same meaning as e
, but with arity n
.
Given:
e' = etaExpand n e
We should have that:
ty = exprType e = exprType e'
etaExpandAT :: InScopeSet -> SafeArityType -> CoreExpr -> CoreExpr Source #
Eta reduction
tryEtaReduce :: UnVarSet -> [Var] -> CoreExpr -> SubDemand -> Maybe CoreExpr Source #
`tryEtaReduce [x,y,z] e sd` returns `Just e'` if `x y z -> e` is evaluated
according to sd
and can soundly and gainfully be eta-reduced to e'
.
See Note [Eta reduction soundness]
and Note [Eta reduction makes sense] when that is the case.
ArityType
The analysis lattice of arity analysis. It is isomorphic to
data ArityType' = AEnd Divergence | ALam OneShotInfo ArityType'
Which is easier to display the Hasse diagram for:
ALam OneShotLam at | AEnd topDiv | ALam NoOneShotInfo at | AEnd exnDiv | AEnd botDiv
where the at
fields of ALam
are inductively subject to the same order.
That is, ALam os at1 < ALam os at2
iff at1 < at2
.
Why the strange Top element? See Note [Combining case branches: optimistic one-shot-ness]
We rely on this lattice structure for fixed-point iteration in
findRhsArity
. For the semantics of ArityType
, see Note [ArityType].
Instances
Outputable ArityType Source # | This is the BNF of the generated output: @ We format AT [o1,..,on] topDiv |
Eq ArityType Source # | |
mkBotArityType :: [OneShotInfo] -> ArityType Source #
arityTypeArity :: SafeArityType -> Arity Source #
The number of value args for the arity type
idArityType :: Id -> ArityType Source #
Bottoming things
exprIsDeadEnd :: CoreExpr -> Bool Source #
typeArity and the state hack
typeArity :: Type -> Arity Source #
(typeArity ty) says how many arrows GHC can expose in ty
, after
looking through newtypes. More generally, (typeOneShots ty) returns
ty's [OneShotInfo], based only on the type itself, using typeOneShot
on the argument type to access the "state hack".
typeOneShots :: Type -> [OneShotInfo] Source #
typeOneShot :: Type -> OneShotInfo Source #
isOneShotBndr :: Var -> Bool Source #
Returns whether the lambda associated with the Id
is
certainly applied at most once
This one is the "business end", called externally.
It works on type variables as well as Ids, returning True
Its main purpose is to encapsulate the Horrible State Hack
See Note [The state-transformer hack] in GHC.Core.Opt.Arity
isStateHackType :: Type -> Bool Source #
Lambdas
zapLamBndrs :: FullArgCount -> [Var] -> [Var] Source #
Join points
etaExpandToJoinPoint :: JoinArity -> CoreExpr -> ([CoreBndr], CoreExpr) Source #
Split an expression into the given number of binders and a body, eta-expanding if necessary. Counts value *and* type binders.
Coercions and casts
pushCoValArg :: CoercionR -> Maybe (MCoercionR, MCoercionR) Source #
If pushCoValArg co = Just (co_arg, co_res)
, then
(\x.body) |> co = (\y. let { x = y |> co_arg } in body) |> co_res)
or, equivalently
(fun |> co) arg = (fun (arg |> co_arg)) |> co_res
If the LHS is well-typed, then so is the RHS. In particular, the argument
arg |> co_arg
is guaranteed to have a fixed RuntimeRep
, in the sense of
Note [Fixed RuntimeRep] in GHC.Tc.Utils.Concrete.
pushCoTyArg :: CoercionR -> Type -> Maybe (Type, MCoercionR) Source #
pushCoercionIntoLambda :: HasDebugCallStack => InScopeSet -> Var -> CoreExpr -> CoercionR -> Maybe (Var, CoreExpr) Source #