
#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