[GHC] #1600: Optimisation: CPR the results of IO

GHC ghc-devs at haskell.org
Tue Nov 26 09:58:51 UTC 2013


#1600: Optimisation: CPR the results of IO
-------------------------------------+-------------------------------------
        Reporter:  simonmar          |            Owner:
            Type:  task              |           Status:  new
        Priority:  lowest            |        Milestone:  7.6.2
       Component:  Compiler          |          Version:  6.6.1
      Resolution:                    |         Keywords:
Operating System:  Unknown/Multiple  |     Architecture:  Unknown/Multiple
 Type of failure:  Runtime           |       Difficulty:  Moderate (less
  performance bug                    |  than a day)
       Test Case:                    |       Blocked By:
        Blocking:                    |  Related Tickets:
-------------------------------------+-------------------------------------

Comment (by nomeata):

 Analysing the `typecheck` divergence yields a very interesting example of
 how nested CPR can go wrong, which I’d like to document here.

 It completely wreak havoc with this innocent function:
 {{{
 repeat :: x -> [x]
 repeat x = x : repeat x
 }}}
 (This requires nesting of sum types, but just imagine for this example
 that `[]` was a stream data type with only one constructor, if you want).

 The analyizer figurs out that its demand signature is `DmdType
 <L,U>tm2(d,tm2(d,tm2(d,d)))`, i.e. it lazily uses its argument and will,
 with guaranteed convergence, produce a `:` constructor, and evaluating the
 second parameter thereof will also converge to a `:`, and so on. The
 signature could actually be infinite; my code cuts them off a a certain
 depth. This signature is certainly correct.

 So it seems this is eligible to a worker-wrapper-transformation. But when
 we do it we end up with (using non-core patterns for clarity):
 {{{
 $wrepeat :: x -> (# a, a, a, [a] #)
 $wrepeat x = case x : repeat x of (x1:x2:x3:r) -> (# x1, x2, x3, r#)

 repeat x :: -> [x]
 repeat x = case $wrepeat x of (# x1, x2, x3, r#) -> (x1:x2:x3:r)
 }}}
 and now this diverges.

 I’m not entirely sure who is at fault here. Since the analysis yields a
 correct result, most likely the w/w transformation. But that does not seem
 to have enough information to prevent this. Needs more thinking.

--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/1600#comment:20>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the ghc-tickets mailing list