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 UNPACKed component and GHC decomposes your function into several simpler functions, those functions will pass every UNPACKed component, used or not, between the simpler functions.
This wastes time copying the unneeded UNPACKed 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 UNPACKed 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 |