summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Klebinger <klebinger.andreas@gmx.at>2019-07-07 21:50:56 +0200
committerMarge Bot <ben+marge-bot@smart-cactus.org>2019-07-11 17:46:57 -0400
commit01ec8549871ebc43db3a7e28324222fa739c6531 (patch)
tree686b8395a2da9d12a9935fb7f204f7c19a70a5d0
parentcb5271ac9a6686d065de63d1dde80e713830e21b (diff)
downloadhaskell-01ec8549871ebc43db3a7e28324222fa739c6531.tar.gz
Special case a few common patterns in unionLists.
In particular we very often pass one empty list and in these cases we want to avoid the overhead of computing `xs ++ []`. This should fix #14759 and #16911.
-rw-r--r--compiler/utils/ListSetOps.hs11
1 files changed, 10 insertions, 1 deletions
diff --git a/compiler/utils/ListSetOps.hs b/compiler/utils/ListSetOps.hs
index 8a6e07d84a..cad8cd9583 100644
--- a/compiler/utils/ListSetOps.hs
+++ b/compiler/utils/ListSetOps.hs
@@ -52,8 +52,17 @@ deleteBys eq xs ys = foldl' (flip (deleteBy eq)) xs ys
-}
+-- | Assumes that the arguments contain no duplicates
unionLists :: (Outputable a, Eq a) => [a] -> [a] -> [a]
--- Assumes that the arguments contain no duplicates
+-- We special case some reasonable common patterns.
+unionLists xs [] = xs
+unionLists [] ys = ys
+unionLists [x] ys
+ | isIn "unionLists" x ys = ys
+ | otherwise = x:ys
+unionLists xs [y]
+ | isIn "unionLists" y xs = xs
+ | otherwise = y:xs
unionLists xs ys
= WARN(lengthExceeds xs 100 || lengthExceeds ys 100, ppr xs $$ ppr ys)
[x | x <- xs, isn'tIn "unionLists" x ys] ++ ys