[GHC] #10918: Float once-used let binding into a recursive function
GHC
ghc-devs at haskell.org
Mon Sep 28 11:44:24 UTC 2015
#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
Keywords: | Operating System: Unknown/Multiple
Architecture: | Type of failure: None/Unknown
Unknown/Multiple |
Test Case: | Blocked By:
Blocking: | Related Tickets:
Differential Rev(s): |
-------------------------------------+-------------------------------------
Consider this code
{{{#!hs
let x = f x0
in let go 10 = x
go i = go (i+1)
in go (0::Int)
}}}
Currently, this is pretty much the core that comes out at the end. But
what we want to see instead is
{{{#!hs
let go 10 = let x = f x 0
in x
go i = go (i+1)
in go (0::Int)
}}}
In general, we do not want to float a binding into a recursive function,
because we would risk doing the allocation and/or evaluation of it
multiple times. But in this case, we can see that it is going to be used
at most once, so it is safe to do so. Even more: In the slightly less
contrived examples that I was looking at, the call to `x` was happening in
the a less likely code path, so this way we’d avoid doing the allocation
in most cases, a clear win.
It might be enough to simply make `CallArity` (or rather the cardinality
analysis done by call arity) tell the rest of the compiler that it found
that `x` is called at most once, and hopefully the simplifier knows what
to make of that information.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/10918>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list