Search code examples
haskelloptimizationvectorinlinevectorization

INLINE_FUSED pragma in Haskell


I am going over the vector library and noticed a {-# INLINE_FUSED transform #-} and I was wondering what it does? I see it defined in vector.h but nowhere else.


Solution

  • The definitions mean that INLINE_FUSED is the same as INLINE [1]; INLINE_INNER is the same as INLINE [0]. The [1] and [0] are standard ghc for ordering the phases of inlining. See the discussion under the heading 7.13.5.5. Phase control in http://www.haskell.org/ghc/docs/7.0.4/html/users_guide/pragmas.html

    vector needs to control the stages at which ghc inlines various definitions. First it wants all uses of the functions stream and unstream to be exposed, so that (above all) stream.unstream can be replaced by id, and similarly in other cases, according to the (rewrite) RULE pragmas distributed throughout.

    Typical vector to vector functions are written as unstream . f . stream, where f is a Stream to Stream function. unstream builds an actual vector in memory from a Stream; stream reads a real vector into a Stream. The object of the game is to reduce the number of actual vectors built. So the composition of three vector to vector functions

     f_vector . g_vector . h_vector
    

    is really

     unstream . f_stream . stream . unstream . g_stream . stream . unstream . h_stream . stream
    

    which his rewritten to

     unstream . f_stream . g_stream . h_stream . stream
    

    and so on. So we write one new vector instead of three.

    The rules for transform are a little fancier than this, but belong with the same subtle system of ordering:

     transform f g (unstream s) = unstream (Bundle.inplace f g s)
     transform f1 g1 (transform f2 g2 p) = transform (f1 . f2) (g1 . g2) p
    

    in https://github.com/haskell/vector/blob/master/Data/Vector/Generic/New.hs#L76

    so you can see how something inlined in the form:

    unstream . h_stream . stream . transform f1 g1 . transform f2 g2 
                        . unstream . j_stream . stream $ input_vector
    

    would be rewritten.