[commit: ghc] master: INLINE unfoldr (78209d7)
git at git.haskell.org
git at git.haskell.org
Sat Sep 6 20:22:02 UTC 2014
Repository : ssh://git@git.haskell.org/ghc
On branch : master
Link : http://ghc.haskell.org/trac/ghc/changeset/78209d70596dcbfcb11ad1de1c961ab8479e531e/ghc
>---------------------------------------------------------------
commit 78209d70596dcbfcb11ad1de1c961ab8479e531e
Author: Joachim Breitner <mail at joachim-breitner.de>
Date: Sat Sep 6 22:21:54 2014 +0200
INLINE unfoldr
Summary:
to allow GHC to maybe remove the Maybe. See the code comment for more
commentary. This fixes #9369.
Test Plan: see what happens on ghcspeed (once it is merged)
Reviewers: austin
Reviewed By: austin
Subscribers: simonmar, ezyang, carter
Differential Revision: https://phabricator.haskell.org/D198
GHC Trac Issues: #9369
>---------------------------------------------------------------
78209d70596dcbfcb11ad1de1c961ab8479e531e
libraries/base/Data/List.hs | 37 ++++++++++++++++++++++++++++++++-----
1 file changed, 32 insertions(+), 5 deletions(-)
diff --git a/libraries/base/Data/List.hs b/libraries/base/Data/List.hs
index f813741..f7b58c1 100644
--- a/libraries/base/Data/List.hs
+++ b/libraries/base/Data/List.hs
@@ -995,11 +995,38 @@ sortOn f =
-- > unfoldr (\b -> if b == 0 then Nothing else Just (b, b-1)) 10
-- > [10,9,8,7,6,5,4,3,2,1]
--
-unfoldr :: (b -> Maybe (a, b)) -> b -> [a]
-unfoldr f b =
- case f b of
- Just (a,new_b) -> a : unfoldr f new_b
- Nothing -> []
+
+-- Note [INLINE unfoldr]
+-- We treat unfoldr a little differently from some other forms for list fusion
+-- for two reasons:
+--
+-- 1. We don't want to use a rule to rewrite a basic form to a fusible
+-- form because this would inline before constant floating. As Simon Peyton-
+-- Jones and others have pointed out, this could reduce sharing in some cases
+-- where sharing is beneficial. Thus we simply INLINE it, which is, for
+-- example, how enumFromTo::Int becomes eftInt. Unfortunately, we don't seem
+-- to get enough of an inlining discount to get a version of eftInt based on
+-- unfoldr to inline as readily as the usual one. We know that all the Maybe
+-- nonsense will go away, but the compiler does not.
+--
+-- 2. The benefit of inlining unfoldr is likely to be huge in many common cases,
+-- even apart from list fusion. In particular, inlining unfoldr often
+-- allows GHC to erase all the Maybes. This appears to be critical if unfoldr
+-- is to be used in high-performance code. A small increase in code size
+-- in the relatively rare cases when this does not happen looks like a very
+-- small price to pay.
+--
+-- Doing a back-and-forth dance doesn't seem to accomplish anything if the
+-- final form has to be inlined in any case.
+
+unfoldr :: (b -> Maybe (a, b)) -> b -> [a]
+
+{-# INLINE unfoldr #-} -- See Note [INLINE unfoldr]
+unfoldr f b0 = build (\c n ->
+ let go b = case f b of
+ Just (a, new_b) -> a `c` go new_b
+ Nothing -> n
+ in go b0)
-- -----------------------------------------------------------------------------
More information about the ghc-commits
mailing list