
#8589: Bad choice of loop breaker with INLINABLE/INLINE --------------------------------------------+------------------------------ Reporter: NickSmallbone | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.6.3 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Type of failure: Runtime performance bug | Unknown/Multiple Test Case: | Difficulty: Unknown Blocking: | Blocked By: | Related Tickets: --------------------------------------------+------------------------------ Comment (by simonpj): '''Explanation of what is happening.''' * Remember that each `Id` has one, and only one, inlining attached to it. * With INLINABLE/INLINE, the `pair`'s inlining is used to store the original RHS. * But since the group is recursive, `pair` is chosen as loop breaker, and never gets inlined. Why does it work without an INLINE pragma? Because we don't snapshot the original RHS we are free to optimise it, which we do by "floating out" some local let bindings, thus exposing the pair. And we are careful never to choose a visible pair as a loop breaker unless we absolutely have to. '''What to do'''. I'm now pretty sure that INLINEABE should really be "SPECIALISABLE", and should be stored quite separately from the Id's inlining. Then they would not get in each others way. See #5928 for another example. INLINE is a bit less obvious. The simple cases are already fine: * For non-recursive functions, if you say INLINE, you really mean to inline it, so it seems stupid to keep a separate snapshot. * Recursive functions never inline anyway, so an INLINE pragma is stupid. A recursive ''group'' with INLINE is tricky,and that is the case here. I'm still thinking about how it should go. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/8589#comment:3 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler