[Haskell-cafe] Announce: ghc-core, command line pager for reading GHC Core

Don Stewart dons at galois.com
Fri May 23 16:14:30 EDT 2008


duncan.coutts:
> 
> On Fri, 2008-05-23 at 21:24 +0200, Henning Thielemann wrote:
> > On Fri, 23 May 2008, Bulat Ziganshin wrote:
> > 
> > > Hello Henning,
> > >
> > > Friday, May 23, 2008, 8:31:24 PM, you wrote:
> > >
> > >> would guarantee speed in every case. Or I can SPECIALISE the function,
> > >> then the function will only be called, but with polymorphism overhead
> > >> eliminated. This would only work for a restricted range of types. I'd like
> > >> to have a pragma, that tells GHC to specialise a function for every type
> > >> it is called with.
> > >
> > > me too. btw, this already present in jhc. inlining doesn't work in any
> > > complex case since recursive functions can't be inlined
> > 
> > GHC inlines recursive functions, too, otherwise it could not turn 'foldl' 
> > and friends into plain machine loops.
> 
> Actually ghc's definition of foldl is not recursive, though it does of
> course contain a local recursion:
> 
> foldl        :: (a -> b -> a) -> a -> [b] -> a
> foldl f z xs = lgo z xs
>              where
>                 lgo z []     =  z
>                 lgo z (x:xs) = lgo (f z x) xs
> 
> The lgo recursive call is then specialised at the call site and we can
> get good code. 
> 
> As I understand it, if foldl was written in the standard directly way
> then ghc would not inline it. So we have to manually apply the static
> argument transformation. You'll see that foldr is written in the same
> way.

Similar for length et al. These worker/wrapper things inline quite
happily:

    module B where

    mylength :: [a] -> Int
    mylength = go 0
        where
            go :: Int -> [a] -> Int
            go n []     = n
            go n (_:xs) = go (n+1) xs
    {-# INLINE mylength #-}

    module A where

    import B

    main = print (mylength (enumFromTo 1 (10::Int)))

------------------------------------------------------------------------

And it is all inlined into A.hs:

    A.lvl2 =
      case A.go1 @ Int A.lvl A.lvl1 of w_axy { I# ww_axA ->
      $wshowSignedInt 0 ww_axA ([] @ Char)
      }

    A.go1 :: forall a1_a5n. Int -> [a1_a5n] -> Int
    A.go1 =
      \ (@ a1_a7b) (n_a5p :: Int) (ds_d9N :: [a1_a7b]) ->
        case ds_d9N of wild_B1 {
          [] -> n_a5p;
          : ds1_d9O xs_a5s ->
            A.go1
              @ a1_a7b
              (case n_a5p of wild1_aqC { I# x_aqE ->
               I# (+# x_aqE 1)
               })
              xs_a5s


-- Don


More information about the Haskell-Cafe mailing list