
#10918: Float once-used let binding into a recursive function -------------------------------------+------------------------------------- Reporter: nomeata | Owner: Type: task | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.10.2 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): -------------------------------------+------------------------------------- Comment (by nomeata): Thanks for the input! Next thing to consider problem: Can we float it past the case analysis (or past multiple recursive bindings): In {{{ let x = f x0 in let go 30 = x go 20 = x go 10 = something else go i = go (i+1) in go y }}} we know that `x` is evaluated at most once, so we want to float it in. Also, `x` might actually not be needed, so we would gain something by not allocating it before hand. But we also definitely not want it to float past the let and the lambda, just to get {{{ let go i = let x = f x0 in case i of 30 -> x 20 -> x 10 -> something else i -> go (i+1) in go y }}} as now we would allocate it on _every_ call. So either, floats that are allowed to go into a recursive group _must_ also go past a case, possibly duplicating it: {{{ let go 30 = let x = f x0 in x go 20 = let x = f x0 in x go 10 = something else go i = go (i+1) in go y }}} But this would blow up the code size... . A more cautious route would be to only float something inside a recursive group if it is used at most once _and_ there is only one syntactical call to it, because then we can be reasonably sure that it will also float into the branches. Is there an easy way to detect that something has only one syntactic occurence? Is it not possible to tell the inliner to do this work and decision making? -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/10918#comment:3 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler