
I'm seeing what looks like repeated computation under a lambda with `-O` and `-O2`. The following definition:
exampleC :: Double -> Double -> Double exampleC = \ t -> let s = sin t in \ x -> x + s
yields this Core:
-- RHS size: {terms: 13, types: 6, coercions: 0} exampleC :: Double -> Double -> Double exampleC = \ (t_afI6 :: Double) (eta_B1 :: Double) -> case eta_B1 of _ { D# x_aj5c -> case t_afI6 of _ { D# x1_aj5l -> D# (+## x_aj5c (sinDouble# x1_aj5l)) } }
The `sinDouble#` here depends only on `t_afI6` (`t`) but still appears under the binding of `eta_B1` (`x`). I'm concerned because many of my uses of such functions involve computations dependent only on `t` (time) but with millions of uses (space) per `t`. (I'm working on a GHC Core plugin (compiling to categories), with one use generating graphics GPU code.) Does the optimization I expected somehow happen later in the compilation pipeline? Are there Core-manipulating functions in GHC that I can use to make it happen earlier (via a `BuiltinRule`, i.e., Core-to-Core function)? Thanks, -- Conal