[Git][ghc/ghc][wip/simplifier-tweaks] Two improvements to coercion optimisation

Simon Peyton Jones (@simonpj) gitlab at gitlab.haskell.org
Thu Jun 29 21:33:20 UTC 2023



Simon Peyton Jones pushed to branch wip/simplifier-tweaks at Glasgow Haskell Compiler / GHC


Commits:
74d7ab44 by Simon Peyton Jones at 2023-06-29T22:31:52+01:00
Two improvements to coercion optimisation

One (mkSymCo) makes a big difference in GHC.Read
The other (in zapSubstEnv) makes a big diffference in T18223

- - - - -


3 changed files:

- compiler/GHC/Core/Coercion.hs
- compiler/GHC/Core/Opt/Simplify/Env.hs
- compiler/GHC/Core/Utils.hs


Changes:

=====================================
compiler/GHC/Core/Coercion.hs
=====================================
@@ -1126,12 +1126,17 @@ mkUnivCo prov role ty1 ty2
 --   a kind of @t1 ~ t2@ becomes the kind @t2 ~ t1 at .
 mkSymCo :: Coercion -> Coercion
 
--- Do a few simple optimizations, but don't bother pushing occurrences
--- of symmetry to the leaves; the optimizer will take care of that.
-mkSymCo co | isReflCo co          = co
-mkSymCo    (SymCo co)             = co
-mkSymCo    (SubCo (SymCo co))     = SubCo co
-mkSymCo co                        = SymCo co
+-- Do a few simple optimizations, mainly to expose the underlying
+-- constructors to other 'mk' functions.  E.g.
+--   mkInstCo (mkSymCo (ForAllCo ...)) ty
+-- We want to push the SymCo inside the ForallCo, so that we can instantiate
+-- This can make a big difference.  E.g without coercion optimisation, GHC.Read
+-- totally explodes; but when we push Sym inside ForAll, it's fine.
+mkSymCo co | isReflCo co       = co
+mkSymCo (SymCo co)             = co
+mkSymCo (SubCo (SymCo co))     = SubCo co
+mkSymCo (ForAllCo tcv kco co)  = ForAllCo tcv (mkSymCo kco) (mkSymCo co)
+mkSymCo co                     = SymCo co
 
 -- | Create a new 'Coercion' by composing the two given 'Coercion's transitively.
 --   (co1 ; co2)


=====================================
compiler/GHC/Core/Opt/Simplify/Env.hs
=====================================
@@ -74,6 +74,7 @@ import GHC.Core.Type hiding     ( substTy, substTyVar, substTyVarBndr, substCo
                                 , extendTvSubst, extendCvSubst )
 import qualified GHC.Core.Coercion as Coercion
 import GHC.Core.Coercion hiding ( substCo, substCoVar, substCoVarBndr )
+import GHC.Core.Coercion.Opt( OptCoercionOpts(..) )
 import GHC.Platform ( Platform )
 import GHC.Types.Basic
 import GHC.Utils.Monad
@@ -616,7 +617,11 @@ setInScopeFromE.
 
 ---------------------
 zapSubstEnv :: SimplEnv -> SimplEnv
-zapSubstEnv env = env {seTvSubst = emptyVarEnv, seCvSubst = emptyVarEnv, seIdSubst = emptyVarEnv}
+zapSubstEnv env@(SimplEnv { seMode = mode })
+  = env { seTvSubst = emptyVarEnv, seCvSubst = emptyVarEnv, seIdSubst = emptyVarEnv
+        , seMode = mode { sm_co_opt_opts = OptCoercionOpts False } }
+    -- Zapping coercion optimisation here saves a /lot/ in T18223;
+    -- reduces compiled time allocation by more than 50%
 
 setSubstEnv :: SimplEnv -> TvSubstEnv -> CvSubstEnv -> SimplIdSubst -> SimplEnv
 setSubstEnv env tvs cvs ids = env { seTvSubst = tvs, seCvSubst = cvs, seIdSubst = ids }


=====================================
compiler/GHC/Core/Utils.hs
=====================================
@@ -263,41 +263,29 @@ mkPiMCo v (MCo co) = MCo (mkPiCo Representational v co)
 -- | Wrap the given expression in the coercion safely, dropping
 -- identity coercions and coalescing nested coercions
 mkCast :: HasDebugCallStack => CoreExpr -> CoercionR -> CoreExpr
-mkCast e co
-  | assertPpr (coercionRole co == Representational)
-              (text "coercion" <+> ppr co <+> text "passed to mkCast"
-               <+> ppr e <+> text "has wrong role" <+> ppr (coercionRole co)) $
-    isReflCo co
-  = e
-
-mkCast (Coercion e_co) co
-  | isCoVarType (coercionRKind co)
-       -- The guard here checks that g has a (~#) on both sides,
-       -- otherwise decomposeCo fails.  Can in principle happen
-       -- with unsafeCoerce
-  = Coercion (mkCoCast e_co co)
-
-mkCast (Cast expr co2) co
-  = warnPprTrace (let { from_ty = coercionLKind co;
-                        to_ty2  = coercionRKind co2 } in
-                     not (from_ty `eqType` to_ty2))
-             "mkCast"
-             (vcat ([ text "expr:" <+> ppr expr
-                   , text "co2:" <+> ppr co2
-                   , text "co:" <+> ppr co ])) $
-    mkCast expr (mkTransCo co2 co)
-
-mkCast (Tick t expr) co
-   = Tick t (mkCast expr co)
 
 mkCast expr co
-  = let from_ty = coercionLKind co in
-    warnPprTrace (not (from_ty `eqType` exprType expr))
+  = {- assertPpr (coercionRole co == Representational)
+              (text "coercion" <+> ppr co <+> text "passed to mkCast"
+               <+> ppr expr <+> text "has wrong role" <+> ppr (coercionRole co)) $
+    warnPprTrace (not (coercionLKind co `eqType` exprType expr))
           "Trying to coerce" (text "(" <> ppr expr
           $$ text "::" <+> ppr (exprType expr) <> text ")"
           $$ ppr co $$ ppr (coercionType co)
           $$ callStackDoc) $
-    (Cast expr co)
+    -}
+    case expr of
+      Cast expr co2 -> mkCast expr (mkTransCo co2 co)
+      Tick t expr   -> Tick t (mkCast expr co)
+
+      Coercion e_co | isCoVarType (coercionRKind co)
+         -- The guard here checks that g has a (~#) on both sides,
+         -- otherwise decomposeCo fails.  Can in principle happen
+         -- with unsafeCoerce
+                      -> Coercion (mkCoCast e_co co)
+
+      _ | isReflCo co -> expr
+        | otherwise   -> Cast expr co
 
 
 {- *********************************************************************



View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/74d7ab44eb2803994c5ec7cbffaf095805b4d031

-- 
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/74d7ab44eb2803994c5ec7cbffaf095805b4d031
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/20230629/d7fa41e0/attachment-0001.html>


More information about the ghc-commits mailing list