summaryrefslogtreecommitdiff
path: root/compiler/GHC/Data
diff options
context:
space:
mode:
authorAndreas Klebinger <klebinger.andreas@gmx.at>2022-09-21 02:37:43 +0200
committerAndreas Klebinger <klebinger.andreas@gmx.at>2022-09-27 01:12:15 +0200
commit829609bde5eb0725c5bb80fbf6543811d5531123 (patch)
tree066ab5d8eb32d4730054032123ef10cf475c5028 /compiler/GHC/Data
parentc8ae3add11969b5128f34d02a5582c1f007cce5c (diff)
downloadhaskell-wip/andreask/opt-core-lint.tar.gz
Apply some tricks to speed up core lint.wip/andreask/opt-core-lint
Below are the noteworthy changes and if given their impact on compiler allocations for a type heavy module: * Use the oneShot trick on LintM * Use a unboxed tuple for the result of LintM: ~6% reduction * Avoid a thunk for the result of typeKind in lintType: ~5% reduction * lint_app: Don't allocate the error msg in the hot code path: ~4% reduction * lint_app: Eagerly force the in scope set: ~4% * nonDetCmpType: Try to short cut using reallyUnsafePtrEquality#: ~2% * lintM: Use a unboxed maybe for the `a` result: ~12% * lint_app: make go_app tail recursive to avoid allocating the go function as heap closure: ~7% * expandSynTyCon_maybe: Use a specialized data type For a less type heavy module like nofib/spectral/simple compiled with -O -dcore-lint allocations went down by ~24% and compile time by ~9%. ------------------------- Metric Decrease: T1969 -------------------------
Diffstat (limited to 'compiler/GHC/Data')
-rw-r--r--compiler/GHC/Data/Unboxed.hs50
1 files changed, 50 insertions, 0 deletions
diff --git a/compiler/GHC/Data/Unboxed.hs b/compiler/GHC/Data/Unboxed.hs
new file mode 100644
index 0000000000..dbd197351b
--- /dev/null
+++ b/compiler/GHC/Data/Unboxed.hs
@@ -0,0 +1,50 @@
+-- Unboxed counterparts to data structures
+
+{-# LANGUAGE UnboxedSums #-}
+{-# LANGUAGE UnboxedTuples #-}
+{-# LANGUAGE PatternSynonyms #-}
+{-# LANGUAGE UnliftedNewtypes #-}
+
+module GHC.Data.Unboxed (
+ MaybeUB(JustUB, NothingUB),
+ fmapMaybeUB, fromMaybeUB, apMaybeUB, maybeUB
+ ) where
+
+import GHC.Prelude hiding (Maybe(..), Either(..))
+
+-- | Like Maybe, but using unboxed sums.
+--
+-- Use with care. Using a unboxed maybe is not always a win
+-- in execution *time* even when allocations go down. So make
+-- sure to benchmark for execution time as well. If the difference
+-- in *runtime* for the compiler is too small to measure it's likely
+-- better to use a regular Maybe instead.
+--
+-- This is since it causes more function arguments to be passed, and
+-- potentially more variables to be captured by closures increasing
+-- closure size.
+newtype MaybeUB a = MaybeUB (# (# #) | a #)
+
+pattern JustUB :: a -> MaybeUB a
+pattern JustUB x = MaybeUB (# | x #)
+
+pattern NothingUB :: MaybeUB a
+pattern NothingUB = MaybeUB (# (# #) | #)
+
+{-# COMPLETE NothingUB, JustUB #-}
+
+fromMaybeUB :: a -> MaybeUB a -> a
+fromMaybeUB d NothingUB = d
+fromMaybeUB _ (JustUB x) = x
+
+apMaybeUB :: MaybeUB (a -> b) -> MaybeUB a -> MaybeUB b
+apMaybeUB (JustUB f) (JustUB x) = JustUB (f x)
+apMaybeUB _ _ = NothingUB
+
+fmapMaybeUB :: (a -> b) -> MaybeUB a -> MaybeUB b
+fmapMaybeUB _f NothingUB = NothingUB
+fmapMaybeUB f (JustUB x) = JustUB $ f x
+
+maybeUB :: b -> (a -> b) -> MaybeUB a -> b
+maybeUB _def f (JustUB x) = f x
+maybeUB def _f NothingUB = def