[project @ 2002-04-04 13:15:18 by simonpj]
authorsimonpj <unknown>
Thu, 4 Apr 2002 13:15:19 +0000 (13:15 +0000)
committersimonpj <unknown>
Thu, 4 Apr 2002 13:15:19 +0000 (13:15 +0000)
commitc44e1c41da1657b845dc74fc38974e5bbb68d7cd
tree716993a7d3787153e7f982425a99afe469c353e8
parentec7a80bff8bf33232a1b48b9d814648db8ca5fda
[project @ 2002-04-04 13:15:18 by simonpj]
---------------------------------------
A glorious improvement to CPR analysis
---------------------------------------

Working on the CPR paper, I finally figured out how to
do a decent job of taking account of strictness analyis when doing
CPR analysis.

There are two places we do that:

1.  Usually, on a letrec for a *thunk* we discard any CPR info from
the RHS.  We can't worker/wrapper a thunk.  BUT, if the let is
non-recursive
non-top-level
used strictly
we don't need to discard the CPR info, because the thunk-splitting
transform (WorkWrap.splitThunk) works.  This idea isn't new in this
commit.

2. Arguments to strict functions.  Consider

  fac n m = if n==0 then m
    else fac (n-1) (m*n)

Does it have the CPR property?  Apparently not, because it returns the
accumulating parameter, m.  But the strictness analyser will
discover that fac is strict in m, so it will be passed unboxed to
the worker for fac.  More concretely, here is the worker/wrapper
split that will result from strictness analysis alone:

  fac n m = case n of MkInt n' ->
    case m of MkInt m' ->
    facw n' m'

  facw n' m' = if n' ==# 0#
       then I# m'
       else facw (n' -# 1#) (m' *# n')

Now facw clearly does have the CPR property!  We can take advantage
of this by giving a demanded lambda the CPR property.

To make this work nicely, I've made NewDemandInfo into Maybe Demand
rather than simply Demand, so that we can tell when we are on the
first iteration.  Lots of comments about this in Note [CPR-AND-STRICTNESS].

I don't know how much all this buys us, but it is simple and elegant.
ghc/compiler/basicTypes/Id.lhs
ghc/compiler/basicTypes/IdInfo.lhs
ghc/compiler/stranal/DmdAnal.lhs
ghc/compiler/stranal/WorkWrap.lhs