X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=compiler%2Fstranal%2FWorkWrap.lhs;h=a1b18a98fb2d00266614aa2016b97e49dbc417cb;hb=2eb04ca0f8d0ec72b417cddc60672c696b4a3daa;hp=d964026756a178f7da9b6d9aaa83bbe2474d270d;hpb=302265d525004c7870864549f7a07a5759d32912;p=ghc-hetmet.git diff --git a/compiler/stranal/WorkWrap.lhs b/compiler/stranal/WorkWrap.lhs index d964026..a1b18a9 100644 --- a/compiler/stranal/WorkWrap.lhs +++ b/compiler/stranal/WorkWrap.lhs @@ -11,11 +11,11 @@ module WorkWrap ( wwTopBinds, mkWrapper ) where import CoreSyn import CoreUnfold ( certainlyWillInline ) import CoreLint ( showPass, endPass ) -import CoreUtils ( exprType, exprIsHNF ) +import CoreUtils ( exprType, exprIsHNF, exprArity ) import Id ( Id, idType, isOneShotLambda, setIdNewStrictness, mkWorkerId, setIdWorkerInfo, setInlinePragma, - idInfo ) + setIdArity, idInfo ) import MkId ( lazyIdKey, lazyIdUnfolding ) import Type ( Type ) import IdInfo ( WorkerInfo(..), arityInfo, @@ -26,7 +26,7 @@ import NewDemand ( Demand(..), StrictSig(..), DmdType(..), DmdResult(..), ) import UniqSupply ( UniqSupply, initUs_, returnUs, thenUs, mapUs, getUniqueUs, UniqSM ) import Unique ( hasKey ) -import BasicTypes ( RecFlag(..), isNonRec, Activation(..) ) +import BasicTypes ( RecFlag(..), isNonRec, isNeverActive ) import VarEnv ( isEmptyVarEnv ) import Maybes ( orElse ) import DynFlags @@ -153,6 +153,10 @@ wwExpr (Note note 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 -> @@ -211,6 +215,11 @@ tryWW is_rec fn_id rhs -- fw = \ab -> (__inline (\x -> E)) (a,b) -- and the original __inline now vanishes, so E is no longer -- inside its __inline wrapper. Death! Disaster! + + || isNeverActive inline_prag + -- No point in worker/wrappering if the thing is never inlined! + -- Because the no-inline prag will prevent the wrapper ever + -- being inlined at a call site. = returnUs [ (new_fn_id, rhs) ] | is_thunk && worthSplittingThunk maybe_fn_dmd res_info @@ -256,14 +265,22 @@ splitFun fn_id fn_info wrap_dmds res_info inline_prag rhs 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 + `setIdArity` (exprArity work_rhs) + -- Set the arity so that the Core Lint check that the + -- arity is consistent with the demand type goes through 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 @@ -308,7 +325,7 @@ splitThunk transforms like this: 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: