[Git][ghc/ghc][wip/or-pats] Deleted 1 commit: Play around with Match
David (@knothed)
gitlab at gitlab.haskell.org
Mon Jun 19 10:51:04 UTC 2023
David pushed to branch wip/or-pats at Glasgow Haskell Compiler / GHC
WARNING: The push did not contain any new commits, but force pushed to delete the commits and changes below.
Deleted commits:
c93c3ddd by David Knothe at 2023-06-09T14:23:36+02:00
Play around with Match
- - - - -
7 changed files:
- compiler/GHC/HsToCore/Expr.hs
- compiler/GHC/HsToCore/Match.hs
- compiler/GHC/HsToCore/Match.hs-boot
- compiler/GHC/HsToCore/Match/Constructor.hs
- compiler/GHC/HsToCore/Match/Literal.hs
- compiler/GHC/HsToCore/Monad.hs
- compiler/GHC/HsToCore/Utils.hs
Changes:
=====================================
compiler/GHC/HsToCore/Expr.hs
=====================================
@@ -204,9 +204,7 @@ dsUnliftedBind (PatBind { pat_lhs = pat, pat_rhs = grhss
do { match_nablas <- pmcGRHSs PatBindGuards grhss
; rhs <- dsGuarded grhss ty match_nablas
; let upat = unLoc pat
- eqn = EqnInfo { eqn_pats = [upat],
- eqn_orig = FromSource,
- eqn_rhs = cantFailMatchResult body }
+ eqn = EqnMatch upat FromSource (EqnDone $ cantFailMatchResult body)
; var <- selectMatchVar ManyTy upat
-- `var` will end up in a let binder, so the multiplicity
-- doesn't matter.
=====================================
compiler/GHC/HsToCore/Match.hs
=====================================
@@ -21,13 +21,15 @@ module GHC.HsToCore.Match
)
where
+import GHC.Stack
import GHC.Prelude
import GHC.Platform
import Language.Haskell.Syntax.Basic (Boxity(..))
import {-#SOURCE#-} GHC.HsToCore.Expr (dsExpr)
-
+import Data.List (intercalate)
+import Debug.Trace
import GHC.Types.Basic ( Origin(..), isGenerated )
import GHC.Types.SourceText
import GHC.Driver.DynFlags
@@ -178,9 +180,20 @@ with External names (#13043).
See also Note [Localise pattern binders] in GHC.HsToCore.Utils
-}
+-- input: equationInfo
+-- output: do call to `match` (recursing into matchNew) but group the first var beforehand
+-- for the call to match, construct a EqnInfo with only a single pattern and put the recursive call into the eqn_rhs.
+
+--matchNew :: [MatchId]
+-- -> Type
+-- -> [EquationInfo]
+-- -> Dsm (MatchResult CoreExpr)
+
+
+
type MatchId = Id -- See Note [Match Ids]
-match :: [MatchId] -- ^ Variables rep\'ing the exprs we\'re matching with
+match :: HasCallStack => [MatchId] -- ^ Variables rep\'ing the exprs we\'re matching with
-- ^ See Note [Match Ids]
--
-- ^ Note that the Match Ids carry not only a name, but
@@ -192,11 +205,7 @@ match :: [MatchId] -- ^ Variables rep\'ing the exprs we\'re matching with
match [] ty eqns
= assertPpr (not (null eqns)) (ppr ty) $
- return (foldr1 combineMatchResults match_results)
- where
- match_results = [ assert (null (eqn_pats eqn)) $
- eqn_rhs eqn
- | eqn <- eqns ]
+ combineRHSs (NEL.fromList eqns)
match (v:vs) ty eqns -- Eqns *can* be empty
= assertPpr (all (isInternalName . idName) vars) (ppr vars) $
@@ -207,11 +216,19 @@ match (v:vs) ty eqns -- Eqns *can* be empty
; (aux_binds, tidy_eqns) <- mapAndUnzipM (tidyEqnInfo v) eqns
-- Group the equations and match each group in turn
; let grouped = groupEquations platform tidy_eqns
+ -- ; grouped' <- mapM (moveGroupVarsIntoRhs vs ty) grouped
+ ; let grouped' = grouped
+
+ -- ; traceM ("Before moving: " ++ show (length grouped) ++ " groups:")
+ -- ; testPrint grouped
+ -- ; traceM ("After moving: " ++ show (length grouped') ++ " groups:")
+ -- ; testPrint grouped'
+ -- ; traceM ""
-- print the view patterns that are commoned up to help debug
- ; whenDOptM Opt_D_dump_view_pattern_commoning (debug grouped)
+ ; whenDOptM Opt_D_dump_view_pattern_commoning (debug grouped')
- ; match_results <- match_groups grouped
+ ; match_results <- match_groups grouped'
; return $ foldr (.) id aux_binds <$>
foldr1 combineMatchResults match_results
}
@@ -239,6 +256,7 @@ match (v:vs) ty eqns -- Eqns *can* be empty
PgBang -> matchBangs vars ty (dropGroup eqns)
PgCo {} -> matchCoercion vars ty (dropGroup eqns)
PgView {} -> matchView vars ty (dropGroup eqns)
+ PgDistinct-> combineRHSs (dropGroup eqns)
PgOr -> matchOr vars ty eq -- every or-pattern makes up a single PgOr group
where eqns' = NEL.toList eqns
ne l = case NEL.nonEmpty l of
@@ -247,7 +265,19 @@ match (v:vs) ty eqns -- Eqns *can* be empty
-- FIXME: we should also warn about view patterns that should be
-- commoned up but are not
-
+{-
+ testPrint :: Applicative f => [NonEmpty (PatGroup, EquationInfo)] -> f ()
+ testPrint groups =
+ traceM $ intercalate "\n" $ map
+ (\group -> intercalate " ; " $ map
+ (\(pg, eqn) -> (show pg ++ " " ++ (intercalate " " $ map (showSDocUnsafe . pprLPat . mklpat) (pats eqn))))
+ (NEL.toList group))
+ groups
+ where
+ pats (EqnMatch pat _ rest) = pat : pats rest
+ pats (EqnDone _) = []
+ mklpat pat = L noSrcSpanA pat
+-}
-- print some stuff to see what's getting grouped
-- use -dppr-debug to see the resolution of overloaded literals
debug eqns =
@@ -267,6 +297,10 @@ matchEmpty var res_ty
mk_seq fail = return $ mkWildCase (Var var) (idScaledType var) res_ty
[Alt DEFAULT [] fail]
+
+combineRHSs :: NonEmpty EquationInfo -> DsM (MatchResult CoreExpr)
+combineRHSs eqns = return $ foldr1 combineMatchResults $ map (\(EqnDone rhs) -> rhs) (NEL.toList eqns)
+
matchVariables :: NonEmpty MatchId -> Type -> NonEmpty EquationInfo -> DsM (MatchResult CoreExpr)
-- Real true variables, just like in matchVar, SLPJ p 94
-- No binding to do: they'll all be wildcards by now (done in tidy)
@@ -319,12 +353,11 @@ matchOr (var :| vars) ty eqn = do {
; match [var] ty or_eqns -- todo: not if pats is empty
})
} where
- singleEqn expr (L _ pat) = EqnInfo { eqn_pats = [pat], eqn_orig = FromSource, eqn_rhs = pure expr }
+ singleEqn expr (L _ pat) = EqnMatch pat FromSource (EqnDone $ pure expr)
-- decompose the first pattern and leave the rest alone
decomposeFirstPat :: (Pat GhcTc -> Pat GhcTc) -> EquationInfo -> EquationInfo
-decomposeFirstPat extractpat (eqn@(EqnInfo { eqn_pats = pat : pats }))
- = eqn { eqn_pats = extractpat pat : pats}
+decomposeFirstPat extract (EqnMatch pat orig rest) = EqnMatch (extract pat) orig rest
decomposeFirstPat _ _ = panic "decomposeFirstPat"
getCoPat, getBangPat, getViewPat :: Pat GhcTc -> Pat GhcTc
@@ -408,7 +441,19 @@ only these which can be assigned a PatternGroup (see patGroup).
-}
-tidyEqnInfo :: Id -> EquationInfo
+{-
+moveGroupVarsIntoRhs :: HasCallStack => [Id] -> Type -> NonEmpty (PatGroup, EquationInfo) -> DsM (NonEmpty (PatGroup, EquationInfo))
+moveGroupVarsIntoRhs vs ty group = do
+ let (gp, eq) = NEL.head group
+ case eq of
+ EqnDone _ -> return group
+ EqnMatch pat orig _ -> do
+ let rest = NEL.map (\(_, EqnMatch _ _ rest) -> rest) group
+ rhs <- match vs ty (NEL.toList rest)
+ return $ NEL.singleton (gp, EqnMatch pat orig (EqnDone rhs))
+-}
+
+tidyEqnInfo :: HasCallStack => Id -> EquationInfo
-> DsM (DsWrapper, EquationInfo)
-- DsM'd because of internal call to dsLHsBinds
-- and mkSelectorBinds.
@@ -418,12 +463,11 @@ tidyEqnInfo :: Id -> EquationInfo
-- POST CONDITION: head pattern in the EqnInfo is
-- one of these for which patGroup is defined.
-tidyEqnInfo _ (EqnInfo { eqn_pats = [] })
- = panic "tidyEqnInfo"
+tidyEqnInfo _ (EqnDone r) = return (idDsWrapper, EqnDone r)
-tidyEqnInfo v eqn@(EqnInfo { eqn_pats = pat : pats, eqn_orig = orig })
- = do { (wrap, pat') <- tidy1 v orig pat
- ; return (wrap, eqn { eqn_pats = pat' : pats }) }
+tidyEqnInfo v (EqnMatch pat orig rest) = do
+ (wrap, pat') <- tidy1 v orig pat
+ return (wrap, EqnMatch pat' orig rest)
tidy1 :: Id -- The Id being scrutinised
-> Origin -- Was this a pattern the user wrote?
@@ -833,9 +877,7 @@ matchWrapper ctxt scrs (MG { mg_alts = L _ matches
-- from that knowledge (#18533)
; match_result <- updPmNablas pat_nablas $
dsGRHSs ctxt grhss rhs_ty rhss_nablas
- ; return EqnInfo { eqn_pats = upats
- , eqn_orig = FromSource
- , eqn_rhs = match_result } }
+ ; return $ mkEqnInfo upats FromSource match_result }
discard_warnings_if_generated orig =
if isGenerated orig
@@ -972,9 +1014,9 @@ matchSinglePatVar var mb_scrut ctx pat ty match_result
addCoreScrutTmCs (maybeToList mb_scrut) [var] $
pmcPatBind (DsMatchContext ctx locn) var (unLoc pat)
- ; let eqn_info = EqnInfo { eqn_pats = [unLoc (decideBangHood dflags pat)]
- , eqn_orig = FromSource
- , eqn_rhs = match_result }
+ ; let eqn_info = EqnMatch (unLoc (decideBangHood dflags pat))
+ FromSource
+ (EqnDone match_result)
; match [var] ty [eqn_info] }
@@ -1002,8 +1044,18 @@ data PatGroup
| PgView (LHsExpr GhcTc) -- view pattern (e -> p):
-- the LHsExpr is the expression e
Type -- the Type is the type of p (equivalently, the result type of e)
+ | PgDistinct -- Group equations which are Done: no further grouping can be done with them
| PgOr -- Or pattern
+instance Show PatGroup where
+ show PgAny = "PgAny"
+ show (PgCon _) = "PgCon"
+ show (PgLit _) = "PgLit"
+ show (PgView _ _) = "PgView"
+ show PgOr = "PgOr"
+ show PgDistinct = "PgDistinct"
+ show _ = "PgOther"
+
{- Note [Don't use Literal for PgN]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Previously we had, as PatGroup constructors
@@ -1030,7 +1082,7 @@ groupEquations :: Platform -> [EquationInfo] -> [NonEmpty (PatGroup, EquationInf
-- (b) none of the gi are empty
-- The ordering of equations is unchanged
groupEquations platform eqns
- = NEL.groupBy same_gp $ [(patGroup platform (firstPat eqn), eqn) | eqn <- eqns]
+ = NEL.groupBy same_gp $ [(patGroup platform (maybeFirstPat eqn), eqn) | eqn <- eqns]
-- comprehension on NonEmpty
where
same_gp :: (PatGroup,EquationInfo) -> (PatGroup,EquationInfo) -> Bool
@@ -1120,6 +1172,7 @@ sameGroup (PgCo t1) (PgCo t2) = t1 `eqType` t2
sameGroup (PgView e1 t1) (PgView e2 t2) = viewLExprEq (e1,t1) (e2,t2)
-- ViewPats are in the same group iff the expressions
-- are "equal"---conservatively, we use syntactic equality
+sameGroup PgDistinct PgDistinct = True
sameGroup _ _ = False
-- An approximation of syntactic equality used for determining when view
@@ -1246,15 +1299,19 @@ viewLExprEq (e1,_) (e2,_) = lexp e1 e2
eq_list _ (_:_) [] = False
eq_list eq (x:xs) (y:ys) = eq x y && eq_list eq xs ys
-patGroup :: Platform -> Pat GhcTc -> PatGroup
-patGroup _ (ConPat { pat_con = L _ con
+patGroup :: Platform -> Maybe (Pat GhcTc) -> PatGroup
+patGroup _ Nothing = PgDistinct
+patGroup p (Just pat) = patGroup' p pat
+
+patGroup' :: Platform -> Pat GhcTc -> PatGroup
+patGroup' _ (ConPat { pat_con = L _ con
, pat_con_ext = ConPatTc { cpt_arg_tys = tys }
})
- | RealDataCon dcon <- con = PgCon dcon
- | PatSynCon psyn <- con = PgSyn psyn tys
-patGroup _ (WildPat {}) = PgAny
-patGroup _ (BangPat {}) = PgBang
-patGroup _ (NPat _ (L _ (OverLit {ol_val=oval})) mb_neg _) =
+ | RealDataCon dcon <- con = PgCon dcon
+ | PatSynCon psyn <- con = PgSyn psyn tys
+patGroup' _ (WildPat {}) = PgAny
+patGroup' _ (BangPat {}) = PgBang
+patGroup' _ (NPat _ (L _ (OverLit {ol_val=oval})) mb_neg _) =
case (oval, isJust mb_neg) of
(HsIntegral i, is_neg) -> PgN (integralFractionalLit is_neg (if is_neg
then negate (il_value i)
@@ -1264,17 +1321,17 @@ patGroup _ (NPat _ (L _ (OverLit {ol_val=oval})) mb_neg _) =
| otherwise -> PgN f
(HsIsString _ s, _) -> assert (isNothing mb_neg) $
PgOverS s
-patGroup _ (NPlusKPat _ _ (L _ (OverLit {ol_val=oval})) _ _ _) =
+patGroup' _ (NPlusKPat _ _ (L _ (OverLit {ol_val=oval})) _ _ _) =
case oval of
HsIntegral i -> PgNpK (il_value i)
_ -> pprPanic "patGroup NPlusKPat" (ppr oval)
-patGroup _ (ViewPat _ expr p) = PgView expr (hsPatType (unLoc p))
-patGroup platform (LitPat _ lit) = PgLit (hsLitKey platform lit)
-patGroup platform (XPat ext) = case ext of
+patGroup' _ (ViewPat _ expr p) = PgView expr (hsPatType (unLoc p))
+patGroup' platform (LitPat _ lit) = PgLit (hsLitKey platform lit)
+patGroup' platform (XPat ext) = case ext of
CoPat _ p _ -> PgCo (hsPatType p) -- Type of innelexp pattern
- ExpansionPat _ p -> patGroup platform p
-patGroup _ (OrPat {}) = PgOr
-patGroup _ pat = pprPanic "patGroup" (ppr pat)
+ ExpansionPat _ p -> patGroup' platform p
+patGroup' _ (OrPat {}) = PgOr
+patGroup' _ pat = pprPanic "patGroup" (ppr pat)
{-
Note [Grouping overloaded literal patterns]
=====================================
compiler/GHC/HsToCore/Match.hs-boot
=====================================
@@ -1,5 +1,6 @@
module GHC.HsToCore.Match where
+import GHC.Stack (HasCallStack)
import GHC.Prelude
import GHC.Types.Var ( Id )
import GHC.Tc.Utils.TcType ( Type )
@@ -8,7 +9,7 @@ import GHC.Core ( CoreExpr )
import GHC.Hs ( LPat, HsMatchContext, MatchGroup, LHsExpr )
import GHC.Hs.Extension ( GhcTc, GhcRn )
-match :: [Id]
+match :: HasCallStack => [Id]
-> Type
-> [EquationInfo]
-> DsM (MatchResult CoreExpr)
=====================================
compiler/GHC/HsToCore/Match/Constructor.hs
=====================================
@@ -153,24 +153,22 @@ matchOneConLike vars ty mult (eqn1 :| eqns) -- All eqns for a single construct
; return $ foldr1 (.) wraps <$> match_result
}
- shift (_, eqn@(EqnInfo
- { eqn_pats = ConPat
- { pat_args = args
- , pat_con_ext = ConPatTc
- { cpt_tvs = tvs
- , cpt_dicts = ds
- , cpt_binds = bind
- }
- } : pats
- }))
+ shift (_, eqn@(EqnMatch (ConPat
+ { pat_args = args
+ , pat_con_ext = ConPatTc
+ { cpt_tvs = tvs
+ , cpt_dicts = ds
+ , cpt_binds = bind
+ }})
+ _ rest
+ ))
= do dsTcEvBinds bind $ \ds_bind ->
return ( wrapBinds (tvs `zip` tvs1)
. wrapBinds (ds `zip` dicts1)
. mkCoreLets ds_bind
- , eqn { eqn_orig = Generated
- , eqn_pats = conArgPats val_arg_tys args ++ pats }
+ , mkEqnInfo (conArgPats val_arg_tys args ++ eqn_pats rest) Generated (eqn_rhs rest)
)
- shift (_, (EqnInfo { eqn_pats = ps })) = pprPanic "matchOneCon/shift" (ppr ps)
+ shift (_, eqn) = pprPanic "matchOneCon/shift" (ppr eqn)
; let scaled_arg_tys = map (scaleScaled mult) val_arg_tys
-- The 'val_arg_tys' are taken from the data type definition, they
-- do not take into account the context multiplicity, therefore we
=====================================
compiler/GHC/HsToCore/Match/Literal.hs
=====================================
@@ -625,10 +625,10 @@ matchLiterals (var :| vars) ty sub_groups
}
where
match_group :: NonEmpty EquationInfo -> DsM (Literal, MatchResult CoreExpr)
- match_group eqns@(firstEqn :| _)
+ match_group eqns
= do { dflags <- getDynFlags
; let platform = targetPlatform dflags
- ; let LitPat _ hs_lit = firstPat firstEqn
+ ; let (EqnMatch (LitPat _ hs_lit) _ _) = NEL.head eqns
; match_result <- match vars ty (NEL.toList $ shiftEqns eqns)
; return (hsLitKey platform hs_lit, match_result) }
@@ -726,7 +726,7 @@ matchNPlusKPats (var :| vars) ty (eqn1 :| eqns)
fmap (foldr1 (.) wraps) $
match_result) }
where
- shift n1 eqn@(EqnInfo { eqn_pats = NPlusKPat _ (L _ n) _ _ _ _ : pats })
- = (wrapBind n n1, eqn { eqn_pats = pats })
+ shift n1 eqn@(EqnMatch (NPlusKPat _ (L _ n) _ _ _ _) _ rest)
+ = (wrapBind n n1, rest)
-- The wrapBind is a no-op for the first equation
shift _ e = pprPanic "matchNPlusKPats/shift" (ppr e)
=====================================
compiler/GHC/HsToCore/Monad.hs
=====================================
@@ -48,7 +48,8 @@ module GHC.HsToCore.Monad (
-- Data types
DsMatchContext(..),
- EquationInfo(..), MatchResult (..), runMatchResult, DsWrapper, idDsWrapper,
+ EquationInfo(..), mkEqnInfo, eqn_rhs, eqn_pats,
+ MatchResult (..), runMatchResult, DsWrapper, idDsWrapper,
-- Trace injection
pprRuntimeTrace
@@ -130,7 +131,7 @@ data DsMatchContext
instance Outputable DsMatchContext where
ppr (DsMatchContext hs_match ss) = ppr ss <+> pprMatchContext hs_match
-data EquationInfo
+{-data EquationInfo
= EqnInfo { eqn_pats :: [Pat GhcTc]
-- ^ The patterns for an equation
--
@@ -149,9 +150,22 @@ data EquationInfo
, eqn_rhs :: MatchResult CoreExpr
-- ^ What to do after match
}
+-}
+
+data EquationInfo = EqnMatch (Pat GhcTc) Origin EquationInfo | EqnDone (MatchResult CoreExpr)
+
+mkEqnInfo [] _ rhs = EqnDone rhs
+mkEqnInfo (pat:pats) orig rhs = EqnMatch pat orig (mkEqnInfo pats orig rhs)
+
+eqn_pats :: EquationInfo -> [Pat GhcTc]
+eqn_pats (EqnDone _) = []
+eqn_pats (EqnMatch pat _ rest) = pat : eqn_pats rest
+eqn_rhs :: EquationInfo -> MatchResult CoreExpr
+eqn_rhs (EqnDone rhs) = rhs
+eqn_rhs (EqnMatch _ _ rest) = eqn_rhs rest
instance Outputable EquationInfo where
- ppr (EqnInfo pats _ _) = ppr pats
+ ppr = ppr . eqn_pats
type DsWrapper = CoreExpr -> CoreExpr
idDsWrapper :: DsWrapper
=====================================
compiler/GHC/HsToCore/Utils.hs
=====================================
@@ -15,7 +15,7 @@ This module exports some utility functions of no great interest.
-- | Utility functions for constructing Core syntax, principally for desugaring
module GHC.HsToCore.Utils (
EquationInfo(..),
- firstPat, shiftEqns,
+ firstPat, maybeFirstPat, shiftEqns,
MatchResult (..), CaseAlt(..),
cantFailMatchResult, alwaysFailMatchResult,
@@ -196,11 +196,16 @@ worthy of a type synonym and a few handy functions.
-}
firstPat :: EquationInfo -> Pat GhcTc
-firstPat eqn = assert (notNull (eqn_pats eqn)) $ head (eqn_pats eqn)
+firstPat (EqnMatch pat _ _) = pat
+firstPat (EqnDone _) = error "firstPat: no patterns"
+
+maybeFirstPat :: EquationInfo -> Maybe (Pat GhcTc)
+maybeFirstPat (EqnMatch pat _ _) = Just pat
+maybeFirstPat (EqnDone _) = Nothing
shiftEqns :: Functor f => f EquationInfo -> f EquationInfo
-- Drop the first pattern in each equation
-shiftEqns = fmap $ \eqn -> eqn { eqn_pats = tail (eqn_pats eqn) }
+shiftEqns = fmap $ \(EqnMatch _ _ rest) -> rest
-- Functions on MatchResult CoreExprs
@@ -221,8 +226,8 @@ extractMatchResult match_result failure_expr =
(shareFailureHandler match_result)
combineMatchResults :: MatchResult CoreExpr -> MatchResult CoreExpr -> MatchResult CoreExpr
-combineMatchResults match_result1@(MR_Infallible _) _
- = match_result1
+-- combineMatchResults match_result1@(MR_Infallible _) _
+-- = match_result1
combineMatchResults match_result1 match_result2 =
-- if the first pattern needs a failure handler (i.e. if it is fallible),
-- make it let-bind it bind it with `shareFailureHandler`.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c93c3ddd060ce347ad76731cdbcfb10da02b99dc
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c93c3ddd060ce347ad76731cdbcfb10da02b99dc
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/20230619/32da40f2/attachment-0001.html>
More information about the ghc-commits
mailing list