[GHC] #9390: Inlining prevents evaluation of ignored parts of unboxed tuples

GHC ghc-devs at haskell.org
Fri Aug 8 11:36:54 UTC 2014


#9390: Inlining prevents evaluation of ignored parts of unboxed tuples
-------------------------------------+-------------------------------------
              Reporter:  snoyberg    |            Owner:
                  Type:  bug         |           Status:  merge
              Priority:  normal      |        Milestone:  7.8.4
             Component:  Compiler    |          Version:  7.8.3
            Resolution:              |         Keywords:
      Operating System:  Linux       |     Architecture:  x86_64 (amd64)
       Type of failure:  Incorrect   |       Difficulty:  Unknown
  result at runtime                  |       Blocked By:
             Test Case:              |  Related Tickets:
  simplCore/should_run/T9390         |
              Blocking:              |
Differential Revisions:              |
-------------------------------------+-------------------------------------

Comment (by simonpj):

 Some quick comments (I'm about to go on holiday):

  * You shouldn't have to quote the documentation for `pseq` to understand
 `seq`.  If `seq`'s documentation is inadequate, let's fix it.

  * You say "seq ensures that both one and one + two will be evaluated
 before the seq expression is evaluated".  I would rather say "...before
 the result of the seq expression is ''returned''".

  * "We can get the same guaranteed ordering of evaluation by having a
 function which is only strict in one of its arguments". Definitely not!
 GHC will inline `add` and all will be lost.  Only `pseq` guarantees this
 behaviour.

  * Passage starting "This looks like it should be straightforward".  Alas
 you have found yet another dark corner.  Here is a comment from the demand
 analyser:
 {{{
         -- Note [IO hack in the demand analyser]
         --
         -- There's a hack here for I/O operations.  Consider
         --      case foo x s of { (# s, r #) -> y }
         -- Is this strict in 'y'.  Normally yes, but what if 'foo' is an
 I/O
         -- operation that simply terminates the program (not in an
 erroneous way)?
         -- In that case we should not evaluate y before the call to 'foo'.
         -- Hackish solution: spot the IO-like situation and add a virtual
 branch,
         -- as if we had
         --      case foo x s of
         --         (# s, r #) -> y
         --         other      -> return ()
         -- So the 'y' isn't necessarily going to be evaluated
         --
         -- A more complete example (Trac #148, #1592) where this shows up
 is:
         --      do { let len = <expensive> ;
         --         ; when (...) (exitWith ExitSuccess)
         --         ; print len }
 }}}
  You can look at the tickets mentioned for some more background.  I hate
 the hack, but the bottom line is that no, GHC does not (and I think should
 not) evaluate helper2 before running helper1.

 That's as far as I got.  Thanks for writing this -- it's a good forcing
 function.

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


More information about the ghc-tickets mailing list