[Git][ghc/ghc][wip/mco-in-exprIsConApp] Try using MCoercion in exprIsConApp_maybe
Simon Peyton Jones (@simonpj)
gitlab at gitlab.haskell.org
Tue Apr 2 14:56:36 UTC 2024
Simon Peyton Jones pushed to branch wip/mco-in-exprIsConApp at Glasgow Haskell Compiler / GHC
Commits:
6d6e9d57 by Simon Peyton Jones at 2024-04-02T15:56:27+01:00
Try using MCoercion in exprIsConApp_maybe
This is just a simple refactor that makes exprIsConApp_maybe
a little bit more direct, simple, and efficient.
Metrics: compile_time/bytes allocated
geo. mean -0.1%
minimum -2.0%
maximum -0.0%
Not a big gain, but worthwhile given that the code is, if anything,
easier to grok.
- - - - -
2 changed files:
- compiler/GHC/Core/Opt/Arity.hs
- compiler/GHC/Core/SimpleOpt.hs
Changes:
=====================================
compiler/GHC/Core/Opt/Arity.hs
=====================================
@@ -3023,7 +3023,7 @@ pushCoercionIntoLambda in_scope x e co
| otherwise
= Nothing
-pushCoDataCon :: DataCon -> [CoreExpr] -> Coercion
+pushCoDataCon :: DataCon -> [CoreExpr] -> MCoercion
-> Maybe (DataCon
, [Type] -- Universal type args
, [CoreExpr]) -- All other args incl existentials
@@ -3033,10 +3033,20 @@ pushCoDataCon :: DataCon -> [CoreExpr] -> Coercion
-- where co :: (T t1 .. tn) ~ to_ty
-- The left-hand one must be a T, because exprIsConApp returned True
-- but the right-hand one might not be. (Though it usually will.)
-pushCoDataCon dc dc_args co
- | isReflCo co || from_ty `eqType` to_ty -- try cheap test first
- , let (univ_ty_args, rest_args) = splitAtList (dataConUnivTyVars dc) dc_args
- = Just (dc, map exprToType univ_ty_args, rest_args)
+pushCoDataCon dc dc_args MRefl = Just $! (push_dc_refl dc dc_args)
+pushCoDataCon dc dc_args (MCo co) = push_dc_gen dc dc_args co (coercionKind co)
+
+push_dc_refl :: DataCon -> [CoreExpr] -> (DataCon, [Type], [CoreExpr])
+push_dc_refl dc dc_args
+ = (dc, map exprToType univ_ty_args, rest_args)
+ where
+ !(univ_ty_args, rest_args) = splitAtList (dataConUnivTyVars dc) dc_args
+
+push_dc_gen :: DataCon -> [CoreExpr] -> Coercion -> Pair Type
+ -> Maybe (DataCon, [Type], [CoreExpr])
+push_dc_gen dc dc_args co (Pair from_ty to_ty)
+ | from_ty `eqType` to_ty -- try cheap test first
+ = Just $! (push_dc_refl dc dc_args)
| Just (to_tc, to_tc_arg_tys) <- splitTyConApp_maybe to_ty
, to_tc == dataConTyCon dc
@@ -3082,8 +3092,6 @@ pushCoDataCon dc dc_args co
| otherwise
= Nothing
- where
- Pair from_ty to_ty = coercionKind co
collectBindersPushingCo :: CoreExpr -> ([Var], CoreExpr)
-- Collect lambda binders, pushing coercions inside if possible
=====================================
compiler/GHC/Core/SimpleOpt.hs
=====================================
@@ -1211,7 +1211,7 @@ data-con wrappers, and that cure would be worse than the disease.
This Note exists solely to document the problem.
-}
-data ConCont = CC [CoreExpr] Coercion
+data ConCont = CC [CoreExpr] MCoercion
-- Substitution already applied
-- | Returns @Just ([b1..bp], dc, [t1..tk], [x1..xn])@ if the argument
@@ -1233,7 +1233,7 @@ exprIsConApp_maybe :: HasDebugCallStack
=> InScopeEnv -> CoreExpr
-> Maybe (InScopeSet, [FloatBind], DataCon, [Type], [CoreExpr])
exprIsConApp_maybe ise@(ISE in_scope id_unf) expr
- = go (Left in_scope) [] expr (CC [] (mkRepReflCo (exprType expr)))
+ = go (Left in_scope) [] expr (CC [] MRefl)
where
go :: Either InScopeSet Subst
-- Left in-scope means "empty substitution"
@@ -1246,14 +1246,12 @@ exprIsConApp_maybe ise@(ISE in_scope id_unf) expr
go subst floats (Tick t expr) cont
| not (tickishIsCode t) = go subst floats expr cont
- go subst floats (Cast expr co1) (CC args co2)
+ go subst floats (Cast expr co1) (CC args m_co2)
| Just (args', m_co1') <- pushCoArgs (subst_co subst co1) args
-- See Note [Push coercions in exprIsConApp_maybe]
- = case m_co1' of
- MCo co1' -> go subst floats expr (CC args' (co1' `mkTransCo` co2))
- MRefl -> go subst floats expr (CC args' co2)
+ = go subst floats expr (CC args' (m_co1' `mkTransMCo` m_co2))
- go subst floats (App fun arg) (CC args co)
+ go subst floats (App fun arg) (CC args mco)
| let arg_type = exprType arg
, not (isTypeArg arg) && needsCaseBinding arg_type arg
-- An unlifted argument that’s not ok for speculation must not simply be
@@ -1276,17 +1274,17 @@ exprIsConApp_maybe ise@(ISE in_scope id_unf) expr
bndr = uniqAway (subst_in_scope subst) (mkWildValBinder ManyTy arg_type)
float = FloatCase arg' bndr DEFAULT []
subst' = subst_extend_in_scope subst bndr
- in go subst' (float:floats) fun (CC (Var bndr : args) co)
+ in go subst' (float:floats) fun (CC (Var bndr : args) mco)
| otherwise
- = go subst floats fun (CC (subst_expr subst arg : args) co)
+ = go subst floats fun (CC (subst_expr subst arg : args) mco)
- go subst floats (Lam bndr body) (CC (arg:args) co)
+ go subst floats (Lam bndr body) (CC (arg:args) mco)
| do_beta_by_substitution bndr arg
- = go (extend subst bndr arg) floats body (CC args co)
+ = go (extend subst bndr arg) floats body (CC args mco)
| otherwise
= let (subst', bndr') = subst_bndr subst bndr
float = FloatLet (NonRec bndr' arg)
- in go subst' (float:floats) body (CC args co)
+ in go subst' (float:floats) body (CC args mco)
go subst floats (Let (NonRec bndr rhs) expr) cont
| not (isJoinId bndr)
@@ -1311,12 +1309,12 @@ exprIsConApp_maybe ise@(ISE in_scope id_unf) expr
(lookupIdSubst sub v)
cont
- go (Left in_scope) floats (Var fun) cont@(CC args co)
+ go (Left in_scope) floats (Var fun) cont@(CC args mco)
| Just con <- isDataConWorkId_maybe fun
, count isValArg args == idArity fun
= succeedWith in_scope floats $
- pushCoDataCon con args co
+ pushCoDataCon con args mco
-- Look through data constructor wrappers: they inline late (See Note
-- [Activation for data constructor wrappers]) but we want to do
@@ -1336,7 +1334,7 @@ exprIsConApp_maybe ise@(ISE in_scope id_unf) expr
-- simplOptExpr initialises the in-scope set with exprFreeVars,
-- but that doesn't account for DFun unfoldings
= succeedWith in_scope floats $
- pushCoDataCon con (map (substExpr subst) dfun_args) co
+ pushCoDataCon con (map (substExpr subst) dfun_args) mco
-- Look through unfoldings, but only arity-zero one;
-- if arity > 0 we are effectively inlining a function call,
@@ -1354,7 +1352,7 @@ exprIsConApp_maybe ise@(ISE in_scope id_unf) expr
, [arg] <- args
, Just (LitString str) <- exprIsLiteral_maybe ise arg
= succeedWith in_scope floats $
- dealWithStringLiteral fun str co
+ dealWithStringLiteral fun str mco
where
unfolding = id_unf fun
extend_in_scope unf_fvs
@@ -1404,15 +1402,15 @@ exprIsConApp_maybe ise@(ISE in_scope id_unf) expr
-- See Note [exprIsConApp_maybe on literal strings]
-dealWithStringLiteral :: Var -> BS.ByteString -> Coercion
+dealWithStringLiteral :: Var -> BS.ByteString -> MCoercion
-> Maybe (DataCon, [Type], [CoreExpr])
-- This is not possible with user-supplied empty literals, GHC.Core.Make.mkStringExprFS
-- turns those into [] automatically, but just in case something else in GHC
-- generates a string literal directly.
-dealWithStringLiteral fun str co =
+dealWithStringLiteral fun str mco =
case utf8UnconsByteString str of
- Nothing -> pushCoDataCon nilDataCon [Type charTy] co
+ Nothing -> pushCoDataCon nilDataCon [Type charTy] mco
Just (char, charTail) ->
let char_expr = mkConApp charDataCon [mkCharLit char]
-- In singleton strings, just add [] instead of unpackCstring# ""#.
@@ -1421,7 +1419,7 @@ dealWithStringLiteral fun str co =
else App (Var fun)
(Lit (LitString charTail))
- in pushCoDataCon consDataCon [Type charTy, char_expr, rest] co
+ in pushCoDataCon consDataCon [Type charTy, char_expr, rest] mco
{-
Note [Unfolding DFuns]
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6d6e9d570898331805b63620b8241ff8970fcf0a
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/6d6e9d570898331805b63620b8241ff8970fcf0a
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/20240402/25f218e4/attachment-0001.html>
More information about the ghc-commits
mailing list