Florian Ragwitz pushed to branch wip/rafl/hpc-instances at Glasgow Haskell Compiler / GHC
Commits:
-
ae204bf8
by Florian Ragwitz at 2026-09-03T12:11:24-07:00
-
844fcc29
by Florian Ragwitz at 2026-09-03T12:11:24-07:00
-
7ca944f1
by Florian Ragwitz at 2026-09-03T12:11:25-07:00
-
54575c5a
by Florian Ragwitz at 2026-09-03T12:11:25-07:00
-
afe5fe80
by Florian Ragwitz at 2026-09-03T12:11:25-07:00
6 changed files:
- compiler/GHC/HsToCore.hs
- compiler/GHC/HsToCore/Ticks.hs
- compiler/GHC/Tc/Module.hs
- compiler/GHC/Tc/TyCl/Instance.hs
- compiler/GHC/Tc/Types.hs
- compiler/GHC/Tc/Utils/Monad.hs
Changes:
| ... | ... | @@ -147,6 +147,7 @@ deSugar hsc_env |
| 147 | 147 | tcg_tcs = tcs,
|
| 148 | 148 | tcg_default_exports = defaults,
|
| 149 | 149 | tcg_insts = insts,
|
| 150 | + tcg_inst_meths = inst_meths,
|
|
| 150 | 151 | tcg_fam_insts = fam_insts,
|
| 151 | 152 | tcg_complete_matches = complete_matches,
|
| 152 | 153 | tcg_self_boot = self_boot
|
| ... | ... | @@ -170,7 +171,7 @@ deSugar hsc_env |
| 170 | 171 | (hsc_logger hsc_env)
|
| 171 | 172 | (initTicksConfig (hsc_dflags hsc_env))
|
| 172 | 173 | mod mod_loc
|
| 173 | - export_set (typeEnvTyCons type_env) binds
|
|
| 174 | + export_set (typeEnvTyCons type_env) inst_meths binds
|
|
| 174 | 175 | else return (binds, Nothing)
|
| 175 | 176 | ; let modBreaks
|
| 176 | 177 | | Just (_, _, breakpointSpecs) <- m_tickInfo
|
| ... | ... | @@ -24,6 +24,7 @@ import GHC.Unit |
| 24 | 24 | |
| 25 | 25 | import GHC.Core.Type
|
| 26 | 26 | import GHC.Core.TyCon
|
| 27 | +import GHC.Core.InstEnv
|
|
| 27 | 28 | |
| 28 | 29 | import GHC.Data.Maybe
|
| 29 | 30 | import GHC.Data.FastString
|
| ... | ... | @@ -100,11 +101,12 @@ addTicksToBinds |
| 100 | 101 | -- isExportedId doesn't work yet (the desugarer
|
| 101 | 102 | -- hasn't set it), so we have to work from this set.
|
| 102 | 103 | -> [TyCon] -- ^ Type constructors in this module
|
| 104 | + -> IdEnv DFunId
|
|
| 103 | 105 | -> LHsBinds GhcTc
|
| 104 | 106 | -> IO (LHsBinds GhcTc, Maybe (FilePath, SizedSeq Tick, SizedSeq Tick))
|
| 105 | 107 | |
| 106 | 108 | addTicksToBinds logger cfg
|
| 107 | - mod mod_loc exports tyCons binds
|
|
| 109 | + mod mod_loc exports tyCons inst_meths binds
|
|
| 108 | 110 | | let passes = ticks_passes cfg
|
| 109 | 111 | , not (null passes)
|
| 110 | 112 | , Just orig_file <- ml_hs_file mod_loc = do
|
| ... | ... | @@ -129,6 +131,7 @@ addTicksToBinds logger cfg |
| 129 | 131 | , this_mod = mod
|
| 130 | 132 | , tickishType = tickish
|
| 131 | 133 | , recSelBinds = emptyVarEnv
|
| 134 | + , instMeths = inst_meths
|
|
| 132 | 135 | }
|
| 133 | 136 | (binds',_,st') = unTM (addTickLHsBinds binds) env st
|
| 134 | 137 | in (binds', st')
|
| ... | ... | @@ -231,7 +234,7 @@ addTickLHsBind :: LHsBind GhcTc -> TM (LHsBind GhcTc) |
| 231 | 234 | addTickLHsBind (L pos (XHsBindsLR bind@(AbsBinds { abs_binds = binds
|
| 232 | 235 | , abs_exports = abs_exports
|
| 233 | 236 | }))) =
|
| 234 | - withEnv (add_rec_sels . add_inlines . add_exports) $ do
|
|
| 237 | + withEnv (add_inst_meths . add_rec_sels . add_inlines . add_exports) $ do
|
|
| 235 | 238 | binds' <- addTickLHsBinds binds
|
| 236 | 239 | return $ L pos $ XHsBindsLR $ bind { abs_binds = binds' }
|
| 237 | 240 | where
|
| ... | ... | @@ -259,19 +262,24 @@ addTickLHsBind (L pos (XHsBindsLR bind@(AbsBinds { abs_binds = binds |
| 259 | 262 | | ABE{ abe_poly, abe_mono } <- abs_exports
|
| 260 | 263 | , RecSelId{} <- [idDetails abe_poly] ] }
|
| 261 | 264 | |
| 265 | + add_inst_meths env =
|
|
| 266 | + env{ instMeths = instMeths env `extendVarEnvList`
|
|
| 267 | + [ (abe_mono, dfun)
|
|
| 268 | + | ABE{ abe_poly, abe_mono } <- abs_exports
|
|
| 269 | + , Just dfun <- [lookupVarEnv (instMeths env) abe_poly] ] }
|
|
| 270 | + |
|
| 262 | 271 | addTickLHsBind (L pos (funBind@(FunBind { fun_id = L _ id, fun_matches = matches }))) = do
|
| 263 | 272 | let name = getOccString id
|
| 264 | 273 | decl_path <- getPathEntry
|
| 265 | 274 | density <- getDensity
|
| 275 | + env <- getEnv
|
|
| 266 | 276 | |
| 267 | - inline_ids <- liftM inlines getEnv
|
|
| 268 | 277 | -- See Note [inline sccs]
|
| 269 | 278 | let inline = isInlinePragma (idInlinePragma id)
|
| 270 | - || id `elemVarSet` inline_ids
|
|
| 279 | + || id `elemVarSet` inlines env
|
|
| 271 | 280 | |
| 272 | 281 | -- See Note [inline sccs]
|
| 273 | - tickish <- tickishType `liftM` getEnv
|
|
| 274 | - case tickish of { ProfNotes | inline -> return (L pos funBind); _ -> do
|
|
| 282 | + case tickishType env of { ProfNotes | inline -> return (L pos funBind); _ -> do
|
|
| 275 | 283 | |
| 276 | 284 | -- See Note [Record-selector ticks]
|
| 277 | 285 | selTicks <- recSelTick id
|
| ... | ... | @@ -294,8 +302,12 @@ addTickLHsBind (L pos (funBind@(FunBind { fun_id = L _ id, fun_matches = matches |
| 294 | 302 | toplev = null decl_path
|
| 295 | 303 | exported = idName id `elemNameSet` exported_names
|
| 296 | 304 | |
| 297 | - tick <- if not blackListed &&
|
|
| 298 | - shouldTickBind density toplev exported simple inline
|
|
| 305 | + let generatedInstMeth = id `elemVarEnv` instMeths env
|
|
| 306 | + && isGenerated (mg_origin (mg_ext matches))
|
|
| 307 | + |
|
| 308 | + tick <- if not generatedInstMeth
|
|
| 309 | + && not blackListed
|
|
| 310 | + && shouldTickBind density toplev exported simple inline
|
|
| 299 | 311 | then
|
| 300 | 312 | bindTick density name (locA pos) fvs
|
| 301 | 313 | else
|
| ... | ... | @@ -1098,6 +1110,7 @@ data TickTransEnv = TTE { fileName :: FastString |
| 1098 | 1110 | , this_mod :: Module
|
| 1099 | 1111 | , tickishType :: TickishType
|
| 1100 | 1112 | , recSelBinds :: IdEnv DVarSet
|
| 1113 | + , instMeths :: IdEnv DFunId
|
|
| 1101 | 1114 | }
|
| 1102 | 1115 | |
| 1103 | 1116 | -- deriving Show
|
| ... | ... | @@ -1770,7 +1770,7 @@ tcTopSrcDecls (HsGroup { hs_tyclds = tycl_decls, |
| 1770 | 1770 | -- Second pass over class and instance declarations,
|
| 1771 | 1771 | -- now using the kind-checked decls
|
| 1772 | 1772 | traceTc "Tc6" empty ;
|
| 1773 | - inst_binds <- tcInstDecls2 (tyClGroupTyClDecls tycl_decls) inst_infos ;
|
|
| 1773 | + (inst_binds, inst_meths) <- tcInstDecls2 (tyClGroupTyClDecls tycl_decls) inst_infos ;
|
|
| 1774 | 1774 | |
| 1775 | 1775 | -- Foreign exports
|
| 1776 | 1776 | traceTc "Tc7" empty ;
|
| ... | ... | @@ -1802,8 +1802,9 @@ tcTopSrcDecls (HsGroup { hs_tyclds = tycl_decls, |
| 1802 | 1802 | , tcg_anns = tcg_anns tcg_env ++ annotations
|
| 1803 | 1803 | , tcg_ann_env = extendAnnEnvList (tcg_ann_env tcg_env) annotations
|
| 1804 | 1804 | , tcg_fords = tcg_fords tcg_env ++ foe_decls ++ fi_decls
|
| 1805 | - , tcg_dus = tcg_dus tcg_env `plusDU` usesOnly fo_fvs } } ;
|
|
| 1805 | + , tcg_dus = tcg_dus tcg_env `plusDU` usesOnly fo_fvs
|
|
| 1806 | 1806 | -- tcg_dus: see Note [Newtype constructor usage in foreign declarations]
|
| 1807 | + , tcg_inst_meths = tcg_inst_meths tcg_env `plusVarEnv` inst_meths } } ;
|
|
| 1807 | 1808 | |
| 1808 | 1809 | -- See Note [Newtype constructor usage in foreign declarations]
|
| 1809 | 1810 | addUsedGREs NoDeprecationWarnings (bagToList fo_gres) ;
|
| ... | ... | @@ -1282,7 +1282,7 @@ takes a slightly different approach. |
| 1282 | 1282 | ********************************************************************* -}
|
| 1283 | 1283 | |
| 1284 | 1284 | tcInstDecls2 :: [LTyClDecl GhcRn] -> [InstInfo GhcRn]
|
| 1285 | - -> TcM (LHsBinds GhcTc)
|
|
| 1285 | + -> TcM (LHsBinds GhcTc, IdEnv DFunId)
|
|
| 1286 | 1286 | -- (a) From each class declaration,
|
| 1287 | 1287 | -- generate any default-method bindings
|
| 1288 | 1288 | -- (b) From each instance decl
|
| ... | ... | @@ -1299,11 +1299,11 @@ tcInstDecls2 tycl_decls inst_decls |
| 1299 | 1299 | -- Add the default method Ids (again)
|
| 1300 | 1300 | -- (they were already added in GHC.Tc.TyCl.Utils.tcAddImplicits)
|
| 1301 | 1301 | -- See Note [Default methods in the type environment]
|
| 1302 | - ; inst_binds_s <- tcExtendGlobalValEnv dm_ids $
|
|
| 1303 | - mapM tcInstDecl2 inst_decls
|
|
| 1302 | + ; (inst_binds_s, inst_meths_s) <- unzip <$> (tcExtendGlobalValEnv dm_ids $
|
|
| 1303 | + mapM tcInstDecl2 inst_decls)
|
|
| 1304 | 1304 | |
| 1305 | 1305 | -- Done
|
| 1306 | - ; return (dm_binds ++ concat inst_binds_s) }
|
|
| 1306 | + ; return (dm_binds ++ concat inst_binds_s, plusVarEnvList inst_meths_s) }
|
|
| 1307 | 1307 | |
| 1308 | 1308 | {- Note [Default methods in the type environment]
|
| 1309 | 1309 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| ... | ... | @@ -1319,12 +1319,12 @@ So right here in tcInstDecls2 we must re-extend the type envt with |
| 1319 | 1319 | the default method Ids replete with their INLINE pragmas. Urk.
|
| 1320 | 1320 | -}
|
| 1321 | 1321 | |
| 1322 | -tcInstDecl2 :: InstInfo GhcRn -> TcM (LHsBinds GhcTc)
|
|
| 1322 | +tcInstDecl2 :: InstInfo GhcRn -> TcM (LHsBinds GhcTc, IdEnv DFunId)
|
|
| 1323 | 1323 | -- Returns a binding for the dfun
|
| 1324 | 1324 | tcInstDecl2 (InstInfo { iSpec = ispec, iBinds = ibinds })
|
| 1325 | - = recoverM (return emptyLHsBinds) $
|
|
| 1326 | - setSrcSpan loc $
|
|
| 1327 | - addErrCtxt (instDeclCtxt2 dfun_ty) $
|
|
| 1325 | + = recoverM (return (emptyLHsBinds, emptyVarEnv)) $
|
|
| 1326 | + setSrcSpan loc $
|
|
| 1327 | + addErrCtxt (instDeclCtxt2 dfun_ty) $
|
|
| 1328 | 1328 | do { -- Instantiate the instance decl with skolem constants
|
| 1329 | 1329 | (skol_info, inst_tyvars, dfun_theta, clas, inst_tys) <- tcSkolDFunType dfun_ty
|
| 1330 | 1330 | ; dfun_ev_vars <- newEvVars dfun_theta
|
| ... | ... | @@ -1342,7 +1342,7 @@ tcInstDecl2 (InstInfo { iSpec = ispec, iBinds = ibinds }) |
| 1342 | 1342 | -- See Note [Typechecking plan for instance declarations]
|
| 1343 | 1343 | ; dfun_ev_binds_var <- newTcEvBinds
|
| 1344 | 1344 | ; let dfun_ev_binds = TcEvBinds dfun_ev_binds_var
|
| 1345 | - ; (tclvl, (sc_meth_ids, sc_meth_binds, sc_meth_implics))
|
|
| 1345 | + ; (tclvl, (sc_meth_ids, sc_meth_binds, sc_meth_implics, meth_ids))
|
|
| 1346 | 1346 | <- pushTcLevelM $
|
| 1347 | 1347 | do { (sc_ids, sc_binds, sc_implics)
|
| 1348 | 1348 | <- tcSuperClasses skol_info dfun_id clas inst_tyvars
|
| ... | ... | @@ -1356,7 +1356,8 @@ tcInstDecl2 (InstInfo { iSpec = ispec, iBinds = ibinds }) |
| 1356 | 1356 | |
| 1357 | 1357 | ; return ( sc_ids ++ meth_ids
|
| 1358 | 1358 | , sc_binds ++ meth_binds
|
| 1359 | - , sc_implics `unionBags` meth_implics ) }
|
|
| 1359 | + , sc_implics `unionBags` meth_implics
|
|
| 1360 | + , meth_ids ) }
|
|
| 1360 | 1361 | |
| 1361 | 1362 | ; imp <- newImplication
|
| 1362 | 1363 | ; emitImplication $
|
| ... | ... | @@ -1413,7 +1414,7 @@ tcInstDecl2 (InstInfo { iSpec = ispec, iBinds = ibinds }) |
| 1413 | 1414 | , abs_binds = [dict_bind]
|
| 1414 | 1415 | , abs_sig = True }
|
| 1415 | 1416 | |
| 1416 | - ; return (L loc' main_bind : sc_meth_binds)
|
|
| 1417 | + ; return (L loc' main_bind : sc_meth_binds, mkVarEnv $ (,dfun_id) <$> meth_ids)
|
|
| 1417 | 1418 | }
|
| 1418 | 1419 | where
|
| 1419 | 1420 | dfun_id = instanceDFunId ispec
|
| ... | ... | @@ -157,6 +157,7 @@ import GHC.Types.Name.Env |
| 157 | 157 | import GHC.Types.Name.Set
|
| 158 | 158 | import GHC.Types.Avail
|
| 159 | 159 | import GHC.Types.Var
|
| 160 | +import GHC.Types.Var.Env
|
|
| 160 | 161 | import GHC.Types.TypeEnv
|
| 161 | 162 | import GHC.Types.SourceFile
|
| 162 | 163 | import GHC.Types.SrcLoc
|
| ... | ... | @@ -528,6 +529,7 @@ data TcGblEnv |
| 528 | 529 | -- ^ Instance envt for all /home-package/ modules;
|
| 529 | 530 | -- Includes the dfuns in tcg_insts
|
| 530 | 531 | -- NB. BangPattern is to fix a leak, see #15111
|
| 532 | + tcg_inst_meths :: IdEnv DFunId,
|
|
| 531 | 533 | tcg_fam_inst_env :: !FamInstEnv, -- ^ Ditto for family instances
|
| 532 | 534 | -- NB. BangPattern is to fix a leak, see #15111
|
| 533 | 535 | tcg_ann_env :: AnnEnv, -- ^ And for annotations
|
| ... | ... | @@ -409,6 +409,7 @@ initTcGblEnv hsc_env hsc_src keep_rn_syntax mod loc = |
| 409 | 409 | , tcg_knot_vars = hsc_type_env_vars hsc_env
|
| 410 | 410 | , tcg_known_key_maps = known_key_maps_var
|
| 411 | 411 | , tcg_inst_env = emptyInstEnv
|
| 412 | + , tcg_inst_meths = emptyVarEnv
|
|
| 412 | 413 | , tcg_fam_inst_env = emptyFamInstEnv
|
| 413 | 414 | , tcg_ann_env = emptyAnnEnv
|
| 414 | 415 | , tcg_complete_match_env = []
|