Get eqTypeRep to inline
authorDavid Feuer <david.feuer@gmail.com>
Thu, 15 Feb 2018 08:48:51 +0000 (03:48 -0500)
committerDavid Feuer <David.Feuer@gmail.com>
Thu, 15 Feb 2018 08:48:52 +0000 (03:48 -0500)
GHC didn't inline `eqTypeRep`, presumably because it ended up
being too big. This was unfortunate because it produces a
`Maybe`, which will almost always be scrutinized immediately.

Split `eqTypeRep` into a worker and a tiny wrapper, and mark the
wrapper `INLINABLE`. This change actually seems to reduce Core size,
at least in a small test.

Reviewers: hvr, bgamari, mpickering

Reviewed By: mpickering

Subscribers: mpickering, rwbarton, thomie, carter

GHC Trac Issues: #14790

Differential Revision: https://phabricator.haskell.org/D4405

libraries/base/Data/Typeable/Internal.hs

index a01a9ff..6c52cc5 100644 (file)
@@ -564,9 +564,17 @@ typeRepTyCon (TrFun {})               = typeRepTyCon $ typeRep @(->)
 eqTypeRep :: forall k1 k2 (a :: k1) (b :: k2).
              TypeRep a -> TypeRep b -> Maybe (a :~~: b)
 eqTypeRep a b
-  | typeRepFingerprint a == typeRepFingerprint b = Just (unsafeCoerce HRefl)
-  | otherwise                                    = Nothing
-
+  | sameTypeRep a b = Just (unsafeCoerce# HRefl)
+  | otherwise       = Nothing
+-- We want GHC to inline eqTypeRep to get rid of the Maybe
+-- in the usual case that it is scrutinized immediately. We
+-- split eqTypeRep into a worker and wrapper because otherwise
+-- it's much larger than anything we'd want to inline.
+{-# INLINABLE eqTypeRep #-}
+
+sameTypeRep :: forall k1 k2 (a :: k1) (b :: k2).
+               TypeRep a -> TypeRep b -> Bool
+sameTypeRep a b = typeRepFingerprint a == typeRepFingerprint b
 
 -------------------------------------------------------------
 --