| Safe Haskell | None | 
|---|---|
| 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 Source #  | |
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  | |
| Outputable IsRecDataConResult Source # | |
Defined in GHC.Core.Opt.WorkWrap.Utils Methods ppr :: IsRecDataConResult -> SDoc Source #  | |
| 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