)
import UniqSupply ( UniqSupply, initUs_, returnUs, thenUs, mapUs, getUniqueUs, UniqSM )
import Unique ( hasKey )
-import BasicTypes ( RecFlag(..), isNonRec, Activation(..) )
+import BasicTypes ( RecFlag(..), isNonRec )
import VarEnv ( isEmptyVarEnv )
import Maybes ( orElse )
import DynFlags
wwExpr e@(Var v)
| v `hasKey` lazyIdKey = returnUs lazyIdUnfolding
| otherwise = returnUs e
- -- Inline 'lazy' after strictness analysis
+ -- HACK alert: Inline 'lazy' after strictness analysis
-- (but not inside InlineMe's)
wwExpr (Lam binder expr)
= wwExpr expr `thenUs` \ new_expr ->
returnUs (Note note new_expr)
+wwExpr (Cast expr co)
+ = wwExpr expr `thenUs` \ new_expr ->
+ returnUs (Cast new_expr co)
+
wwExpr (Let bind expr)
= wwBind bind `thenUs` \ intermediate_bind ->
wwExpr expr `thenUs` \ new_expr ->
work_rhs = work_fn rhs
work_id = mkWorkerId work_uniq fn_id (exprType work_rhs)
`setInlinePragma` inline_prag
+ -- Any inline pragma (which sets when inlining is active)
+ -- on the original function is duplicated on the worker and wrapper
+ -- It *matters* that the pragma stays on the wrapper
+ -- It seems sensible to have it on the worker too, although we
+ -- can't think of a compelling reason. (In ptic, INLINE things are
+ -- not w/wd)
`setIdNewStrictness` StrictSig (mkTopDmdType work_demands work_res_info)
-- Even though we may not be at top level,
-- it's ok to give it an empty DmdEnv
wrap_rhs = wrap_fn work_id
wrap_id = fn_id `setIdWorkerInfo` HasWorker work_id arity
- `setInlinePragma` AlwaysActive -- Zap any inline pragma;
- -- Put it on the worker instead
+
in
returnUs ([(work_id, work_rhs), (wrap_id, wrap_rhs)])
-- Worker first, because wrapper mentions it
Now simplifier will transform to
case x-rhs of
- I# a -> let x* = I# b
+ I# a -> let x* = I# a
in body
which is what we want. Now suppose x-rhs is itself a case: