[GHC] #10744: Allow oneShot to work with unboxed types

GHC ghc-devs at haskell.org
Thu Aug 6 15:42:26 UTC 2015


#10744: Allow oneShot to work with unboxed types
-------------------------------------+-------------------------------------
        Reporter:  akio              |                   Owner:
            Type:  feature request   |                  Status:  new
        Priority:  normal            |               Milestone:
       Component:  Compiler          |                 Version:  7.10.2
      Resolution:                    |                Keywords:
Operating System:  Unknown/Multiple  |            Architecture:
                                     |  Unknown/Multiple
 Type of failure:  None/Unknown      |               Test Case:
      Blocked By:                    |                Blocking:
 Related Tickets:                    |  Differential Revisions:
-------------------------------------+-------------------------------------

Comment (by akio):

 I use it in the fast-builder package [1], which aims to be a ByteString
 builder implementation that is significantly faster than the standard one.

 The main Builder type looks like this

 {{{#!hs
 type Builder = DataSink -> State -> State
 data DataSink = -- abstract
 data State = -- abstract

 -- | Builder concatenation.
 (<>) :: Builder -> Builder -> Builder
 a <> b = \sink s = b sink (a sink s)

 -- | Primitive builder.
 int :: Int -> Builder
 int = -- implementation omitted.
 }}}

 As an example, the user may write code like this to serialize a list of
 Ints:

 {{{#!hs
 serialize :: [Int] -> Builder
 serialize list = int (length list) <> foldr (<>) mempty (map int list)
 }}}

 For `serialize` to work efficiently, I really want it to have the arity of
 3. However, simply inlining `int` and `(<>)` only gives

 {{{#!hs
 serialize = \list -> let len = length list in \sink s -> ...
 }}}

 So it gets arity 1, which means it has to allocate a lambda and then call
 it.

 By default GHC doesn't eta-expand `serialize` because it wants to avoid
 evaluating `length` multiple times. However, I want GHC to produce better
 code in the assumption that the resulting Builder will be used at most
 once, because using the same Builder multiple times is usually a bad idea
 anyway (you should instead turn it into a ByteString and use that
 ByteString multiple times). I express this preference by inserting calls
 to `oneShot` into the definitions of `(<>)`, `int`, etc.

 The current type of `oneShot` means `State` has to be a lifted type.
 Ideally I'd like to use something like `(# Addr#, Addr#, State# RealWorld
 #)`.

 [1]: http://hackage.haskell.org/package/fast-builder

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


More information about the ghc-tickets mailing list