Unexpected lack of optimisation

Simon Peyton-Jones simonpj at microsoft.com
Tue Apr 29 12:56:07 EDT 2008


| {-# INLINE foo #-}
| foo = large
|
| bar x = if x then res else res
|     where res = foo
|
| By putting an INLINE on foo I am able to persuade it to be inlined
| into the binding of bar, but I can't then persuade it to be inlined at
| the let expression.

I'm not certain what you mean here.  I think you mean that in the above code you end up with
        bar x = let res = large in if x then res else res
whereas what you wanted was
        bar x = if x then large else large


That is indeed tricky in general, as I'm sure you can see:

        let x = <large> in
        let y = e2[x,x] in
        let z = e3[y] in
        ...

Is it better to inline x into e2, or y into e3, or z into e4?  Hard to tell!

In your example, you want 'res' to inline "first".  You can get that by explicit control:

{-# NOINLINE [0] foo #-}

That says "don't inline foo before phase 0", which in turn gives time for 'res' to get inlined first.  I'm not certain whether that'll help in your actual example.

Simon


More information about the Glasgow-haskell-users mailing list