- strictness_info = getIdStrictness fn_id
- has_strictness_info = case strictness_info of
- StrictnessInfo _ _ -> True
- other -> False
-
- StrictnessInfo wrap_args_info result_bot = strictness_info
-
- revised_wrap_args_info = if has_strictness_info
- then setUnpackStrategy wrap_args_info
- else repeat wwLazy
-
- do_strict_ww = has_strictness_info && worthSplitting revised_wrap_args_info result_bot
-
- cpr_info = getIdCprInfo fn_id
- has_cpr_info = case cpr_info of
- CPRInfo _ -> True
- other -> False
-
- do_cpr_ww = has_cpr_info
- unfold_guidance = calcUnfoldingGuidance opt_UF_CreationThreshold rhs
-
--- This rather (nay! extremely!) crude function looks at a wrapper function, and
--- snaffles out the worker Id from the wrapper.
--- This is needed when we write an interface file.
--- [May 1999: we used to get the constructors too, but that's no longer
--- necessary, because the renamer hauls in all type decls in
--- their fullness.]
-
--- <Mar 1999 (keving)> - Well, since the addition of the CPR transformation this function
--- got too crude!
--- Now the worker id is stored directly in the id's Info field. We still use this function to
--- snaffle the wrapper's constructors but I don't trust the code to find the worker id.
-getWorkerId :: Id -> CoreExpr -> Id
-getWorkerId wrap_id wrapper_fn
- = work_id wrapper_fn
+ fun_ty = idType fn_id
+ arity = idArity fn_id -- The arity is set by the simplifier using exprEtaExpandArity
+ -- So it may be more than the number of top-level-visible lambdas
+
+ 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