
#14137: Do more inlining into non-recursive join points -------------------------------------+------------------------------------- Reporter: simonpj | Owner: nomeata Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 8.2.1 Resolution: | Keywords: JoinPoints 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 nomeata):
Maybe it didn't start that way?
Quite possible (didn’t check). The problem of things floating out of recursive lets and never back in has beein bothering me for a while, especially in the context of https://ghc.haskell.org/trac/ghc/ticket/10918#comment:5. Maybe the following thought deserves a ticket of its own: Currently, we cannot inline `x` in {{{ let x = f x0 in let go 10 y = exit1 x y go 20 y = exit2 (y*y) go 30 y = exit3 0 go i = go (i+1) (y*2) in go y }}} because it goes into a recursive function and under lambdas, and that is, in general, dangerous. But in this case, it would be ok because the occurence of `x` is not actually on a recursive path. But that is hard to spot in this form! It would be easy to spot if we take all codepaths of `go` that do not mention `go` and float them out of the recursive let ''as non-recursive jointpoints'': {{{ let x = f x0 in join j1 y = exit1 x y join j2 y = exit2 (y*y) join j3 = exit3 0 let go 10 y = call j1 y go 20 y = call j2 y go 30 y = call j3 go i = go (i+1) (y*2) in go y }}} and now the existing machinery will happily inline `x` into `j1` or `j2`. In the example of this ticket, we’d move all occurrences of `ds5` out of `save` this way, and the inliner could do its work unhindered by the recursion. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/14137#comment:10 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler