[GHC] #2289: Needless reboxing of values when returning from a tight loop

GHC ghc-devs at haskell.org
Sat Feb 20 17:17:00 UTC 2016


#2289: Needless reboxing of values when returning from a tight loop
-------------------------------------+-------------------------------------
        Reporter:  dons              |                Owner:
            Type:  bug               |               Status:  new
        Priority:  lowest            |            Milestone:
       Component:  Compiler          |              Version:  6.8.2
      Resolution:                    |             Keywords:  boxing,
                                     |  loops, performance
Operating System:  Unknown/Multiple  |         Architecture:
 Type of failure:  Runtime           |  Unknown/Multiple
  performance bug                    |            Test Case:
      Blocked By:                    |             Blocking:
 Related Tickets:  #2387,#1600       |  Differential Rev(s):
       Wiki Page:                    |
-------------------------------------+-------------------------------------

Comment (by rwbarton):

 Your example combines two issues. The big one is that you can in fact call
 `loop2` like this:
 {{{
 main = case loop2 100 (undefined,undefined) of (_,_) -> return ()
 }}}
 and it will terminate without evaluating `undefined`. So GHC can't eagerly
 evaluate `au+1` and `ad-1`, so there is thunk build-up in the argument
 pair, that eventually becomes the result pair.

 To fix this you could either

 * return a strict pair (`data P = P !Int !Int`, `| otherwise = P au ad`),
 which might be inconvenient, or

 * manually make the return tuple strict ({{{| otherwise = au `seq` ad
 `seq` (au,ad)}}}).

 Then, the second issue, which is the one I think you are interested in, is
 whether after one of these changes, the unboxed tuple returned by `loop2`
 contains boxed `Int`s or unboxed `Int#`s. (It can't very well contain
 `Int#`s without either change, since `au` and `ad` might be `undefined`!
 Or GHC would have to generate multiple specializations of `loop2` for
 different demand patterns, which it doesn't currently do.) Currently,
 `loop2` produces `Int#`s if its result type is a strict pair and `-funbox-
 small-strict-fields` is on (which it is by default), otherwise `Int`s.

 Unboxing the `Int`s inside the unboxed tuple is indeed nested CPR, which
 is the subject of this ticket.

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


More information about the ghc-tickets mailing list