
#15519: Minor code refactoring leads to drastic performance degradation -------------------------------------+------------------------------------- Reporter: danilo2 | Owner: (none) Type: bug | Status: new Priority: highest | Milestone: 8.8.1 Component: Compiler | Version: 8.4.3 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): OK I have figured out `test2`. Consider {{{ f x p = case x of A y -> ..(f y p2)... B z -> map z something main = f (A (B isEven)) blah }}} `SpecConstr` will see the call `f (A (B isEven))` but, looking at `f`, it only see a single-level pattern-match on `x`, so it'll only do a single- level specialisation: {{{ f_spec y p = ...(f y p2)... {-# RULE f (A y) p = f_spec y p #-} }}} This is good so far as it goes, but we are left with {{{ f_spec y p = ...(f y p2)... main = f_spec (B isEven) something }}} which is not good (because we have not specialised on `B`. Even if we ran `SpecConstr` a second time, it won't see any reason to specialise `f_spec` (since it does not directly scrutinise `y`), and neither will it see any reason to further specialise `f`. It would be much better to specialise on that full call in the first place, giving {{{ f_spec1 p = ...(f (B isEven) p2)... {-# RULE f (A (B isEven)) p = f_spec1 p #-} }}} Now we have a call in the body of `f_spec1` that we can specialise, and `SpecConstr` does just that, giving {{{ f_spec2 p = map isEven something {-# RULE f (B isEven) p = f_spec2 p #-} }}} And all is good. The final code is {{{ f_spec2 p = map isEven something f_spec1 y p = ...(f_spec2 y p2)... main = f_spec1 blah }}} But specialising on the full call pattern risks over-specialising, duplicating code to no purpose, ''and'' making the specialisation less useful to other callers. I'm not sure what to do about this. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/15519#comment:12 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler