[commit: ghc] wip/cbv-conv-thunk: Try to make "<S>t" meaningful (b794662)

git at git.haskell.org git at git.haskell.org
Thu Jan 9 18:35:32 UTC 2014


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

On branch  : wip/cbv-conv-thunk
Link       : http://ghc.haskell.org/trac/ghc/changeset/b794662db02949b45e0a16d49e53e0b03985118b/ghc

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

commit b794662db02949b45e0a16d49e53e0b03985118b
Author: Joachim Breitner <mail at joachim-breitner.de>
Date:   Thu Jan 9 10:37:29 2014 +0000

    Try to make "<S>t" meaningful
    
    by giving it the meaning: "Assuming my first argument is terminating,
    then I am terminating".
    
    In pictures: This is the lattice, which is not a simple product lattice any more:
    
           ------ <L><L>------
         /          | \       \
        /           | <L><L>t  \
    <S><L>          |           <S><L>
     |  \ \         |           |  |  \
     |   \ <S><L>t  |          /   |   <S><L>t
     |    \         |         /    |
     \     \        |        /     |
      \     ----- <S><S>-----      |
       \           |    \          |
        \          |     <S><S>t   /
         \         |              /
          ---------⊥-------------/
    
    This means that we need to be careful when lub’ing: If one branch is lazy, but
    not absent in an argument or free variable, and the other branch is strict,
    then even if both branches claim to terminate, we need to remove the
    termination flag (as one had the termination under a stronger hypothesis as the
    hole result) (Feels inelegant.)
    
    There is no unit for lubDmdType any more. So for case, use we use botDmdType
    for no alternatives, and foldr1 if there are multiple.
    
    Unlifted variables (e.g. Int#) are tricky. Everything is strict in them, so for
    an *unlifted* argument, <L>t implies <S>t and hence <S>t ⊔ <L>t = <S>t, and we
    really want to make use of that stronger equation. But when lub’ing, we don’t
    know any more if this is the demand for an unlifted type. So instead, the
    demand type of x :: Int# itself is {x ↦ <L>} t, while x :: Int continues to
    have type {x ↦ <S>} t.
    
    It is important that functions (including primitive operations and constructors
    like I#) have a strict demand on their unlifted argument. But it turned out to
    be easier to enforce this in the demand analyser: So even if f claims to have a
    lazy demand on a argument of unlifted type, we make this demand strict before
    feeding it into the argument.


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

b794662db02949b45e0a16d49e53e0b03985118b
 compiler/basicTypes/Demand.lhs  |   61 +++++++++++++++++++++++++++++++--------
 compiler/prelude/PrimOp.lhs     |    4 ++-
 compiler/prelude/primops.txt.pp |    1 +
 compiler/stranal/DmdAnal.lhs    |   36 +++++++++++++++++------
 4 files changed, 80 insertions(+), 22 deletions(-)

Diff suppressed because of size. To see it, use:

    git diff-tree --root --patch-with-stat --no-color --find-copies-harder --ignore-space-at-eol --cc b794662db02949b45e0a16d49e53e0b03985118b


More information about the ghc-commits mailing list