Ticket #4081 (new bug)
Strict constructor fields inspected in loop
| Reported by: | rl | Owned by: | benl |
|---|---|---|---|
| Priority: | low | Milestone: | 7.6.2 |
| Component: | Compiler | Version: | 6.13 |
| Keywords: | Cc: | benl@…, nightski@…, bjornbm, chr.andreetta@…, choener@…, batterseapower, rl, bgamari@… | |
| Operating System: | Unknown/Multiple | Architecture: | Unknown/Multiple |
| Type of failure: | Runtime performance bug | Difficulty: | Unknown |
| Test Case: | Blocked By: | ||
| Blocking: | Related Tickets: |
Description
Here is a small example to illustrate the problem:
module T where
data S a b = S !a !b
class C a where
make :: a -> S a a
instance C Int where
{-# NOINLINE make #-}
make n = S n n
foo :: (C a, Num a) => a -> Int -> a
{-# INLINE foo #-}
foo x k = k `seq` m `seq` go k 0
where
S m n = make x
go 0 i = i
go k i = go (k-1) (i + m)
module U where import T bar :: Int -> Int -> Int bar s k = foo s k + 1
Relying on LiberateCase seems to be the only way to unbox m outside of the loop in bar. The seq in foo doesn't help because it gets eliminated immediately.
GHC does have enough information to do this:
U.bar =
\ (s_aaw [Dmd=Just S(A)] :: GHC.Types.Int)
(k_aax [Dmd=Just U(L)] :: GHC.Types.Int) ->
case k_aax
of k1_ajh [Dmd=Just U(L)] { GHC.Types.I# ipv_ajj [Dmd=Just A] ->
case T.$fCInt_$cmake s_aaw of _ { T.S m_ajy [Dmd=Just U(T)] _ ->
...
Note the demand on m. If it was an argument instead of a local binding, it would be unboxed by w/w.
Also, the seq does help if we use lazy pairs instead of strict ones.
Change History
Note: See
TracTickets for help on using
tickets.
