UNPACK can lead to unnecessary copying and wasted stack space
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#) ->
Trac metadata
Trac field | Value |
---|---|
Version | 6.12.3 |
Type | Bug |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | Compiler |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | |
Operating system | |
Architecture |