[Git][ghc/ghc][master] 2 commits: Allow CPR on unrestricted constructors

Marge Bot (@marge-bot) gitlab at gitlab.haskell.org
Wed May 31 12:34:51 UTC 2023



Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC


Commits:
981e5e11 by Arnaud Spiwack at 2023-05-31T08:34:33-04:00
Allow CPR on unrestricted constructors

Per the new `Note [Linting linearity]`, we want optimisations over
trying to preserve linearity. This will allow CPR to handle `Ur`, in
particular.

- - - - -
bf9344d2 by Arnaud Spiwack at 2023-05-31T08:34:33-04:00
Push coercions across multiplicity boundaries

Per the new `Note [Linting linearity]`, we want optimisations over
trying to preserve linearity. This will avoid preventing inlinings and
reductions and make linear programs more efficient.

- - - - -


3 changed files:

- compiler/GHC/Builtin/Types/Prim.hs
- compiler/GHC/Core/Opt/Arity.hs
- compiler/GHC/Core/Opt/WorkWrap/Utils.hs


Changes:

=====================================
compiler/GHC/Builtin/Types/Prim.hs
=====================================
@@ -763,6 +763,11 @@ Wrinkles
 
 (W3) We need a TypeOrConstraint flag in LitRubbish.
 
+(W4) In the CPR transformation, we can't unbox constructors with constraint
+     arguments because unboxed tuples (# …, … #) currently only supports fields
+     of type TYPE rr. See (CPR2) in Note [Which types are unboxed?] in
+     GHC.Core.Opt.WorkWrap.Utils.
+
 Note [Type and Constraint are not apart]
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 Type and Constraint are not equal (eqType) but they are not /apart/


=====================================
compiler/GHC/Core/Opt/Arity.hs
=====================================
@@ -2863,18 +2863,11 @@ pushCoValArg co
   = Just (MRefl, MRefl)
 
   | isFunTy tyL
-  , (co_mult, co1, co2) <- decomposeFunCo co
+  , (_, co1, co2) <- decomposeFunCo co
       -- If   co  :: (tyL1 -> tyL2) ~ (tyR1 -> tyR2)
       -- then co1 :: tyL1 ~ tyR1
       --      co2 :: tyL2 ~ tyR2
 
-  , isReflexiveCo co_mult
-    -- We can't push the coercion in the case where co_mult isn't reflexivity:
-    -- it could be an unsafe axiom, and losing this information could yield
-    -- ill-typed terms. For instance (fun x ::(1) Int -> (fun _ -> () |> co) x)
-    -- with co :: (Int -> ()) ~ (Int %1 -> ()), would reduce to (fun x ::(1) Int
-    -- -> (fun _ ::(Many) Int -> ()) x) which is ill-typed.
-
   , typeHasFixedRuntimeRep new_arg_ty
     -- We can't push the coercion inside if it would give rise to
     -- a representation-polymorphic argument.
@@ -2907,10 +2900,7 @@ pushCoercionIntoLambda in_scope x e co
     , Pair s1s2 t1t2 <- coercionKind co
     , Just {}              <- splitFunTy_maybe s1s2
     , Just (_, w1, t1,_t2) <- splitFunTy_maybe t1t2
-    , (co_mult, co1, co2)  <- decomposeFunCo co
-    , isReflexiveCo co_mult
-      -- We can't push the coercion in the case where co_mult isn't
-      -- reflexivity. See pushCoValArg for more details.
+    , (_, co1, co2)  <- decomposeFunCo co
     , typeHasFixedRuntimeRep t1
       -- We can't push the coercion into the lambda if it would create
       -- a representation-polymorphic binder.


=====================================
compiler/GHC/Core/Opt/WorkWrap/Utils.hs
=====================================
@@ -674,13 +674,11 @@ canUnboxResult fam_envs ty cpr
                                 -- type constructor via a .hs-boot file (#8743)
   , let dc = dcs `getNth` (con_tag - fIRST_TAG)
   , null (dataConExTyCoVars dc) -- no existentials;
-                                -- See Note [Which types are unboxed?]
+                                -- See (CPR1) in Note [Which types are unboxed?]
                                 -- and GHC.Core.Opt.CprAnal.argCprType
                                 -- where we also check this.
-  , all isLinear (dataConInstArgTys dc tc_args)
-  -- Deactivates CPR worker/wrapper splits on constructors with non-linear
-  -- arguments, for the moment, because they require unboxed tuple with variable
-  -- multiplicity fields.
+  , null (dataConTheta dc) -- no constraints;
+                           -- See (CPR2) in Note [Which types are unboxed?]
   = DoUnbox (DataConPatContext { dcpc_dc = dc, dcpc_tc_args = tc_args
                                , dcpc_co = co, dcpc_args = arg_cprs })
 
@@ -691,13 +689,6 @@ canUnboxResult fam_envs ty cpr
     -- See Note [non-algebraic or open body type warning]
     open_body_ty_warning = warnPprTrace True "canUnboxResult: non-algebraic or open body type" (ppr ty) Nothing
 
-isLinear :: Scaled a -> Bool
-isLinear (Scaled w _ ) =
-  case w of
-    OneTy -> True
-    _     -> False
-
-
 {- Note [Which types are unboxed?]
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 Worker/wrapper will unbox
@@ -719,25 +710,28 @@ Worker/wrapper will unbox
        * is not recursive (as per 'isRecDataCon')
        * (might have multiple constructors, in contrast to (1))
        * the applied data constructor *does not* bind existentials
+       * nor does it bind constraints (equalities or dictionaries)
      We can transform
      > f x y = let ... in D a b
      to
      > $wf x y = let ... in (# a, b #)
      via 'mkWWcpr'.
 
-     NB: We don't allow existentials for CPR W/W, because we don't have unboxed
-     dependent tuples (yet?). Otherwise, we could transform
+     (CPR1).  We don't allow existentials for CPR W/W, because we don't have
+     unboxed dependent tuples (yet?). Otherwise, we could transform
      > f x y = let ... in D @ex (a :: ..ex..) (b :: ..ex..)
      to
      > $wf x y = let ... in (# @ex, (a :: ..ex..), (b :: ..ex..) #)
 
+     (CPR2) we don't allow constraints for CPR W/W, because an unboxed tuple
+     contains types of kind `TYPE rr`, but not of kind `CONSTRAINT rr`.
+     This is annoying; there is no real reason for this except that we don't
+     have TYPE/CONSTAINT polymorphism.  See Note [TYPE and CONSTRAINT]
+     in GHC.Builtin.Types.Prim.
+
 The respective tests are in 'canUnboxArg' and
 'canUnboxResult', respectively.
 
-Note that the data constructor /can/ have evidence arguments: equality
-constraints, type classes etc.  So it can be GADT.  These evidence
-arguments are simply value arguments, and should not get in the way.
-
 Note [mkWWstr and unsafeCoerce]
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 By using unsafeCoerce, it is possible to make the number of demands fail to



View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6629f1c58a714405ba94e93d54a9c471f6f62914...bf9344d24157986ea013210e7cb9a5953670e0e2

-- 
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/6629f1c58a714405ba94e93d54a9c471f6f62914...bf9344d24157986ea013210e7cb9a5953670e0e2
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/20230531/62549077/attachment-0001.html>


More information about the ghc-commits mailing list