
Here's an example: data Tree a = Bin (Tree a) a (Tree a) | Tip deriving Functor {-# NOINLINE replace #-} replace :: a -> Tree b -> Tree a replace x t = x <$ t When I compile this with -O2, I get Rec { -- RHS size: {terms: 18, types: 21, coercions: 0} $fFunctorTree_$cfmap :: forall a_ar2 b_ar3. (a_ar2 -> b_ar3) -> Tree a_ar2 -> Tree b_ar3 $fFunctorTree_$cfmap = \ (@ a_aGb) (@ b_aGc) (f_aFH :: a_aGb -> b_aGc) (ds_dGN :: Tree a_aGb) -> case ds_dGN of _ { Bin a1_aFI a2_aFJ a3_aFK -> Bin ($fFunctorTree_$cfmap f_aFH a1_aFI) (f_aFH a2_aFJ) ($fFunctorTree_$cfmap f_aFH a3_aFK); Tip -> Tip } end Rec } $fFunctorTree_$c<$ :: forall a_ar4 b_ar5. a_ar4 -> Tree b_ar5 -> Tree a_ar4 $fFunctorTree_$c<$ = \ (@ a_aGQ) (@ b_aGR) (eta_aGS :: a_aGQ) (eta1_B1 :: Tree b_aGR) -> $fFunctorTree_$cfmap (\ _ -> eta_aGS) eta1_B1 replace :: forall a_aqt b_aqu. a_aqt -> Tree b_aqu -> Tree a_aqt replace = $fFunctorTree_$c<$ This is no good at all, because replacing the values in the same tree over and over will build up a giant chain of thunks in each node carrying all the previous values. I suppose that inlining per se may not be quite enough to fix this problem, but I suspect there's some way to fix it. Fixing it in Functor deriving would be a start (I can look into that), but fixing it in user code would be quite good too. On Monday, January 30, 2017 9:01:34 PM EST Simon Peyton Jones via ghc-devs wrote:
Functions whose body is no bigger (by the inliner’s metrics) than the call are always inlined vigorously. So (\.....-> k) replaces a call by a single variable. GHC will do that a lot.
These ideas are best backed by use-cases where something good is not happening. Do you have some?
Simon
From: ghc-devs [mailto:ghc-devs-bounces@haskell.org] On Behalf Of David Feuer Sent: 27 January 2017 16:42 To: ghc-devs
Subject: Constant functions and selectors make for interesting arguments GHC's inliner has a notion of "interesting argument" it uses to encourage inlining of functions called with (I think) dictionary arguments. I think another class of argument is very interesting, by being very boring. Any argument that looks like either
\ _ ... (Con _ ... x ... _ ) ... _ -> coerce x
or
\ _ ... _ -> k
Has a pretty good chance of doing a lot of good when inlined, perhaps plugging a space leak. Would it make sense to try to identify such functions and consider them interesting for inlining?