summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Peyton Jones <simonpj@microsoft.com>2013-12-11 18:30:54 +0000
committerJoachim Breitner <mail@joachim-breitner.de>2013-12-12 11:26:58 +0000
commitba78bf1772c9d695a0ded932eeceed10622d91a4 (patch)
tree0d49084ecec0f2938348a57c3758fc86c9489af6
parent838da6fc74266cf6e561d6ba0cb1c8bd052b4efc (diff)
downloadhaskell-ba78bf1772c9d695a0ded932eeceed10622d91a4.tar.gz
Do not split void functions
This is authored by SPJ, and split out out "Improve the handling of used-once stuff" by Joachim.
-rw-r--r--compiler/stranal/WorkWrap.lhs22
1 files changed, 20 insertions, 2 deletions
diff --git a/compiler/stranal/WorkWrap.lhs b/compiler/stranal/WorkWrap.lhs
index b66a449119..14a01d5097 100644
--- a/compiler/stranal/WorkWrap.lhs
+++ b/compiler/stranal/WorkWrap.lhs
@@ -17,6 +17,7 @@ import CoreSyn
import CoreUnfold ( certainlyWillInline, mkInlineUnfolding, mkWwInlineRule )
import CoreUtils ( exprType, exprIsHNF )
import CoreArity ( exprArity )
+import Type ( isVoidTy )
import Var
import Id
import IdInfo
@@ -256,7 +257,7 @@ tryWW dflags is_rec fn_id rhs
-- Furthermore, don't even expose strictness info
= return [ (fn_id, rhs) ]
- | is_fun && (any worthSplittingArgDmd wrap_dmds || returnsCPR res_info)
+ | is_fun && (worth_splitting_args wrap_dmds rhs || returnsCPR res_info)
= checkSize dflags new_fn_id rhs $
splitFun dflags new_fn_id fn_info wrap_dmds res_info rhs
@@ -274,7 +275,13 @@ tryWW dflags is_rec fn_id rhs
fn_dmd = demandInfo fn_info
inline_act = inlinePragmaActivation (inlinePragInfo fn_info)
- -- In practice it always will have a strictness
+ worth_splitting_args [d] (Lam b _)
+ | isAbsDmd d && isVoidTy (idType b)
+ = False -- Note [Do not split void functions]
+ worth_splitting_args wrap_dmds _
+ = any worthSplittingArgDmd wrap_dmds
+
+ -- 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
@@ -394,6 +401,17 @@ noOneShotInfo :: [Bool]
noOneShotInfo = repeat False
\end{code}
+Note [Do not split void functions]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Consider this rather common form of binding:
+ $j = \x:Void# -> ...no use of x...
+
+Since x is not used it'll be marked as absent. But there is no point
+in w/w-ing because we'll simply add (\y:Void#), see WwLib.mkWorerArgs.
+
+If x has a more interesting type (eg Int, or Int#), there *is* a point
+in w/w so that we don't pass the argument at all.
+
Note [Thunk splitting]
~~~~~~~~~~~~~~~~~~~~~~
Suppose x is used strictly (never mind whether it has the CPR