#16029: Inadequate absence analysis -------------------------------------+------------------------------------- Reporter: simonpj | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: 8.6.3 Component: Compiler | Version: 8.6.2 Keywords: | Operating System: Unknown/Multiple Architecture: | Type of failure: None/Unknown Unknown/Multiple | Test Case: | Blocked By: Blocking: | Related Tickets: Differential Rev(s): | Wiki Page: -------------------------------------+------------------------------------- Consider {{{ data S = MkS Int Int g1 :: S -> Int -> Int g1 (MkS x y) 0 = 0 g1 (MkS x y) n = g1 (MkS y x) (n-1) }}} With GHC 8.6 we get {{{ $wg1 :: S -> GHC.Prim.Int# -> GHC.Prim.Int# [Str=<S,1*H><S,1*U>] $wg1 = \ (w_s2oH :: S) (ww_s2oL :: GHC.Prim.Int#) -> case w_s2oH of { MkS x_s2pz y_s2pA -> case ww_s2oL of ds_X2nb { __DEFAULT -> Foo.$wg1 (Foo.MkS y_s2pA x_s2pz) (GHC.Prim.-# ds_X2nb 1#); 0# -> 0# }} g1 :: S -> Int -> Int [Str=<S,1*H><S(S),1*U(1*U)>m] g1 = \ (w_s2oH :: S) (w1_s2oI :: Int) -> case w_s2oH of w2_X2pG { MkS ipv_s2p2 ipv1_s2p3 -> case w1_s2oI of { GHC.Types.I# ww1_s2oL -> case Foo.$wg1 w2_X2pG ww1_s2oL of ww2_s2oP { __DEFAULT -> GHC.Types.I# ww2_s2oP }}} }}} What terrible code! We evaluate the S argument in the wrapper, and box and unbox it every time around the loop, even though it is never ultimately used. Here's what happens if the arguments are banged: {{{ data T = MkT !Int !Int g2 :: T -> Int -> Int g2 (MkT x y) 0 = 0 g2 (MkT x y) n = g2 (MkT y x) (n-1) }}} We get {{{ $wg2 GHC.Prim.Int# -> GHC.Prim.Int# -> GHC.Prim.Int# -> GHC.Prim.Int# [Str=<L,1*U><L,1*U><S,1*U>] Foo.$wg2 = \ (ww_s2ow :: GHC.Prim.Int#) (ww1_s2ox :: GHC.Prim.Int#) (ww2_s2oB :: GHC.Prim.Int#) -> case ww2_s2oB of ds_X2n0 { __DEFAULT -> Foo.$wg2 ww1_s2ox ww_s2ow (GHC.Prim.-# ds_X2n0 1#); 0# -> 0# } g2 :: T -> Int -> Int [Str=<S(SS),1*U(1*U,1*U)><S(S),1*U(1*U)>m ] g2 = \ (w_s2os :: T) (w1_s2ot :: Int) -> case w_s2os of { MkT ww1_s2ow ww2_s2ox -> case w1_s2ot of { GHC.Types.I# ww4_s2oB -> case Foo.$wg2 ww1_s2ow ww2_s2ox ww4_s2oB of ww5_s2oF { __DEFAULT -> GHC.Types.I# ww5_s2oF }}} }}} Still terrible. We pass the two components around the loop before discarding them at the end. -- Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/16029> GHC <http://www.haskell.org/ghc/> The Glasgow Haskell Compiler