[commit: ghc] master: Lift an unnecessary assumption in the demand analyser (fix Trac #8329) (9bd3666)

git at git.haskell.org git
Tue Oct 1 11:09:09 UTC 2013


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

On branch  : master
Link       : http://ghc.haskell.org/trac/ghc/changeset/9bd366642f495fe26db261317dd416de1ff854bc/ghc

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

commit 9bd366642f495fe26db261317dd416de1ff854bc
Author: Simon Peyton Jones <simonpj at microsoft.com>
Date:   Tue Oct 1 09:27:53 2013 +0100

    Lift an unnecessary assumption in the demand analyser (fix Trac #8329)
    
    Here's the Note about the (simple) fix.  Apparently #8329 prevented all
    23 packages of the Snap framework from compiling.
    
    Note [Demand transformer for a ditionary selector]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    If we evaluate (op dict-expr) under demand 'd', then we can push the demand 'd'
    into the appropriate field of the dictionary. What *is* the appropriate field?
    We just look at the strictness signature of the class op, which will be
    something like: U(AAASAAAAA).  Then replace the 'S' by the demand 'd'.
    
    For single-method classes, which are represented by newtypes the signature
    of 'op' won't look like U(...), so the splitProdDmd_maybe will fail.
    That's fine: if we are doing strictness analysis we are also doing inling,
    so we'll have inlined 'op' into a cast.  So we can bale out in a conservative
    way, returning topDmdType.
    
    It is (just.. Trac #8329) possible to be running strictness analysis *without*
    having inlined class ops from single-method classes.  Suppose you are using
    ghc --make; and the first module has a local -O0 flag.  So you may load a class
    without interface pragmas, ie (currently) without an unfolding for the class
    ops.   Now if a subsequent module in the --make sweep has a local -O flag
    you might do strictness analysis, but there is no inlining for the class op.
    This is wierd so I'm not worried about whether this optimises brilliantly; but
    it should not fall over.


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

9bd366642f495fe26db261317dd416de1ff854bc
 compiler/basicTypes/Demand.lhs |   41 ++++++++++++++++++++++++++++++++--------
 1 file changed, 33 insertions(+), 8 deletions(-)

diff --git a/compiler/basicTypes/Demand.lhs b/compiler/basicTypes/Demand.lhs
index ee4527e..516dbb8 100644
--- a/compiler/basicTypes/Demand.lhs
+++ b/compiler/basicTypes/Demand.lhs
@@ -1316,17 +1316,42 @@ dmdTransformDictSelSig :: StrictSig -> CleanDemand -> DmdType
 -- for dictionary selectors.  If the selector is saturated (ie has one
 -- argument: the dictionary), we feed the demand on the result into
 -- the indicated dictionary component.
-dmdTransformDictSelSig (StrictSig (DmdType _ [dictJd] _)) cd
-  = case peelCallDmd cd of
-      (cd',False,_) -> case splitProdDmd_maybe dictJd of
-        Just jds -> DmdType emptyDmdEnv [mkManyUsedDmd $ mkProdDmd $ map enhance jds] topRes
-          where enhance old | isAbsDmd old = old
-                            | otherwise    = mkManyUsedDmd cd'
-        Nothing   -> panic "dmdTransformDictSelSig: split failed"
-      _ -> topDmdType
+dmdTransformDictSelSig (StrictSig (DmdType _ [dict_dmd] _)) cd
+   | (cd',defer,_) <- peelCallDmd cd
+   , not defer
+   , Just jds <- splitProdDmd_maybe dict_dmd
+   = DmdType emptyDmdEnv [mkManyUsedDmd $ mkProdDmd $ map (enhance cd') jds] topRes
+   | otherwise
+   = topDmdType              -- See Note [Demand transformer for a ditionary selector]
+  where
+    enhance cd old | isAbsDmd old = old
+                   | otherwise    = mkManyUsedDmd cd
+
 dmdTransformDictSelSig _ _ = panic "dmdTransformDictSelSig: no args"
 \end{code}
 
+Note [Demand transformer for a ditionary selector]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+If we evaluate (op dict-expr) under demand 'd', then we can push the demand 'd'
+into the appropriate field of the dictionary. What *is* the appropriate field?
+We just look at the strictness signature of the class op, which will be
+something like: U(AAASAAAAA).  Then replace the 'S' by the demand 'd'.
+
+For single-method classes, which are represented by newtypes the signature 
+of 'op' won't look like U(...), so the splitProdDmd_maybe will fail.
+That's fine: if we are doing strictness analysis we are also doing inling,
+so we'll have inlined 'op' into a cast.  So we can bale out in a conservative
+way, returning topDmdType.
+
+It is (just.. Trac #8329) possible to be running strictness analysis *without*
+having inlined class ops from single-method classes.  Suppose you are using
+ghc --make; and the first module has a local -O0 flag.  So you may load a class
+without interface pragmas, ie (currently) without an unfolding for the class
+ops.   Now if a subsequent module in the --make sweep has a local -O flag
+you might do strictness analysis, but there is no inlining for the class op.
+This is wierd so I'm not worried about whether this optimises brilliantly; but
+it should not fall over.
+
 Note [Non-full application] 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
 If a function having bottom as its demand result is applied to a less




More information about the ghc-commits mailing list