[commit: ghc] wip/tdammers/D4394-squash: Improve coercionKind(Role) perfomance (8f4ee8d)
git at git.haskell.org
git at git.haskell.org
Fri Apr 20 08:39:21 UTC 2018
Repository : ssh://git@git.haskell.org/ghc
On branch : wip/tdammers/D4394-squash
Link : http://ghc.haskell.org/trac/ghc/changeset/8f4ee8d5a349bc2395eafb4f45fd26e7f547f1d8/ghc
>---------------------------------------------------------------
commit 8f4ee8d5a349bc2395eafb4f45fd26e7f547f1d8
Author: Tobias Dammers <tdammers at gmail.com>
Date: Wed Jan 24 16:05:55 2018 +0100
Improve coercionKind(Role) perfomance
By separating / refactoring the coercionKind and coercionRole functions,
we can avoid unnecessary calculations and avoid some costly recursions.
See #11735.
>---------------------------------------------------------------
8f4ee8d5a349bc2395eafb4f45fd26e7f547f1d8
compiler/types/Coercion.hs | 82 ++++++++++++++++------------------------------
1 file changed, 29 insertions(+), 53 deletions(-)
diff --git a/compiler/types/Coercion.hs b/compiler/types/Coercion.hs
index c8105d0..4cc8cef 100644
--- a/compiler/types/Coercion.hs
+++ b/compiler/types/Coercion.hs
@@ -1755,6 +1755,8 @@ substitute for them all at once. Remarkably, for Trac #11735 this single
change reduces /total/ compile time by a factor of more than ten.
-}
+=======
+>>>>>>> Applying patch suggested in #11735 to improve coercionKind perf
-- | Apply 'coercionKind' to multiple 'Coercion's
coercionKinds :: [Coercion] -> Pair [Type]
@@ -1763,77 +1765,51 @@ coercionKinds tys = sequenceA $ map coercionKind tys
-- | Get a coercion's kind and role.
-- Why both at once? See Note [Computing a coercion kind and role]
coercionKindRole :: Coercion -> (Pair Type, Role)
-coercionKindRole = go
+coercionKindRole co = (coercionKind co, coercionRole co)
+
+-- | Retrieve the role from a coercion.
+coercionRole :: Coercion -> Role
+coercionRole = go
where
- go (Refl r ty) = (Pair ty ty, r)
- go (TyConAppCo r tc cos)
- = (mkTyConApp tc <$> (sequenceA $ map coercionKind cos), r)
- go (AppCo co1 co2)
- = let (tys1, r1) = go co1 in
- (mkAppTy <$> tys1 <*> coercionKind co2, r1)
- go (ForAllCo tv1 k_co co)
- = let Pair _ k2 = coercionKind k_co
- tv2 = setTyVarKind tv1 k2
- (Pair ty1 ty2, r) = go co
- subst = zipTvSubst [tv1] [TyVarTy tv2 `mkCastTy` mkSymCo k_co]
- ty2' = substTyAddInScope subst ty2 in
- -- We need free vars of ty2 in scope to satisfy the invariant
- -- from Note [The substitution invariant]
- -- This is doing repeated substitutions and probably doesn't
- -- need to, see #11735
- (mkInvForAllTy <$> Pair tv1 tv2 <*> Pair ty1 ty2', r)
- go (FunCo r co1 co2)
- = (mkFunTy <$> coercionKind co1 <*> coercionKind co2, r)
+ go (Refl r _) = r
+ go (TyConAppCo r _ _) = r
+ go (AppCo co1 _) = go co1
+ go (ForAllCo _ _ co) = go co
+ go (FunCo r _ _) = r
go (CoVarCo cv) = go_var cv
go (HoleCo h) = go_var (coHoleCoVar h)
- go co@(AxiomInstCo ax _ _) = (coercionKind co, coAxiomRole ax)
- go (UnivCo _ r ty1 ty2) = (Pair ty1 ty2, r)
- go (SymCo co) = first swap $ go co
- go (TransCo co1 co2)
- = let (tys1, r) = go co1 in
- (Pair (pFst tys1) (pSnd $ coercionKind co2), r)
+ go (AxiomInstCo ax _ _) = coAxiomRole ax
+ go (UnivCo _ r _ _) = r
+ go (SymCo co) = go co
+ go (TransCo co1 co2) = go co1
go (NthCo d co)
| Just (tv1, _) <- splitForAllTy_maybe ty1
= ASSERT( d == 0 )
- let (tv2, _) = splitForAllTy ty2 in
- (tyVarKind <$> Pair tv1 tv2, Nominal)
+ Nominal
| otherwise
= let (tc1, args1) = splitTyConApp ty1
(_tc2, args2) = splitTyConApp ty2
in
ASSERT2( tc1 == _tc2, ppr d $$ ppr tc1 $$ ppr _tc2 )
- ((`getNth` d) <$> Pair args1 args2, nthRole r tc1 d)
+ (nthRole r tc1 d)
where
- (Pair ty1 ty2, r) = go co
- go co@(LRCo {}) = (coercionKind co, Nominal)
- go (InstCo co arg) = go_app co [arg]
- go (CoherenceCo co1 co2)
- = let (Pair t1 t2, r) = go co1 in
- (Pair (t1 `mkCastTy` co2) t2, r)
- go co@(KindCo {}) = (coercionKind co, Nominal)
- go (SubCo co) = (coercionKind co, Representational)
- go co@(AxiomRuleCo ax _) = (coercionKind co, coaxrRole ax)
+ (Pair ty1 ty2, r) = coercionKindRole co
+ go (LRCo {}) = Nominal
+ go (InstCo co arg) = go_app co
+ go (CoherenceCo co1 _) = go co1
+ go (KindCo {}) = Nominal
+ go (SubCo _) = Representational
+ go (AxiomRuleCo ax _) = coaxrRole ax
-------------
- go_var cv = (coVarTypes cv, coVarRole cv)
+ go_var = coVarRole
-------------
- go_app :: Coercion -> [Coercion] -> (Pair Type, Role)
- -- Collect up all the arguments and apply all at once
- -- See Note [Nested InstCos]
- go_app (InstCo co arg) args = go_app co (arg:args)
- go_app co args
- = let (pair, r) = go co in
- (piResultTys <$> pair <*> (sequenceA $ map coercionKind args), r)
-
--- | Retrieve the role from a coercion.
-coercionRole :: Coercion -> Role
-coercionRole = snd . coercionKindRole
- -- There's not a better way to do this, because NthCo needs the *kind*
- -- and role of its argument. Luckily, laziness should generally avoid
- -- the need for computing kinds in other cases.
+ go_app :: Coercion -> Role
+ go_app (InstCo co arg) = go_app co
+ go_app co = go co
{-
Note [Nested InstCos]
More information about the ghc-commits
mailing list