Constant functions and selectors make for interesting arguments
Simon Peyton Jones
simonpj at microsoft.com
Mon Jan 30 22:50:43 UTC 2017
What code would you like to get?
I think you are talking about specialising a recursive function ($fFunctorTree_$cfmap in this case) for a particular value of its function argument. That's a bit like SpecConstr (SpecFun perhaps) and nothing at all like inlining.
Unless I'm missing something.
I think there's a ticket somewhere about extending SpecConstr to work on function arugments, but it's tricky to do.
Simon
| -----Original Message-----
| From: David Feuer [mailto:david at well-typed.com]
| Sent: 30 January 2017 21:42
| To: ghc-devs at haskell.org; Simon Peyton Jones <simonpj at microsoft.com>
| Cc: David Feuer <david.feuer at gmail.com>
| Subject: Re: Constant functions and selectors make for interesting
| arguments
|
| 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 at haskell.org] On Behalf Of
| > David Feuer
| Sent: 27 January 2017 16:42
| > To: ghc-devs <ghc-devs at haskell.org>
| > 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?
|
More information about the ghc-devs
mailing list