<div dir="ltr"><div>I'm seeing what looks like repeated computation under a lambda with `-O` and `-O2`. The following definition:</div><div><br></div><div>> exampleC :: Double -> Double -> Double</div><div>> exampleC = \ t -> let s = sin t in \ x -> x + s</div><div><br></div><div>yields this Core:</div><div><br></div><div>> -- RHS size: {terms: 13, types: 6, coercions: 0}</div><div>> exampleC :: Double -> Double -> Double</div><div>> exampleC =</div><div>>   \ (t_afI6 :: Double) (eta_B1 :: Double) -></div><div>>     case eta_B1 of _ { D# x_aj5c -></div><div>>     case t_afI6 of _ { D# x1_aj5l -></div><div>>     D# (+## x_aj5c (sinDouble# x1_aj5l))</div><div>>     }</div><div>>     }</div><div><br></div><div>The `sinDouble#` here depends only on `t_afI6` (`t`) but still appears under the binding of `eta_B1` (`x`).</div><div><br></div><div><div>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.)<br></div><div><br></div><div>Does the optimization I expected somehow happen later in the compilation pipeline?</div><div><br></div><div>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)?</div></div><div><br></div><div>Thanks,</div><div>-- Conal</div><div><br></div></div>