
#14013: Bad monads performance -------------------------------------+------------------------------------- Reporter: danilo2 | Owner: (none) Type: bug | Status: new Priority: high | Milestone: Component: Compiler | Version: 8.2.1-rc3 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 have not worked all of this out, but I have learned something. You have this INLINE pragma: {{{ {-# INLINE mtlStateListParser_a #-} }}} It does nothing, because the function is recursive. But alas, it harms things a lot. Simply removing that INLINE pragma makes `mtlStateListParser_a` behave well in all settings, I think. Can you confirm that? I believe that the reason things go bad is this. GHC does this transformation (always): {{{ f = e |> co ===> f' = e f = f' |> co }}} Reason: `f` can now be inlined at all use sites, and `co` may cancel. But if the original `f` has an INLINE pragma we get {{{ f = e |> co { INLINE = <inline rhs> } ===> f' = e f = f' |> co { INLINE = <inline rhs> } }}} where the `{ INLINE = <inline rhs> }` is the (stable, user-written) inlining for `f`. Now the point of the transformation is lost, becuase `f` won't be replaced at its use sites by `f' |> co`; the INLINE pragma is what gets inlined. Moreover, if `<inline rhs>` and `e` both mention `f`, then `f` becomes a loop breaker and we get mutual recusion between `f` and `f'`. This what ultimately leads to the alternation between `(,)` and `(##)` you observed. Solution (I think) don't do this transformation if `f` has an INLINE pragma. I'll try that. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/14013#comment:9 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler