[GHC] #9992: Constructor specialization requires eta expansion

GHC ghc-devs at haskell.org
Fri Jan 16 00:27:35 UTC 2015


#9992: Constructor specialization requires eta expansion
-------------------------------------+-------------------------------------
              Reporter:  bgamari     |             Owner:
                  Type:  bug         |            Status:  new
              Priority:  normal      |         Milestone:
             Component:  Compiler    |           Version:  7.8.4
              Keywords:              |  Operating System:  Unknown/Multiple
  performance                        |   Type of failure:  Runtime
          Architecture:              |  performance bug
  Unknown/Multiple                   |        Blocked By:
             Test Case:              |   Related Tickets:
              Blocking:              |
Differential Revisions:              |
-------------------------------------+-------------------------------------
 I recently encountered a slightly tricky performance issue[1] in
 `bytestring`'s `Builder` implementation which required explicit eta
 expansion in order for GHC to perform ConstrSpec.

 We have
 {{{#!hs
 data BufferRange = BufferRange {-# UNPACK #-} !(Ptr Word8)  -- First byte
 of range
                                {-# UNPACK #-} !(Ptr Word8)  -- First byte
 /after/ range

 data BuildSignal a = ... -- Just a vanilla ADT
 type BuildStep a = BufferRange -> IO (BuildSignal a)
 }}}

 We end up with Core (full version
 https://gist.github.com/bgamari/091e3dac9c45ee9accf1#file-slow-hs-L1)
 that looks like this,

 {{{#!hs
 Main.$wa
   :: GHC.Prim.Word#
      -> GHC.Prim.Int#
      -> forall r_aKUt.
         Data.ByteString.Builder.Internal.BuildStep r_aKUt
         -> Data.ByteString.Builder.Internal.BuildStep r_aKUt
 Main.$wa =
   \ (ww_s10YU :: GHC.Prim.Word#)
     (ww1_s10YY :: GHC.Prim.Int#)
     (@ r_aKUt)
     (w_s10YR :: Data.ByteString.Builder.Internal.BuildStep r_aKUt) ->
     case ww1_s10YY of wild_XE {
       __DEFAULT -> (
           \ (eta1_X1Q :: Data.ByteString.Builder.Internal.BufferRange) ->
             case eta1_X1Q of BufferRange a b ->
               -- A bunch of code eventually ending in a recursive call to
 $wa
       )
       0 -> w_s10YR
     }
 }}}

 If `w_s10YR` is eta-expanded GHC will run ConstrSpec, eliminating the
 fields of `BufferRange` to be unpacked between iterations of `$wa` and
 substantially improving performance.

 In [1] we had to manually eta-expand the empty case to ensure that
 this would happen. It would be great if GHC would identify cases like
 this.

 [1] https://github.com/haskell/bytestring/pull/40

--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/9992>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the ghc-tickets mailing list