[GHC] #12603: INLINE and manually inlining produce different code

GHC ghc-devs at haskell.org
Fri Oct 21 08:08:54 UTC 2016


#12603: INLINE and manually inlining produce different code
-------------------------------------+-------------------------------------
        Reporter:  bgamari           |                Owner:  bgamari
            Type:  task              |               Status:  new
        Priority:  normal            |            Milestone:  8.2.1
       Component:  Compiler          |              Version:  8.0.1
      Resolution:                    |             Keywords:
Operating System:  Unknown/Multiple  |         Architecture:
                                     |  Unknown/Multiple
 Type of failure:  None/Unknown      |            Test Case:
      Blocked By:                    |             Blocking:
 Related Tickets:                    |  Differential Rev(s):
       Wiki Page:                    |
-------------------------------------+-------------------------------------

Comment (by simonpj):

 > I've compared the resulting Core. The difference is that the version
 with INLINE recomputes `((2 ^ (8 :: Int) - 1)` every time, while the
 manually inlined version uses a value computed just once.

 Here's how that could happen:
 {{{
 f x y = (expensive x) + y

 g x ys = map (f x) ys
 }}}
 Executed as-is each call to `(f x yi)` will evaluate `(expensive x)`
 afresh.  In this particular example it'd be better if GHC transformed to
 {{{
 f x = let v = expensive x in
       \y -> v + y
 }}}
 but GHC's full laziness transformation never separates adjacent lambdas.
 (Doing so can be very bad in other ways.)  But if you INLINE f we get
 {{{
 g x ys = map (\y -> expensive x + y) ys
 }}}
 and now full laziness ''can'' float `(expensive x)` outwards.

 To make your program robust, I'd write `f` with the local let-binding as I
 do above.  Then it shouldn't repeatedly evaluate `(expensive x)`
 regardless of optimisation or inlining.

 I'm guessing a bit of course.  It could just be a bug.  I'm really swamped
 right now, but maybe I've given you enough to investigate further. If you
 think it's a bug, it'd be really helpful to boil out a smaller example
 with full repro instructions.

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


More information about the ghc-tickets mailing list