[GHC] #12620: Allow the user to prevent floating and CSE

GHC ghc-devs at haskell.org
Fri Sep 30 08:44:48 UTC 2016


#12620: Allow the user to prevent floating and CSE
-------------------------------------+-------------------------------------
        Reporter:  nomeata           |                Owner:
            Type:  feature request   |               Status:  new
        Priority:  normal            |            Milestone:
       Component:  Compiler          |              Version:  8.0.1
      Resolution:                    |             Keywords:
Operating System:  Unknown/Multiple  |         Architecture:
                                     |  Unknown/Multiple
 Type of failure:  None/Unknown      |            Test Case:
      Blocked By:                    |             Blocking:
 Related Tickets:  #9520, #8457      |  Differential Rev(s):
       Wiki Page:                    |
-------------------------------------+-------------------------------------

Comment (by simonpj):

 I'm beginning to get glimmers of understanding about this no-update thing.
 Consider
 {{{
   t1 = [1..n]
 vs
   t2 = \_ -> [1..n]
 vs
   t3 = let x = [1..n] in \_ -> x
 }}}
 Note that

 * If we use `t1` in a shared context like `sum t1 / length t1`, we'll end
 up materialising the whole list.
 * For `t2`, we'd get `sum (t2 ()) / length (t2 ())`, and now the list is
 computed twice rather than duplicated.  Note that `t1` and `t2` have
 different types of course.
 * Then `t3` is the result of applying the full laziness transformation to
 `t2`, and its space behaviour is back to that of `t1`.

 Reflections:

 * I think that this "noupdate" pragma is intended to achieve an effect
 like `t2`, but more conveniently, without changing types.  Correct?

 * I think (but am not sure) that you intend to use this only for one-shot
 thunks, where (unlike the sum/count example) the thunk is evaluated only
 once.   In which case it would often be discarded after being evaluated,
 in which case where does the leak come from.  A small, concrete example
 would be jolly useful.

 * Notice how important it is that in `t2` the lambda ''syntactically
 encloses'' the leaky computation.  Otherwise you get `t3`.  My conclusion
 from this is that if you want a pragma on a data constructor, that the
 pragma only guarantees to affect the syntactic argument.  Thus
 {{{
   let x = <expression> in Yield o x
 vs
   Yield o <expression>
 }}}
 The latter would "work" (i.e. `<expression>` would be wrapped in a non-
 updatable thunk); but the former might not.

 I say "might not" rather "would not" because cardinality analysis might
 propagate the one-shot info to `x`.  But that would be a "best-efforts"
 thing on which one might not like to rely.

 Would syntactic enclosure be enough in your application?

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


More information about the ghc-tickets mailing list