summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSylvain Henry <sylvain@haskus.fr>2021-03-05 15:04:59 +0100
committerMarge Bot <ben+marge-bot@smart-cactus.org>2021-03-14 12:57:40 -0400
commit87ae062ab8a73430308f4ea5967e76bc384e5a76 (patch)
treec3011e4c99d7076dcdd973bf02a05eb246a9aa63
parentd412cd108b2617cb3d2837994c7f39b5ba0b625d (diff)
downloadhaskell-87ae062ab8a73430308f4ea5967e76bc384e5a76.tar.gz
Compute length only once in foldBal
-rw-r--r--compiler/GHC/Tc/Deriv/Generics.hs15
1 files changed, 11 insertions, 4 deletions
diff --git a/compiler/GHC/Tc/Deriv/Generics.hs b/compiler/GHC/Tc/Deriv/Generics.hs
index 5a9e329ae2..8b0899e38a 100644
--- a/compiler/GHC/Tc/Deriv/Generics.hs
+++ b/compiler/GHC/Tc/Deriv/Generics.hs
@@ -900,10 +900,17 @@ nlHsCompose x y = compose_RDR `nlHsApps` [x, y]
-- | Variant of foldr for producing balanced lists
foldBal :: (a -> a -> a) -> a -> [a] -> a
-foldBal _ x [] = x
-foldBal _ _ [y] = y
-foldBal op x l = let (a,b) = splitAt (length l `div` 2) l
- in foldBal op x a `op` foldBal op x b
+{-# INLINE foldBal #-} -- inlined to produce specialised code for each op
+foldBal op0 x0 xs0 = fold_bal op0 x0 (length xs0) xs0
+ where
+ fold_bal op x !n xs = case xs of
+ [] -> x
+ [a] -> a
+ _ -> let !nl = n `div` 2
+ !nr = n - nl
+ (l,r) = splitAt nl xs
+ in fold_bal op x nl l
+ `op` fold_bal op x nr r
{-
Note [Generics and unlifted types]