[Git][ghc/ghc][wip/andreask/rec_field_shapes] WIP: Try harder to detect recursive fields
Andreas Klebinger
gitlab at gitlab.haskell.org
Sat Jun 13 15:33:03 UTC 2020
Andreas Klebinger pushed to branch wip/andreask/rec_field_shapes at Glasgow Haskell Compiler / GHC
Commits:
750101f2 by Andreas Klebinger at 2020-06-13T17:32:54+02:00
WIP: Try harder to detect recursive fields
- - - - -
3 changed files:
- compiler/GHC/Core/Opt/DmdAnal.hs
- compiler/GHC/Core/Opt/WorkWrap/Utils.hs
- compiler/GHC/Types/Demand.hs
Changes:
=====================================
compiler/GHC/Core/Opt/DmdAnal.hs
=====================================
@@ -48,6 +48,7 @@ import GHC.Types.Unique.Set
************************************************************************
-}
+{-# NOINLINE dmdAnalProgram #-}
dmdAnalProgram :: DynFlags -> FamInstEnvs -> CoreProgram -> IO CoreProgram
dmdAnalProgram dflags fam_envs binds = do
let env = emptyAnalEnv dflags fam_envs
@@ -1252,7 +1253,14 @@ findBndrDmd env arg_of_dfun dmd_ty id
= (dmd_ty', dmd')
where
dmd' = strictify $
- trimToType starting_dmd (findTypeShape fam_envs id_ty)
+ -- pprTrace "trimToType"
+ -- (ppr id <> text "::" <> ppr id_ty $$
+ -- text "shape" <+> ppr (findTypeShape fam_envs id_ty) $$
+ -- (text "untrimmed" <+> ppr starting_dmd) $$
+ -- (text "trimmed" <+> ppr (trimToType starting_dmd (findTypeShape fam_envs id_ty))))
+ -- $
+
+ trimToType starting_dmd (findTypeShape fam_envs id_ty)
(dmd_ty', starting_dmd) = peelFV dmd_ty id
=====================================
compiler/GHC/Core/Opt/WorkWrap/Utils.hs
=====================================
@@ -40,12 +40,14 @@ import GHC.Core.Coercion
import GHC.Core.FamInstEnv
import GHC.Types.Basic ( Boxity(..) )
import GHC.Core.TyCon
+import GHC.Core.Map (TypeMap, lookupTypeMap, extendTypeMap)
import GHC.Types.Unique.Supply
import GHC.Types.Unique
import GHC.Data.Maybe
import GHC.Utils.Misc
import GHC.Utils.Outputable
import GHC.Driver.Session
+import GHC.Data.TrieMap
import GHC.Data.FastString
import GHC.Data.List.SetOps
@@ -1001,34 +1003,61 @@ findTypeShape :: FamInstEnvs -> Type -> TypeShape
-- The data type TypeShape is defined in GHC.Types.Demand
-- See Note [Trimming a demand to a type] in GHC.Core.Opt.DmdAnal
findTypeShape fam_envs ty
- = go (setRecTcMaxBound 2 initRecTc) ty
+ = go emptyTM (setRecTcMaxBound 2 initRecTc) ty
-- You might think this bound of 2 is low, but actually
-- I think even 1 would be fine. This only bites for recursive
-- product types, which are rare, and we really don't want
-- to look deep into such products -- see #18034
where
- go rec_tc ty
+ fieldShape :: TypeMap () -> RecTcChecker -> Type -> Type -> TypeShape
+ fieldShape tyMap rec_tc origTy fldTy
+ | Just _ <- lookupTypeMap tyMap' fldTy = TsRecField
+ | otherwise = go tyMap' rec_tc fldTy
+ where
+ tyMap' = extendTypeMap tyMap origTy ()
+ go tyMap rec_tc ty
| Just (_, res) <- splitFunTy_maybe ty
- = TsFun (go rec_tc res)
+ = TsFun (go tyMap rec_tc res)
+ -- Tuples are never recursive
| Just (tc, tc_args) <- splitTyConApp_maybe ty
, Just con <- isDataProductTyCon_maybe tc
- , Just rec_tc <- if isTupleTyCon tc
- then Just rec_tc
- else checkRecTc rec_tc tc
+ , isTupleTyCon tc
+ = TsProd (map (go tyMap rec_tc) (dataConInstArgTys con tc_args))
+
+ | Just (tc, tc_args) <- splitTyConApp_maybe ty
+ , Just con <- isDataProductTyCon_maybe tc
+ -- , fieldTys <- dataConInstArgTys con
+ = TsProd (map (fieldShape tyMap rec_tc ty) (dataConInstArgTys con tc_args))
+
+ -- Check for recursion using rec_tc
+ | Just (tc, tc_args) <- splitTyConApp_maybe ty
+ , Just con <- isDataProductTyCon_maybe tc
+ , Just rec_tc <- checkRecTc rec_tc tc
-- We treat tuples specially because they can't cause loops.
-- Maybe we should do so in checkRecTc.
- = TsProd (map (go rec_tc) (dataConInstArgTys con tc_args))
+ = TsProd (map (go tyMap rec_tc) (dataConInstArgTys con tc_args))
| Just (_, ty') <- splitForAllTy_maybe ty
- = go rec_tc ty'
+ = go tyMap rec_tc ty'
| Just (_, ty') <- topNormaliseType_maybe fam_envs ty
- = go rec_tc ty'
+ = go tyMap rec_tc ty'
| otherwise
= TsUnk
+
+ -- , Just con <- isDataProductTyCon_maybe tc
+ -- , False
+ -- = let rec_tc
+ -- | isTupleTyCon tc = Just rec_tc
+ -- | otherwise = checkRecTc rec_tc tc
+ -- in
+ -- -- We treat tuples specially because they can't cause loops.
+ -- -- Maybe we should do so in checkRecTc.
+ -- TsProd (map (go rec_tc) (dataConInstArgTys con tc_args))
+
{-
************************************************************************
* *
=====================================
compiler/GHC/Types/Demand.hs
=====================================
@@ -833,6 +833,7 @@ data TypeShape -- See Note [Trimming a demand to a type]
-- in GHC.Core.Opt.DmdAnal
= TsFun TypeShape
| TsProd [TypeShape]
+ | TsRecField
| TsUnk
trimToType :: Demand -> TypeShape -> Demand
@@ -864,6 +865,7 @@ trimToType (JD { sd = ms, ud = mu }) ts
instance Outputable TypeShape where
ppr TsUnk = text "TsUnk"
+ ppr TsRecField = text "TsRecField"
ppr (TsFun ts) = text "TsFun" <> parens (ppr ts)
ppr (TsProd tss) = parens (hsep $ punctuate comma $ map ppr tss)
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/750101f2567cf3323a321c6108a1ca4fb6d80001
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/750101f2567cf3323a321c6108a1ca4fb6d80001
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/20200613/ef26b7ab/attachment-0001.html>
More information about the ghc-commits
mailing list