
#10069: CPR related performance issue -------------------------------------+------------------------------------- Reporter: pacak | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 8.6.2 Resolution: | Keywords: | DemandAnalysis Operating System: Unknown/Multiple | Architecture: Type of failure: Runtime | Unknown/Multiple performance bug | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by simonpj):
So: If we WW fc, we should also WW c1, otherwise we end up with bad code.
Quite right. Why does that not happen? It's because of {{{ tryWW dflags fam_envs is_rec fn_id rhs -- See Note [Worker-wrapper for NOINLINE functions] | Just stable_unf <- certainlyWillInline dflags fn_info = return [ (fn_id `setIdUnfolding` stable_unf, rhs) ] -- See Note [Don't w/w INLINE things] -- See Note [Don't w/w inline small non-loop-breaker things] }}} The Notes are informative. What happens here is that * `certainlyWillInline` returns True for `c1`, despite the NOINLINE pragma * We set a stable unfolding, for reasons described in `Note [Don't w/w inline small non-loop-breaker things]` * But alas the NOINLINE stays there and prevents `c1` inlining. I think we should always create a wrapper for NOINLINE things, just as if they were big. We already have technology for transferring the NOINLINE pragma to the worker; see * `Note [Worker-wrapper for INLINABLE functions]` * `Note [Worker activation]`, which even talks about NOINLINE specifically. So the bottom line is, I think, that the `certainlyWillInline` test should return False for NOINLINE functions. This call in `WorkWrap` is its only call site, so the change should be easy. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/10069#comment:33 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler