
#15578: Honour INLINE pragmas on 0-arity bindings -------------------------------------+------------------------------------- Reporter: simonpj | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: 8.6.1 Component: Compiler | Version: 8.4.3 Keywords: | Operating System: Unknown/Multiple Architecture: | Type of failure: None/Unknown Unknown/Multiple | Test Case: | Blocked By: Blocking: | Related Tickets: Differential Rev(s): | Wiki Page: -------------------------------------+------------------------------------- Currently if we see {{{ x = factorial 200 {-# INLINE x #-} f y = ...x... }}} we won't inline `x`, lest we duplicate the work of `factorial 200`. But * Occasionally it's very important to inline `x`: see Trac #15519 for a real-world example. * Suppose `x` is used exactly once, not inside a lambda, thus {{{ x = blah {-# INLINE x #-} g = ...x... }}} Then, if there is ''no'' INLINE pragma, `x` will get inlined (by `preInlineUnconditionally`. But if there ''is'' an INLINE pragma, currently `x` is ''not'' inlined by `preInlineUnconditionally`: see `Note [Stable unfoldings and preInlineUnconditionally]` in `SimplUtils`. This is insane! * INLINE says "inline me at every saturated call", where "saturated" is determined by the number of arguments syntactically to the left of the "=" in the source bindings. In this case, there are no arguments to the left, so every occurrence is saturated. So it's inconsistent not to inline. Bottom line: if a 0-ary binding has an INLINE pragma, I think we should inline it at every use site * Regardless of the work duplication * Including inside lambdas Note, however, that there is a real risk that full laziness will float it right back out again. Consider again {{{ x = factorial 200 {-# INLINE x #-} f y = ...x... }}} After inlining we get {{{ f y = ...(factorial 200)... }}} but it's entirely possible that full laziness will do {{{ lvl23 = factorial 200 f y = l...lvl23... }}} That's a problem for another day. Presumably the reason the user wanted to inline it was to get some rule to fire, and this change gives at least some chance that will happen, and makes INLINE behave consistently. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/15578 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler