#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