[commit: ghc] wip/T8598: Do not forget CPR information after an IO action (5c690b4)

git at git.haskell.org git at git.haskell.org
Mon Dec 9 14:52:55 UTC 2013


Repository : ssh://git@git.haskell.org/ghc

On branch  : wip/T8598
Link       : http://ghc.haskell.org/trac/ghc/changeset/5c690b4de0aea8e9416403bb615c7519f7e2504e/ghc

>---------------------------------------------------------------

commit 5c690b4de0aea8e9416403bb615c7519f7e2504e
Author: Joachim Breitner <mail at joachim-breitner.de>
Date:   Fri Dec 6 17:58:29 2013 +0000

    Do not forget CPR information after an IO action
    
    but do forget about certain divergence, if required. Fixes one part of
    ticket #8598.
    
    The added function (deferAfterIO) can maybe be merged with existing
    code, but given the ongoing work in the nested-cpr branch, I defer that
    work.


>---------------------------------------------------------------

5c690b4de0aea8e9416403bb615c7519f7e2504e
 compiler/basicTypes/Demand.lhs |   19 ++++++++++++++++++-
 compiler/stranal/DmdAnal.lhs   |    2 +-
 2 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/compiler/basicTypes/Demand.lhs b/compiler/basicTypes/Demand.lhs
index cd844a1..ff6c59f 100644
--- a/compiler/basicTypes/Demand.lhs
+++ b/compiler/basicTypes/Demand.lhs
@@ -35,7 +35,7 @@ module Demand (
 
         evalDmd, cleanEvalDmd, cleanEvalProdDmd, isStrictDmd, 
         splitDmdTy, splitFVs,
-        deferDmd, deferType, deferAndUse, deferEnv, modifyEnv,
+        deferDmd, deferType, deferAndUse, deferAfterIO, deferEnv, modifyEnv,
 
         splitProdDmd, splitProdDmd_maybe, peelCallDmd, mkCallDmd,
         dmdTransformSig, dmdTransformDataConSig, dmdTransformDictSelSig,
@@ -1086,6 +1086,23 @@ useType (DmdType fv ds res_ty) = DmdType (useEnv fv) ds res_ty
 useEnv :: DmdEnv -> DmdEnv
 useEnv fv = mapVarEnv useDmd fv
 
+-- When e is evaluated after executing an IO action, and d is e's demand, then
+-- what of this demand should we consider, given that the IO action can cleanly
+-- exit?
+-- * We have to kill all strictness demands (i.e. lub with a lazy demand)
+-- * We can keep demand information (i.e. lub with an absent deman)
+-- * We have to kill definite divergence
+-- * We can keep CPR information.
+-- See Note [IO hack in the demand analyser]
+deferAfterIO :: DmdType -> DmdType
+deferAfterIO d@(DmdType _ _ res) =
+    case d `lubDmdType` topDmdType of
+        DmdType fv ds _ -> DmdType fv ds (defer_res res)
+  where
+  defer_res BotCPR  = NoCPR
+  defer_res r       = r
+
+
 modifyEnv :: Bool                       -- No-op if False
           -> (Demand -> Demand)         -- The zapper
           -> DmdEnv -> DmdEnv           -- Env1 and Env2
diff --git a/compiler/stranal/DmdAnal.lhs b/compiler/stranal/DmdAnal.lhs
index 99eb7ac..5e0453ca8 100644
--- a/compiler/stranal/DmdAnal.lhs
+++ b/compiler/stranal/DmdAnal.lhs
@@ -332,7 +332,7 @@ dmdAnalAlt env dmd (con,bndrs,rhs)
 	(rhs_ty, rhs')   = dmdAnal env dmd rhs
         rhs_ty'          = addDataConPatDmds con bndrs rhs_ty
 	(alt_ty, bndrs') = annotateBndrs env rhs_ty' bndrs
-	final_alt_ty | io_hack_reqd = alt_ty `lubDmdType` topDmdType
+	final_alt_ty | io_hack_reqd = deferAfterIO alt_ty
 		     | otherwise    = alt_ty
 
 	-- There's a hack here for I/O operations.  Consider



More information about the ghc-commits mailing list