#4306: UNPACK can lead to unnecessary copying and wasted stack space
---------------------------------+------------------------------------------
    Reporter:  Olathe            |       Owner:                         
        Type:  bug               |      Status:  new                    
    Priority:  normal            |   Component:  Compiler               
     Version:  6.12.3            |    Keywords:                         
    Testcase:                    |   Blockedby:                         
          Os:  Unknown/Multiple  |    Blocking:                         
Architecture:  Unknown/Multiple  |     Failure:  Runtime performance bug
---------------------------------+------------------------------------------
 You can write a pattern-matched function to take only certain components
 of a data type.  If you pattern match on an `UNPACK`ed component and GHC
 decomposes your function into several simpler functions, those functions
 will pass '''every''' `UNPACK`ed component, used or not, between the
 simpler functions.

 This wastes time copying the unneeded `UNPACK`ed components to the stack
 and obviously wastes stack space.

 ----

 For example, the function `upd` below
 {{{
 data D = D {-# UNPACK #-} !Double {-# UNPACK #-} !Double
 data UPD = UPD {-# UNPACK #-} !Double D

 upd (UPD _ (D x _)) = sqrt $! (x*x + x*x)
 }}}
 takes only one component of the nested data structure.  However, it will
 be decomposed into `Test.upd` and `Test.$wupd`
 {{{
 Test.upd :: Test.UPD -> GHC.Types.Double
 GblId
 [Arity 1
  Worker Test.$wupd
  NoCafRefs
  Str: DmdType U(AU(LA))m]
 Test.upd =
   __inline_me (\ (w_spS :: Test.UPD) ->
                  case w_spS of _ { Test.UPD ww_spU ww1_spV ->
                  case ww1_spV of _ { Test.D ww3_spX ww4_spY ->
                  case Test.$wupd ww_spU ww3_spX ww4_spY of ww5_sq3 {
 __DEFAULT ->
                  GHC.Types.D# ww5_sq3
                  }
                  }
                  })

 Test.$wupd :: GHC.Prim.Double#
               -> GHC.Prim.Double#
               -> GHC.Prim.Double#
               -> GHC.Prim.Double#
 GblId
 [Arity 3
  NoCafRefs
  Str: DmdType ALA]
 Test.$wupd =
   \ _ (ww1_spX :: GHC.Prim.Double#) _ ->
   ...
 }}}
 wherein `Test.upd` takes the structure and passes '''''all''''' of the
 `UNPACK`ed components to `Test.$wupd`, giving it `Arity 3`, and which
 immediately drops all the unneeded components via underscores.

 ----

 The correct behavior can be seen when you don't use `UNPACK` at all, as
 with `ppb` here
 {{{
 data B = B                !Double                !Double
 data PPB = PPB                !Double B

 ppb (PPB _ (B x _)) = sqrt $! (x*x + x*x)
 }}}
 for which GHC produces a nested function, `Test.$wppb`, which has `Arity
 1`, as it should.
 {{{
 Test.$wppb :: GHC.Prim.Double# -> GHC.Prim.Double#
 GblId
 [Arity 1
  NoCafRefs
  Str: DmdType L]
 Test.$wppb =
   \ (ww_sr1 :: GHC.Prim.Double#) ->
 }}}

-- 
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/4306>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
_______________________________________________
Glasgow-haskell-bugs mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs

Reply via email to