summaryrefslogtreecommitdiff
path: root/compiler
diff options
context:
space:
mode:
authorAustin Seipp <austin@well-typed.com>2014-08-20 03:31:18 -0500
committerAustin Seipp <austin@well-typed.com>2014-08-20 03:47:35 -0500
commit236e2ea646a8ebd0d98d04c3908cca26dc5cafe8 (patch)
tree8f34df9578aa8c73ffb8d7442b1dfcdf26477e04 /compiler
parent11f05c538addda0e037c626d75de96a9eb477f94 (diff)
downloadhaskell-236e2ea646a8ebd0d98d04c3908cca26dc5cafe8.tar.gz
stranal: detabify/dewhitespace WorkWrap
Signed-off-by: Austin Seipp <austin@well-typed.com>
Diffstat (limited to 'compiler')
-rw-r--r--compiler/stranal/WorkWrap.lhs163
1 files changed, 78 insertions, 85 deletions
diff --git a/compiler/stranal/WorkWrap.lhs b/compiler/stranal/WorkWrap.lhs
index 5b9d0a3083..4e4b1aee99 100644
--- a/compiler/stranal/WorkWrap.lhs
+++ b/compiler/stranal/WorkWrap.lhs
@@ -5,26 +5,19 @@
\begin{code}
{-# LANGUAGE CPP #-}
-{-# OPTIONS_GHC -fno-warn-tabs #-}
--- The above warning supression flag is a temporary kludge.
--- While working on this module you are encouraged to remove it and
--- detab the module (please do the detabbing in a separate patch). See
--- http://ghc.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#TabsvsSpaces
--- for details
-
module WorkWrap ( wwTopBinds ) where
import CoreSyn
-import CoreUnfold ( certainlyWillInline, mkInlineUnfolding, mkWwInlineRule )
-import CoreUtils ( exprType, exprIsHNF )
-import CoreArity ( exprArity )
+import CoreUnfold ( certainlyWillInline, mkInlineUnfolding, mkWwInlineRule )
+import CoreUtils ( exprType, exprIsHNF )
+import CoreArity ( exprArity )
import Var
import Id
import IdInfo
import UniqSupply
import BasicTypes
import DynFlags
-import VarEnv ( isEmptyVarEnv )
+import VarEnv ( isEmptyVarEnv )
import Demand
import WwLib
import Util
@@ -71,9 +64,9 @@ wwTopBinds dflags fam_envs us top_binds
\end{code}
%************************************************************************
-%* *
+%* *
\subsection[wwBind-wwExpr]{@wwBind@ and @wwExpr@}
-%* *
+%* *
%************************************************************************
@wwBind@ works on a binding, trying each \tr{(binder, expr)} pair in
@@ -83,9 +76,9 @@ turn. Non-recursive case first, then recursive...
wwBind :: DynFlags
-> FamInstEnvs
-> CoreBind
- -> UniqSM [CoreBind] -- returns a WwBinding intermediate form;
- -- the caller will convert to Expr/Binding,
- -- as appropriate.
+ -> UniqSM [CoreBind] -- returns a WwBinding intermediate form;
+ -- the caller will convert to Expr/Binding,
+ -- as appropriate.
wwBind dflags fam_envs (NonRec binder rhs) = do
new_rhs <- wwExpr dflags fam_envs rhs
@@ -141,9 +134,9 @@ wwExpr dflags fam_envs (Case expr binder ty alts) = do
\end{code}
%************************************************************************
-%* *
+%* *
\subsection[tryWW]{@tryWW@: attempt a worker/wrapper pair}
-%* *
+%* *
%************************************************************************
@tryWW@ just accumulates arguments, converts strictness info from the
@@ -219,11 +212,11 @@ late in the pipeline, and we want to prioritise specialisations over
strictness. Eg if we have
module Foo where
f :: Num a => a -> Int -> a
- f n 0 = n -- Strict in the Int, hence wrapper
+ f n 0 = n -- Strict in the Int, hence wrapper
f n x = f (n+n) (x-1)
g :: Int -> Int
- g x = f x x -- Provokes a specialisation for f
+ g x = f x x -- Provokes a specialisation for f
module Bsr where
import Foo
@@ -243,21 +236,21 @@ it appears in the first place in the defining module.
tryWW :: DynFlags
-> FamInstEnvs
-> RecFlag
- -> Id -- The fn binder
- -> CoreExpr -- The bound rhs; its innards
- -- are already ww'd
- -> UniqSM [(Id, CoreExpr)] -- either *one* or *two* pairs;
- -- if one, then no worker (only
- -- the orig "wrapper" lives on);
- -- if two, then a worker and a
- -- wrapper.
+ -> Id -- The fn binder
+ -> CoreExpr -- The bound rhs; its innards
+ -- are already ww'd
+ -> UniqSM [(Id, CoreExpr)] -- either *one* or *two* pairs;
+ -- if one, then no worker (only
+ -- the orig "wrapper" lives on);
+ -- if two, then a worker and a
+ -- wrapper.
tryWW dflags fam_envs is_rec fn_id rhs
| isNeverActive inline_act
- -- 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.
- --
- -- Furthermore, don't even expose strictness info
+ -- 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.
+ --
+ -- Furthermore, don't even expose strictness info
= return [ (fn_id, rhs) ]
| isStableUnfolding (realIdUnfolding fn_id)
@@ -270,9 +263,9 @@ tryWW dflags fam_envs is_rec fn_id rhs
| certainlyWillInline dflags (idUnfolding fn_id)
= let inline_rule = mkInlineUnfolding Nothing rhs
in return [ (fn_id `setIdUnfolding` inline_rule, rhs) ]
- -- Note [Don't w/w inline small non-loop-breaker things]
- -- NB: use idUnfolding because we don't want to apply
- -- this criterion to a loop breaker!
+ -- Note [Don't w/w inline small non-loop-breaker things]
+ -- NB: use idUnfolding because we don't want to apply
+ -- this criterion to a loop breaker!
| is_fun
= splitFun dflags fam_envs new_fn_id fn_info wrap_dmds res_info rhs
@@ -284,19 +277,19 @@ tryWW dflags fam_envs is_rec fn_id rhs
= return [ (new_fn_id, rhs) ]
where
- fn_info = idInfo fn_id
+ fn_info = idInfo fn_id
inline_act = inlinePragmaActivation (inlinePragInfo fn_info)
- -- In practice it always will have a strictness
- -- signature, even if it's a uninformative one
+ -- In practice it always will have a strictness
+ -- signature, even if it's a uninformative one
strict_sig = strictnessInfo fn_info
StrictSig (DmdType env wrap_dmds res_info) = strict_sig
- -- new_fn_id has the DmdEnv zapped.
- -- (a) it is never used again
- -- (b) it wastes space
- -- (c) it becomes incorrect as things are cloned, because
- -- we don't push the substitution into it
+ -- new_fn_id has the DmdEnv zapped.
+ -- (a) it is never used again
+ -- (b) it wastes space
+ -- (c) it becomes incorrect as things are cloned, because
+ -- we don't push the substitution into it
new_fn_id | isEmptyVarEnv env = fn_id
| otherwise = fn_id `setIdStrictness`
mkClosedStrictSig wrap_dmds res_info
@@ -316,45 +309,45 @@ splitFun dflags fam_envs fn_id fn_info wrap_dmds res_info rhs
Just (work_demands, wrap_fn, work_fn) -> do
work_uniq <- getUniqueM
let work_rhs = work_fn rhs
- work_id = mkWorkerId work_uniq fn_id (exprType work_rhs)
- `setIdOccInfo` occInfo fn_info
- -- Copy over occurrence info from parent
- -- Notably whether it's a loop breaker
- -- Doesn't matter much, since we will simplify next, but
- -- seems right-er to do so
-
- `setInlineActivation` (inlinePragmaActivation inl_prag)
- -- Any inline activation (which sets when inlining is active)
- -- on the original function is duplicated on the worker
- -- 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). However, the RuleMatchInfo is not transferred since
+ work_id = mkWorkerId work_uniq fn_id (exprType work_rhs)
+ `setIdOccInfo` occInfo fn_info
+ -- Copy over occurrence info from parent
+ -- Notably whether it's a loop breaker
+ -- Doesn't matter much, since we will simplify next, but
+ -- seems right-er to do so
+
+ `setInlineActivation` (inlinePragmaActivation inl_prag)
+ -- Any inline activation (which sets when inlining is active)
+ -- on the original function is duplicated on the worker
+ -- 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). However, the RuleMatchInfo is not transferred since
-- it does not make sense for workers to be constructorlike.
- `setIdStrictness` mkClosedStrictSig work_demands work_res_info
- -- Even though we may not be at top level,
- -- it's ok to give it an empty DmdEnv
+ `setIdStrictness` mkClosedStrictSig 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_prag = InlinePragma { inl_inline = Inline
+ wrap_rhs = wrap_fn work_id
+ wrap_prag = InlinePragma { inl_inline = Inline
, inl_sat = Nothing
, inl_act = ActiveAfter 0
, inl_rule = rule_match_info }
- -- See Note [Wrapper activation]
- -- The RuleMatchInfo is (and must be) unaffected
- -- The inl_inline is bound to be False, else we would not be
- -- making a wrapper
+ -- See Note [Wrapper activation]
+ -- The RuleMatchInfo is (and must be) unaffected
+ -- The inl_inline is bound to be False, else we would not be
+ -- making a wrapper
wrap_id = fn_id `setIdUnfolding` mkWwInlineRule wrap_rhs arity
- `setInlinePragma` wrap_prag
- `setIdOccInfo` NoOccInfo
- -- Zap any loop-breaker-ness, to avoid bleating from Lint
- -- about a loop breaker with an INLINE rule
+ `setInlinePragma` wrap_prag
+ `setIdOccInfo` NoOccInfo
+ -- Zap any loop-breaker-ness, to avoid bleating from Lint
+ -- about a loop breaker with an INLINE rule
return $ [(work_id, work_rhs), (wrap_id, wrap_rhs)]
-- Worker first, because wrapper mentions it
-- mkWwBodies has already built a wrap_rhs with an INLINE pragma wrapped around it
@@ -365,11 +358,11 @@ splitFun dflags fam_envs fn_id fn_info wrap_dmds res_info rhs
inl_prag = inlinePragInfo fn_info
rule_match_info = inlinePragmaRuleMatchInfo inl_prag
arity = arityInfo fn_info
- -- The arity is set by the simplifier using exprEtaExpandArity
- -- So it may be more than the number of top-level-visible lambdas
+ -- The arity is set by the simplifier using exprEtaExpandArity
+ -- So it may be more than the number of top-level-visible lambdas
- work_res_info | isBotRes res_info = botRes -- Cpr stuff done by wrapper
- | otherwise = topRes
+ work_res_info | isBotRes res_info = botRes -- Cpr stuff done by wrapper
+ | otherwise = topRes
one_shots = get_one_shots rhs
@@ -382,7 +375,7 @@ get_one_shots (Lam b e)
| isId b = idOneShotInfo b : get_one_shots e
| otherwise = get_one_shots e
get_one_shots (Tick _ e) = get_one_shots e
-get_one_shots _ = []
+get_one_shots _ = []
\end{code}
Note [Do not split void functions]
@@ -402,24 +395,24 @@ Suppose x is used strictly (never mind whether it has the CPR
property).
let
- x* = x-rhs
+ x* = x-rhs
in body
splitThunk transforms like this:
let
- x* = case x-rhs of { I# a -> I# a }
+ x* = case x-rhs of { I# a -> I# a }
in body
Now simplifier will transform to
case x-rhs of
- I# a -> let x* = I# a
- in body
+ I# a -> let x* = I# a
+ in body
which is what we want. Now suppose x-rhs is itself a case:
- x-rhs = case e of { T -> I# a; F -> I# b }
+ x-rhs = case e of { T -> I# a; F -> I# b }
The join point will abstract over a, rather than over (which is
what would have happened before) which is fine.
@@ -433,11 +426,11 @@ then the splitting will go deeper too.
\begin{code}
-- See Note [Thunk splitting]
-- splitThunk converts the *non-recursive* binding
--- x = e
+-- x = e
-- into
--- x = let x = e
--- in case x of
--- I# y -> let x = I# y in x }
+-- x = let x = e
+-- in case x of
+-- I# y -> let x = I# y in x }
-- See comments above. Is it not beautifully short?
-- Moreover, it works just as well when there are
-- several binders, and if the binders are lifted