summaryrefslogtreecommitdiff
path: root/compiler/GHC/Core/Type.hs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/GHC/Core/Type.hs')
-rw-r--r--compiler/GHC/Core/Type.hs23
1 files changed, 19 insertions, 4 deletions
diff --git a/compiler/GHC/Core/Type.hs b/compiler/GHC/Core/Type.hs
index 17519d8dd5..8d41466d30 100644
--- a/compiler/GHC/Core/Type.hs
+++ b/compiler/GHC/Core/Type.hs
@@ -4,6 +4,7 @@
-- Type - public interface
{-# LANGUAGE FlexibleContexts, PatternSynonyms, ViewPatterns #-}
+{-# LANGUAGE MagicHash #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
{-# OPTIONS_GHC -Wno-incomplete-record-updates #-}
@@ -294,10 +295,10 @@ import GHC.Data.Pair
import GHC.Data.List.SetOps
import GHC.Types.Unique ( nonDetCmpUnique )
+import GHC.Base (reallyUnsafePtrEquality#)
import GHC.Data.Maybe ( orElse, expectJust, isJust )
import Control.Monad ( guard )
import qualified Data.Semigroup as S
--- import GHC.Utils.Trace
-- $type_classification
-- #type_classification#
@@ -556,7 +557,7 @@ expandTypeSynonyms ty
in_scope = mkInScopeSet (tyCoVarsOfType ty)
go subst (TyConApp tc tys)
- | Just (tenv, rhs, tys') <- expandSynTyCon_maybe tc expanded_tys
+ | ExpandsSyn tenv rhs tys' <- expandSynTyCon_maybe tc expanded_tys
= let subst' = mkTvSubst in_scope (mkVarEnv tenv)
-- Make a fresh substitution; rhs has nothing to
-- do with anything that has happened so far
@@ -2787,6 +2788,16 @@ comparing type variables is nondeterministic, note the call to nonDetCmpVar in
nonDetCmpTypeX.
See Note [Unique Determinism] for more details.
+Note [Type comparisons using object pointer comparisons]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Quite often we substitute the type from a definition site into
+occurances without a change. This means for code like:
+ \x -> (x,x,x)
+The type of every `x` will often be represented by a single object
+in the heap. We can take advantage of this by shortcutting the equality
+check if two types are represented by the same pointer under the hood.
+In some cases this reduces compiler allocations by ~2%.
+
Note [Computing equality on types]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
There are several places within GHC that depend on the precise choice of
@@ -2800,11 +2811,15 @@ See also Note [Non-trivial definitional equality] in GHC.Core.TyCo.Rep.
-}
nonDetCmpType :: Type -> Type -> Ordering
+nonDetCmpType !t1 !t2
+ -- See Note [Type comparisons using object pointer comparisons]
+ | 1# <- reallyUnsafePtrEquality# t1 t2
+ = EQ
nonDetCmpType (TyConApp tc1 []) (TyConApp tc2 []) | tc1 == tc2
= EQ
-nonDetCmpType t1 t2
+nonDetCmpType t1 t2 =
-- we know k1 and k2 have the same kind, because they both have kind *.
- = nonDetCmpTypeX rn_env t1 t2
+ nonDetCmpTypeX rn_env t1 t2
where
rn_env = mkRnEnv2 (mkInScopeSet (tyCoVarsOfTypes [t1, t2]))
{-# INLINE nonDetCmpType #-}