| Safe Haskell | Ignore |
|---|---|
| Language | Haskell2010 |
GHC.Core.Opt.WorkWrap.Utils
Synopsis
- data WwOpts = MkWwOpts {
- wo_fam_envs :: !FamInstEnvs
- wo_simple_opts :: !SimpleOpts
- wo_cpr_anal :: !Bool
- wo_module :: !Module
- wo_unlift_strict :: !Bool
- mkWwBodies :: WwOpts -> Id -> [Var] -> Type -> [Demand] -> Cpr -> UniqSM (Maybe WwResult)
- mkWWstr :: WwOpts -> [Var] -> [StrictnessMark] -> UniqSM (WwUse, [(Var, StrictnessMark)], CoreExpr -> CoreExpr, [CoreExpr])
- mkWWstr_one :: WwOpts -> Var -> StrictnessMark -> UniqSM (WwUse, [(Var, StrictnessMark)], CoreExpr -> CoreExpr, CoreExpr)
- needsVoidWorkerArg :: Id -> [Var] -> [Var] -> Bool
- data DataConPatContext s = DataConPatContext {}
- data UnboxingDecision unboxing_info
- = DontUnbox
- | DoUnbox !unboxing_info
- | DropAbsent
- canUnboxArg :: FamInstEnvs -> Type -> Demand -> UnboxingDecision (DataConPatContext Demand)
- findTypeShape :: FamInstEnvs -> Type -> TypeShape
- data IsRecDataConResult
- isRecDataCon :: FamInstEnvs -> IntWithInf -> DataCon -> IsRecDataConResult
- mkAbsentFiller :: WwOpts -> Id -> StrictnessMark -> Maybe CoreExpr
- isWorkerSmallEnough :: Int -> Int -> [Var] -> Bool
- dubiousDataConInstArgTys :: DataCon -> [Type] -> [Type]
- boringSplit :: WwUse
- usefulSplit :: WwUse
Documentation
Constructors
| MkWwOpts | |
Fields
| |
Arguments
| :: WwOpts | |
| -> Id | The original function |
| -> [Var] | Manifest args of original function |
| -> Type | Result type of the original function, after being stripped of args |
| -> [Demand] | Strictness of original function |
| -> Cpr | Info about function result |
| -> UniqSM (Maybe WwResult) |
Given a function definition
data T = MkT Int Bool Char f :: (a, b) -> Int -> T f = \x y -> E
mkWwBodies _
returnsf ['x::(a,b)','y::Int'] '(a,b)' ['1P(L,L)', '1P(L)'] '1'
- The wrapper body context for the call to the worker function, lacking
only the
Idfor the worker function:
W[_] :: Id -> CoreExpr W[work_fn] = \x y -> -- args of the wrapper (cloned_arg_vars) case x of (a, b) -> -- unbox wrapper args (wrap_fn_str) case y of I# n -> -- case <work_fn> a b n of -- call to the worker fun (call_work) (# i, b, c #) -> MkT i b c -- rebox result (wrap_fn_cpr)
- The worker body context that wraps around its hole reboxing defns for x and y, as well as returning CPR transit variables of the unboxed MkT result in an unboxed tuple:
w[_] :: CoreExpr -> CoreExpr
w[fn_rhs] = \a b n -> -- args of the worker (work_lam_args)
let { y = I# n; x = (a, b) } in -- reboxing wrapper args (work_fn_str)
case <fn_rhs> x y of -- call to the original RHS (call_rhs)
MkT i b c -> (# i, b, c #) -- return CPR transit vars (work_fn_cpr)NB: The wrap_rhs hole is to be filled with the original wrapper RHS
x y -> E. This is so that we can also use w to transform stable
unfoldings, the lambda args of which may be different than x and y.
- Id details for the worker function like demands on arguments and its join arity.
All without looking at E (except for beta reduction, see Note [Join points and beta-redexes]), which allows us to apply the same split to function body and its unfolding(s) alike.
mkWWstr :: WwOpts -> [Var] -> [StrictnessMark] -> UniqSM (WwUse, [(Var, StrictnessMark)], CoreExpr -> CoreExpr, [CoreExpr]) Source #
mkWWstr_one :: WwOpts -> Var -> StrictnessMark -> UniqSM (WwUse, [(Var, StrictnessMark)], CoreExpr -> CoreExpr, CoreExpr) Source #
needsVoidWorkerArg :: Id -> [Var] -> [Var] -> Bool Source #
Whether the worker needs an additional `Void#` arg as per Note [Protecting the last value argument] or Note [Preserving float barriers].
data DataConPatContext s Source #
The information needed to build a pattern for a DataCon to be unboxed.
The pattern can be generated from dcpc_dc and dcpc_tc_args via
dataConRepInstPat. The coercion dcpc_co is for newtype
wrappers.
If we get DataConPatContext dc tys co for some type ty
and dataConRepInstPat ... dc tys = (exs, flds), then
dcexs flds :: T tys@co :: T tys ~ ty
Constructors
| DataConPatContext | |
data UnboxingDecision unboxing_info Source #
Describes the outer shape of an argument to be unboxed or left as-is
Depending on how s is instantiated (e.g., Demand or Cpr).
Constructors
| DontUnbox | We ran out of strictness info. Leave untouched. |
| DoUnbox !unboxing_info | The argument is used strictly or the returned product was constructed, so unbox it. |
| DropAbsent | The argument/field was absent. Drop it. |
Instances
| Outputable i => Outputable (UnboxingDecision i) Source # | |
Defined in GHC.Core.Opt.WorkWrap.Utils Methods ppr :: UnboxingDecision i -> SDoc # | |
Arguments
| :: FamInstEnvs | |
| -> Type | Type of the argument |
| -> Demand | How the arg was used |
| -> UnboxingDecision (DataConPatContext Demand) |
Unwraps the Boxity decision encoded in the given SubDemand and returns
a DataConPatContext as well the nested demands on fields of the DataCon
to unbox.
findTypeShape :: FamInstEnvs -> Type -> TypeShape Source #
data IsRecDataConResult Source #
Returned by isRecDataCon.
See also Note [Detecting recursive data constructors].
Constructors
| DefinitelyRecursive | The algorithm detected a loop |
| NonRecursiveOrUnsure | The algorithm detected no loop, went out of fuel or hit an .hs-boot file |
Instances
| Show IsRecDataConResult Source # | |
Defined in GHC.Core.Opt.WorkWrap.Utils Methods showsPrec :: Int -> IsRecDataConResult -> ShowS # show :: IsRecDataConResult -> String # showList :: [IsRecDataConResult] -> ShowS # | |
| Outputable IsRecDataConResult Source # | |
Defined in GHC.Core.Opt.WorkWrap.Utils Methods ppr :: IsRecDataConResult -> SDoc # | |
| Eq IsRecDataConResult Source # | |
Defined in GHC.Core.Opt.WorkWrap.Utils Methods (==) :: IsRecDataConResult -> IsRecDataConResult -> Bool # (/=) :: IsRecDataConResult -> IsRecDataConResult -> Bool # | |
isRecDataCon :: FamInstEnvs -> IntWithInf -> DataCon -> IsRecDataConResult Source #
isRecDataCon _ fuel dc, where tc = dataConTyCon dc returns
DefinitelyRecursiveif the analysis found thattcis reachable through one ofdc'sarg_tys.NonRecursiveOrUnsureif the analysis found thattcis not reachable through one ofdc's fields (so surely non-recursive).NonRecursiveOrUnsurewhenfuel /= Infinityandfuelexpansions of nested data TyCons were not enough to prove non-recursiveness, nor arrive at an occurrence oftcthus proving recursiveness. (So not sure if non-recursive.)NonRecursiveOrUnsurewhen we hit an abstract TyCon (one without visible DataCons), such as those imported from .hs-boot files. Similarly for stuck type and data families.
If fuel = and there are no boot files involved, then the result
is never InfinityNothing and the analysis is a depth-first search. If fuel = , then the analysis behaves like a depth-limited DFS and returns Int
fNothing
if the search was inconclusive.
See Note [Detecting recursive data constructors] for which recursive DataCons we want to flag.
mkAbsentFiller :: WwOpts -> Id -> StrictnessMark -> Maybe CoreExpr Source #
Tries to find a suitable absent filler to bind the given absent identifier to. See Note [Absent fillers].
If mkAbsentFiller _ id == Just e, then e is an absent filler with the
same type as id. Otherwise, no suitable filler could be found.
dubiousDataConInstArgTys :: DataCon -> [Type] -> [Type] Source #
Exactly dataConInstArgTys, but lacks the (ASSERT'ed) precondition that
the DataCon may not have existentials. The lack of cloning the
existentials this function "dubious"; only use it where type variables
aren't substituted for! Why may the data con bind existentials?
See Note [Which types are unboxed?]
boringSplit :: WwUse Source #
WW split not profitable
usefulSplit :: WwUse Source #
WW split profitable