[GHC] #16029: Inadequate absence analysis

GHC ghc-devs at haskell.org
Mon Dec 10 17:45:49 UTC 2018


#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


More information about the ghc-tickets mailing list