- strictness_info = getIdStrictness fn_id
- has_strictness_info = case strictness_info of
- StrictnessInfo _ _ -> True
- other -> False
-
- wrap_args_info = case strictness_info of
- StrictnessInfo args_info _ -> args_info
- revised_wrap_args_info = setUnpackStrategy wrap_args_info
-
--- This rather (nay! extremely!) crude function looks at a wrapper function, and
--- snaffles out (a) the worker Id and (b) constructors needed to
--- make the wrapper.
--- These are needed when we write an interface file.
-getWorkerIdAndCons wrap_id wrapper_fn
- = go wrapper_fn
+ fun_ty = idType fn_id
+ arity = exprEtaExpandArity rhs
+
+ -- Don't split something which is marked unconditionally NOINLINE
+ inline_prag = idInlinePragma fn_id
+
+ strictness_info = idStrictness fn_id
+ has_strictness = case strictness_info of
+ StrictnessInfo _ _ -> True
+ NoStrictnessInfo -> False
+ (arg_demands, result_bot) = case strictness_info of
+ StrictnessInfo d r -> (d, r)
+ NoStrictnessInfo -> ([], False)
+
+ wrap_dmds = setUnpackStrategy arg_demands
+ do_strict_ww = WARN( has_strictness && not result_bot && arity < length arg_demands && worthSplitting wrap_dmds result_bot,
+ text "Insufficient arity" <+> ppr fn_id <+> ppr arity <+> ppr arg_demands )
+ (result_bot || arity >= length arg_demands) -- Only if there's enough visible arity
+ && -- (else strictness info isn't valid)
+ --
+ worthSplitting wrap_dmds result_bot -- And it's useful
+ -- worthSplitting returns False for an empty list of demands,
+ -- and hence do_strict_ww is False if arity is zero
+ -- Also it's false if there is no strictness (arg_demands is [])
+
+ wrapper_strictness | has_strictness = mkStrictnessInfo (wrap_dmds, result_bot)
+ | otherwise = noStrictnessInfo
+
+ -------------------------------------------------------------
+ cpr_info = idCprInfo fn_id
+ do_cpr_ww = arity > 0 &&
+ case cpr_info of
+ ReturnsCPR -> True
+ other -> False
+
+ -------------------------------------------------------------
+ do_coerce_ww = check_for_coerce arity fun_ty
+ -- We are willing to do a w/w even if the arity is zero.
+ -- x = coerce t E
+ -- ==>
+ -- x' = E
+ -- x = coerce t x'
+
+ -------------------------------------------------------------
+ one_shots = get_one_shots rhs
+
+-- See if there's a Coerce before we run out of arity;
+-- if so, it's worth trying a w/w split. Reason: we find
+-- functions like f = coerce (\s -> e)
+-- and g = \x -> coerce (\s -> e)
+-- and they may have no useful strictness or cpr info, but if we
+-- do the w/w thing we get rid of the coerces.
+
+check_for_coerce arity ty
+ = length arg_tys <= arity && isNewType res_ty
+ -- Don't look further than arity args,
+ -- but if there are arity or fewer, see if there's
+ -- a newtype in the corner