[Git][ghc/ghc][wip/T8095-spj] 2 commits: Two perf wibbles
Simon Peyton Jones
gitlab at gitlab.haskell.org
Wed Aug 5 11:58:22 UTC 2020
Simon Peyton Jones pushed to branch wip/T8095-spj at Glasgow Haskell Compiler / GHC
Commits:
72570fae by Simon Peyton Jones at 2020-08-05T11:53:56+01:00
Two perf wibbles
- - - - -
d35f1fef by Simon Peyton Jones at 2020-08-05T12:57:42+01:00
Further wibbles
- - - - -
3 changed files:
- compiler/GHC/Core/TyCo/FVs.hs
- compiler/GHC/Core/TyCo/Rep.hs
- compiler/GHC/Core/Unify.hs
Changes:
=====================================
compiler/GHC/Core/TyCo/FVs.hs
=====================================
@@ -268,13 +268,17 @@ type InScopeBndrs = TyCoVarSet
newtype TyCoAcc acc = TCA' { runTCA :: InScopeBndrs -> acc -> acc }
pattern TCA :: forall acc. (InScopeBndrs -> acc -> acc) -> TyCoAcc acc
+-- See GHC.Core.Unify Note [The one-shot state monad trick]
{-# COMPLETE TCA #-}
pattern TCA f <- TCA' f
where
TCA f = TCA' (oneShot f)
instance Semigroup (TyCoAcc acc) where
- (TCA f1) <> (TCA f2) = TCA (\is acc -> f2 is (f1 is acc))
+ (TCA f1) <> (TCA f2) = TCA (\is acc -> f1 is (f2 is acc))
+ -- It makes a perf difference going f1 (f2 acc), rather
+ -- than f2 (f1 acc). In a short-cutting situation (e.g.
+ -- a boolean accumulator, people put the short-cut first.
{-# INLINE (<>) #-}
instance Monoid (TyCoAcc acc) where
@@ -287,21 +291,25 @@ emptyInScope :: InScopeBndrs
emptyInScope = emptyVarSet
addTyCoVar :: TyCoVar -> TyCoAcc TyCoVarSet -> TyCoAcc TyCoVarSet
--- Add a variable tcv, and the extras, to the free vars unless
--- tcv is in the in-scope
--- or is already in the in-scope set-
--- The 'extras' start from an empty in-scope set;
--- see Note [Closing over free variable kinds]
-addTyCoVar tcv (TCA add_extras) = TCA add_it
+-- If 'tcv' is (a) in scope or (b) in the accumulator, then do nothing
+-- Otherwise:
+-- - Add 'tcv' to the accumulator, and
+-- - Run 'add_kind_fvs' starting from an empty in-scope set;
+-- see Note [Closing over free variable kinds]
+addTyCoVar tcv (TCA add_kind_fvs) = TCA add_it
where
add_it is acc
| tcv `elemVarSet` is = acc
| tcv `elemVarSet` acc = acc
- | otherwise = add_extras emptyVarSet (acc `extendVarSet` tcv)
+ | otherwise = add_kind_fvs emptyVarSet (acc `extendVarSet` tcv)
extendInScope :: TyCoVar -> TyCoAcc acc -> TyCoAcc acc
-- Gather the argument free vars in an empty in-scope set
-extendInScope tcv (TCA f) = TCA (\is acc -> f (is `extendVarSet` tcv) acc)
+extendInScope tcv (TCA f) = TCA (\is acc -> let !is' = is `extendVarSet` tcv
+ in f is' acc)
+ -- Making this strict removes a thunk, which reduces
+ -- allocation slightly; and the in-scope set is consulted
+ -- at every variable occurrence anyway
whenNotInScope :: TyCoVar -> TyCoAcc acc -> TyCoAcc acc
-- If tcv is not in the in-scope set, compute
=====================================
compiler/GHC/Core/TyCo/Rep.hs
=====================================
@@ -1819,11 +1819,15 @@ coercion witnessing the reduction. The reduction will proceed as follows:
~> S (S (S (Z + S Z))) |> CoAx2 (CoAx2 (CoAx2 Refl))
~> S (S (S (S (S Z)))) |> CoAx1 (CoAx2 (CoAx2 (CoAx2 Refl)))
-Moreover, coercions are really only useful when validating core transformations
-(i.e. by the Core Linter). To avoid burdening users who aren't linting with the
-cost of maintaining these structures, we replace coercions with placeholders
-("zap" them) them unless -dcore-lint is enabled. These placeholders are
-represented by UnivCo with ZappedProv provenance. Concretely, a coercion
+This looks linear, but the type arguments to CoAx2 are of size N, N-1
+etc; hence quadratic.
+
+Moreover, coercions are really only useful when validating core
+transformations (i.e. by the Core Linter). To avoid burdening users
+who aren't linting with the cost of maintaining these structures, we
+replace coercions with placeholders ("zap" them) them unless
+-dcore-lint is enabled. These placeholders are represented by UnivCo
+with ZappedProv provenance. Concretely, a coercion
co :: t1 ~r t2
@@ -1974,6 +1978,8 @@ keyword):
to avoid unsound floating. This means that the free variable lists of zapped
coercions loaded from interface files will lack top-level things (e.g. type
constructors) that appear only in the unzapped proof.
+
+* coercionSize gives a smaller size, of course.
-}
@@ -2077,6 +2083,7 @@ data TyCoFolder a
-- See Note [Coercion holes] in "GHC.Core.TyCo.Rep".
, tcf_tycobinder :: TyCoVar -> ArgFlag -> a -> a
+ -- ^ Modify the result of folding over the body of the forall
}
noView :: Type -> Maybe Type -- Simplest form of tcf_view
@@ -2107,7 +2114,7 @@ foldTyCo (TyCoFolder { tcf_view = view
go_ty (ForAllTy (Bndr tv vis) inner)
= go_ty (varType tv) `mappend` tycobinder tv vis (go_ty inner)
- -- Explicit recursion becuase using foldr builds a local
+ -- Explicit recursion because using foldr builds a local
-- loop (with free) and I'm not confident it'll be
-- lambda lifted in the end
go_tys [] = mempty
@@ -2147,8 +2154,9 @@ foldTyCo (TyCoFolder { tcf_view = view
go_prov (ZapCoProv cvs) = go_cvs (dVarSetElems cvs)
-- This use of dVarSetElems does a sort, which seems very
-- inefficient. But it seems required for determinism, alas.
- -- Unless the 'a' is instantiated with a non-deterministic kind
- -- of thing...could we exploit that somehow? ToDo.
+ -- Unless the 'a' is instantiated with a commutative monoid,
+ -- such as (VarSet -> VarSet) ...could we exploit that somehow?
+ -- ToDo.
go_cvs [] = mempty
go_cvs (cv:cvs) = covar cv `mappend` go_cvs cvs
=====================================
compiler/GHC/Core/Unify.hs
=====================================
@@ -1278,7 +1278,7 @@ and voila! In summary:
described here is applicable on a monad-by-monad basis under
programmer control.
-* Beware: itt changes the behaviour of
+* Beware: it changes the behaviour of
map (foo 3) xs
ToDo: explain what to do if you want to do this
-}
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c5deeadeb1f90b47beab9d91dcb5095b22581efd...d35f1fefd24846dee79a6572c6b957309814d3fd
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/c5deeadeb1f90b47beab9d91dcb5095b22581efd...d35f1fefd24846dee79a6572c6b957309814d3fd
You're receiving this email because of your account on gitlab.haskell.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-commits/attachments/20200805/d2493ef8/attachment-0001.html>
More information about the ghc-commits
mailing list