diff options
author | simonpj@microsoft.com <unknown> | 2009-12-11 16:19:28 +0000 |
---|---|---|
committer | simonpj@microsoft.com <unknown> | 2009-12-11 16:19:28 +0000 |
commit | b84ba676034763b3082bbd9405794a4fde499d14 (patch) | |
tree | 6d6d15917e0c6946ec318640e4b0e5d5a00ac4fd /compiler/iface | |
parent | 015d3d46b6de2f95386a515a7d166d996a0416db (diff) | |
download | haskell-b84ba676034763b3082bbd9405794a4fde499d14.tar.gz |
Bottom extraction: float out bottoming expressions to top level
The idea is to float out bottoming expressions to top level,
abstracting them over any variables they mention, if necessary. This
is good because it makes functions smaller (and more likely to
inline), by keeping error code out of line.
See Note [Bottoming floats] in SetLevels.
On the way, this fixes the HPC failures for cg059 and friends.
I've been meaning to do this for some time. See Maessen's paper 1999
"Bottom extraction: factoring error handling out of functional
programs" (unpublished I think).
Here are the nofib results:
Program Size Allocs Runtime Elapsed
--------------------------------------------------------------------------------
Min +0.1% -7.8% -14.4% -32.5%
Max +0.5% +0.2% +1.6% +13.8%
Geometric Mean +0.4% -0.2% -4.9% -6.7%
Module sizes
-1 s.d. ----- -2.6%
+1 s.d. ----- +2.3%
Average ----- -0.2%
Compile times:
-1 s.d. ----- -11.4%
+1 s.d. ----- +4.3%
Average ----- -3.8%
I'm think program sizes have crept up because the base library
is bigger -- module sizes in nofib decrease very slightly. In turn
I think that may be because the floating generates a call where
there was no call before. Anyway I think it's acceptable.
The main changes are:
* SetLevels floats out things that exprBotStrictness_maybe
identifies as bottom. Make sure to pin on the right
strictness info to the newly created Ids, so that the
info ends up in interface files.
Since FloatOut is run twice, we have to be careful that we
don't treat the function created by the first float-out as
a candidate for the second; this is what worthFloating does.
See SetLevels Note [Bottoming floats]
Note [Bottoming floats: eta expansion]
* Be careful not to inline top-level bottoming functions; this
would just undo what the floating transformation achieves.
See CoreUnfold Note [Do not inline top-level bottoming functions
Ensuring this requires a bit of extra plumbing, but nothing drastic..
* Similarly pre/postInlineUnconditionally should be
careful not to re-inline top-level bottoming things!
See SimplUtils Note [Top-level botomming Ids]
Note [Top level and postInlineUnconditionally]
Diffstat (limited to 'compiler/iface')
-rw-r--r-- | compiler/iface/MkIface.lhs | 2 | ||||
-rw-r--r-- | compiler/iface/TcIface.lhs | 14 |
2 files changed, 12 insertions, 4 deletions
diff --git a/compiler/iface/MkIface.lhs b/compiler/iface/MkIface.lhs index 897c138406..1c34edca3c 100644 --- a/compiler/iface/MkIface.lhs +++ b/compiler/iface/MkIface.lhs @@ -1472,6 +1472,8 @@ toIfaceIdInfo :: IdInfo -> [IfaceInfoItem] toIfaceIdInfo id_info = catMaybes [arity_hsinfo, caf_hsinfo, strict_hsinfo, inline_hsinfo, unfold_hsinfo] + -- NB: strictness must be before unfolding + -- See TcIface.tcUnfolding where ------------ Arity -------------- arity_info = arityInfo id_info diff --git a/compiler/iface/TcIface.lhs b/compiler/iface/TcIface.lhs index 2ec9de97a0..c9c33dbde6 100644 --- a/compiler/iface/TcIface.lhs +++ b/compiler/iface/TcIface.lhs @@ -46,6 +46,7 @@ import VarEnv import Name import NameEnv import OccurAnal ( occurAnalyseExpr ) +import Demand ( isBottomingSig ) import Module import LazyUniqFM import UniqSupply @@ -1003,11 +1004,16 @@ tcIdInfo ignore_prags name ty info \begin{code} tcUnfolding :: Name -> Type -> IdInfo -> IfaceUnfolding -> IfL Unfolding -tcUnfolding name _ _ (IfCoreUnfold if_expr) +tcUnfolding name _ info (IfCoreUnfold if_expr) = do { mb_expr <- tcPragExpr name if_expr ; return (case mb_expr of Nothing -> NoUnfolding - Just expr -> mkTopUnfolding expr) } + Just expr -> mkTopUnfolding is_bottoming expr) } + where + -- Strictness should occur before unfolding! + is_bottoming = case strictnessInfo info of + Just sig -> isBottomingSig sig + Nothing -> False tcUnfolding name _ _ (IfInlineRule arity unsat_ok if_expr) = do { mb_expr <- tcPragExpr name if_expr @@ -1029,8 +1035,8 @@ tcUnfolding name ty info (IfWrapper arity wkr) (initUs_ us (mkWrapper ty strict_sig) wkr_id) arity - -- We are relying here on strictness info always appearing - -- before worker info, fingers crossed .... + -- Again we rely here on strictness info always appearing + -- before unfolding strict_sig = case strictnessInfo info of Just sig -> sig Nothing -> pprPanic "Worker info but no strictness for" (ppr wkr) |