Zubin pushed to branch wip/hls-unload-v2 at Glasgow Haskell Compiler / GHC
Commits:
-
92861ae2
by Zubin Duggal at 2026-08-12T15:47:20+05:30
-
5165b8b3
by Zubin Duggal at 2026-08-12T15:51:22+05:30
11 changed files:
- compiler/GHC/Driver/Backpack.hs
- compiler/GHC/Driver/Downsweep.hs
- compiler/GHC/Driver/Main/Passes.hs
- compiler/GHC/Driver/Pipeline.hs
- compiler/GHC/Driver/Pipeline/Execute.hs
- compiler/GHC/Iface/Recomp.hs
- compiler/GHC/Iface/Recomp/Types.hs
- compiler/GHC/Linker/Loader.hs
- compiler/GHC/Unit/Module/Graph.hs
- compiler/GHC/Unit/Module/ModIface.hs
- compiler/GHC/Unit/Module/ModSummary.hs
Changes:
| ... | ... | @@ -823,7 +823,6 @@ summariseRequirement pn mod_name = do |
| 823 | 823 | ms_dyn_obj_date = Nothing,
|
| 824 | 824 | ms_iface_date = hi_timestamp,
|
| 825 | 825 | ms_hie_date = hie_timestamp,
|
| 826 | - ms_bytecode_date = Nothing,
|
|
| 827 | 826 | ms_srcimps = [],
|
| 828 | 827 | ms_textual_imps = ((,,) NormalLevel NoPkgQual . noLoc) <$> extra_sig_imports,
|
| 829 | 828 | ms_parsed_mod = Just (HsParsedModule {
|
| ... | ... | @@ -940,7 +939,6 @@ hsModuleToModSummary home_keys pn hsc_src modname |
| 940 | 939 | ms_hs_hash = fingerprint0,
|
| 941 | 940 | ms_obj_date = Nothing, -- TODO do this, but problem: hi_timestamp is BOGUS
|
| 942 | 941 | ms_dyn_obj_date = Nothing, -- TODO do this, but problem: hi_timestamp is BOGUS
|
| 943 | - ms_bytecode_date = Nothing,
|
|
| 944 | 942 | ms_iface_date = hi_timestamp,
|
| 945 | 943 | ms_hie_date = hie_timestamp
|
| 946 | 944 | }
|
| ... | ... | @@ -1502,7 +1502,6 @@ makeNewModSummary hsc_env MakeNewModSummary{..} = do |
| 1502 | 1502 | dyn_obj_timestamp <- modificationTimeIfExists (ml_dyn_obj_file_ospath nms_location)
|
| 1503 | 1503 | hi_timestamp <- modificationTimeIfExists (ml_hi_file_ospath nms_location)
|
| 1504 | 1504 | hie_timestamp <- modificationTimeIfExists (ml_hie_file_ospath nms_location)
|
| 1505 | - bytecode_timestamp <- modificationTimeIfExists (ml_bytecode_file_ospath nms_location)
|
|
| 1506 | 1505 | extra_sig_imports <- findExtraSigImports hsc_env nms_hsc_src pi_mod_name
|
| 1507 | 1506 | (implicit_sigs, _inst_deps) <- implicitRequirementsShallow (hscSetActiveUnitId (moduleUnitId nms_mod) hsc_env) pi_theimps
|
| 1508 | 1507 | |
| ... | ... | @@ -1525,7 +1524,6 @@ makeNewModSummary hsc_env MakeNewModSummary{..} = do |
| 1525 | 1524 | , ms_hie_date = hie_timestamp
|
| 1526 | 1525 | , ms_obj_date = obj_timestamp
|
| 1527 | 1526 | , ms_dyn_obj_date = dyn_obj_timestamp
|
| 1528 | - , ms_bytecode_date = bytecode_timestamp
|
|
| 1529 | 1527 | }
|
| 1530 | 1528 | |
| 1531 | 1529 | data PreprocessedImports
|
| ... | ... | @@ -597,13 +597,13 @@ hscRecompStatus |
| 597 | 597 | | otherwise -> do
|
| 598 | 598 | -- Check the status of all the linkable types we might need.
|
| 599 | 599 | -- 1. The in-memory linkable we had at hand.
|
| 600 | - bc_in_memory_linkable <- checkByteCodeInMemory hsc_env mod_summary (homeMod_bytecode old_linkable)
|
|
| 600 | + bc_in_memory_linkable <- checkByteCodeInMemory hsc_env checked_iface mod_summary (homeMod_bytecode old_linkable)
|
|
| 601 | 601 | -- 2. The bytecode object file
|
| 602 | - bc_obj_linkable <- checkByteCodeFromObject hsc_env mod_summary
|
|
| 602 | + bc_obj_linkable <- checkByteCodeFromObject hsc_env checked_iface mod_summary
|
|
| 603 | 603 | -- 3. Bytecode from an interface's whole core bindings.
|
| 604 | 604 | bc_core_linkable <- checkByteCodeFromIfaceCoreBindings hsc_env checked_iface mod_summary
|
| 605 | 605 | -- 4. The object file.
|
| 606 | - obj_linkable <- liftIO $ checkObjects lcl_dflags (homeMod_object old_linkable) mod_summary
|
|
| 606 | + obj_linkable <- liftIO $ checkObjects lcl_dflags checked_iface (homeMod_object old_linkable) mod_summary
|
|
| 607 | 607 | trace_if (hsc_logger hsc_env)
|
| 608 | 608 | (vcat [text "BCO linkable", nest 2 (ppr bc_in_memory_linkable)
|
| 609 | 609 | , text "BCO obj linkable", ppr bc_obj_linkable
|
| ... | ... | @@ -683,12 +683,11 @@ choose l1 _ = l1 |
| 683 | 683 | |
| 684 | 684 | -- | Check that the .o files produced by compilation are already up-to-date
|
| 685 | 685 | -- or not.
|
| 686 | -checkObjects :: DynFlags -> Maybe Linkable -> ModSummary -> IO (MaybeValidated Linkable)
|
|
| 687 | -checkObjects dflags mb_old_linkable summary = do
|
|
| 686 | +checkObjects :: DynFlags -> ModIface -> Maybe Linkable -> ModSummary -> IO (MaybeValidated Linkable)
|
|
| 687 | +checkObjects dflags iface mb_old_linkable summary = do
|
|
| 688 | 688 | let
|
| 689 | 689 | dt_enabled = gopt Opt_BuildDynamicToo dflags
|
| 690 | 690 | this_mod = ms_mod summary
|
| 691 | - mb_obj_date = ms_obj_date summary
|
|
| 692 | 691 | mb_dyn_obj_date = ms_dyn_obj_date summary
|
| 693 | 692 | mb_if_date = ms_iface_date summary
|
| 694 | 693 | obj_fn = ml_obj_file (ms_location summary)
|
| ... | ... | @@ -702,44 +701,39 @@ checkObjects dflags mb_old_linkable summary = do |
| 702 | 701 | -- Not in dynamic-too mode
|
| 703 | 702 | else k
|
| 704 | 703 | |
| 705 | - -- We check by date first, even though we have the hash
|
|
| 706 | - -- If a compilation is interupted after writing the .hi
|
|
| 707 | - -- but before writing the .o, then we catch this through
|
|
| 708 | - -- modtimes.
|
|
| 709 | - -- If the object file is newer than the .hi file, and the
|
|
| 710 | - -- .hi file is up to date, we also assume the object file
|
|
| 711 | - -- is up to date.
|
|
| 712 | 704 | checkDynamicObj $
|
| 713 | - case (,) <$> mb_obj_date <*> mb_if_date of
|
|
| 714 | - Just (obj_date, if_date)
|
|
| 715 | - | obj_date >= if_date -> do
|
|
| 705 | + case mi_sr_object_hash =<< mi_self_recomp_info iface of
|
|
| 706 | + Nothing -> return $ outOfDateItemBecause MissingObjectFile Nothing
|
|
| 707 | + Just expected_hash -> do
|
|
| 708 | + exists <- doesFileExist obj_fn
|
|
| 709 | + if not exists
|
|
| 710 | + then return $ outOfDateItemBecause MissingObjectFile Nothing
|
|
| 711 | + else do
|
|
| 716 | 712 | disk_hash <- getFileHash obj_fn
|
| 717 | - case mb_old_linkable of
|
|
| 718 | - Just old_linkable
|
|
| 719 | - | linkableIsNativeCodeOnly old_linkable
|
|
| 720 | - , linkableHash old_linkable == disk_hash
|
|
| 721 | - -> return $ UpToDateItem old_linkable
|
|
| 722 | - _ -> return $ UpToDateItem (findObjectLinkable this_mod obj_fn disk_hash)
|
|
| 723 | - _ -> return $ outOfDateItemBecause MissingObjectFile Nothing
|
|
| 713 | + if disk_hash /= expected_hash
|
|
| 714 | + then return $ outOfDateItemBecause ObjectsChanged Nothing
|
|
| 715 | + else case mb_old_linkable of
|
|
| 716 | + Just old_linkable
|
|
| 717 | + | linkableIsNativeCodeOnly old_linkable
|
|
| 718 | + , linkableHash old_linkable == disk_hash
|
|
| 719 | + -> return $ UpToDateItem old_linkable
|
|
| 720 | + _ -> return $ UpToDateItem (findObjectLinkable this_mod obj_fn disk_hash)
|
|
| 724 | 721 | |
| 725 | 722 | -- | Check to see if we can reuse the old linkable, by this point we will
|
| 726 | 723 | -- have just checked that the old interface matches up with the source hash, so
|
| 727 | 724 | -- no need to check that again here
|
| 728 | -checkByteCodeInMemory :: HscEnv -> ModSummary -> Maybe (LinkableWith ModuleByteCode) -> IO (MaybeValidated (LinkableWith ModuleByteCode))
|
|
| 729 | -checkByteCodeInMemory hsc_env mod_sum mb_old_linkable =
|
|
| 725 | +checkByteCodeInMemory :: HscEnv -> ModIface -> ModSummary -> Maybe (LinkableWith ModuleByteCode) -> IO (MaybeValidated (LinkableWith ModuleByteCode))
|
|
| 726 | +checkByteCodeInMemory hsc_env iface mod_sum mb_old_linkable =
|
|
| 730 | 727 | case mb_old_linkable of
|
| 731 | 728 | Just old_linkable -> do
|
| 732 | 729 | -- If `-fwrite-byte-code` is enabled, then check that the .gbc file is
|
| 733 | 730 | -- up-to-date with the linkable we have in our hand.
|
| 734 | - -- If ms_bytecode_date is Nothing, then the .gbc file does not exist yet.
|
|
| 735 | - -- Otherwise, check that the hash matches the disk.
|
|
| 736 | 731 | ok <- if gopt Opt_WriteByteCode (hsc_dflags hsc_env)
|
| 737 | - then case ms_bytecode_date mod_sum of
|
|
| 738 | - Nothing -> pure False
|
|
| 739 | - Just _ -> do
|
|
| 740 | - disk_hash <- ByteCode.readBinByteCodeHash hsc_env
|
|
| 741 | - (ml_bytecode_file (ms_location mod_sum))
|
|
| 742 | - pure (disk_hash == linkableHash old_linkable)
|
|
| 732 | + then case mi_sr_bytecode_hash =<< mi_self_recomp_info iface of
|
|
| 733 | + Just expected_hash
|
|
| 734 | + | expected_hash == linkableHash old_linkable
|
|
| 735 | + -> doesFileExist (ml_bytecode_file (ms_location mod_sum))
|
|
| 736 | + _ -> pure False
|
|
| 743 | 737 | else pure True
|
| 744 | 738 | if ok
|
| 745 | 739 | then return (UpToDateItem old_linkable)
|
| ... | ... | @@ -747,22 +741,27 @@ checkByteCodeInMemory hsc_env mod_sum mb_old_linkable = |
| 747 | 741 | _ -> return $ outOfDateItemBecause MissingBytecode Nothing
|
| 748 | 742 | |
| 749 | 743 | -- | Load bytecode from a ".gbc" object file if it exists and is up-to-date
|
| 750 | -checkByteCodeFromObject :: HscEnv -> ModSummary -> IO (MaybeValidated (LinkableWith ModuleByteCode))
|
|
| 751 | -checkByteCodeFromObject hsc_env mod_sum = do
|
|
| 744 | +checkByteCodeFromObject :: HscEnv -> ModIface -> ModSummary -> IO (MaybeValidated (LinkableWith ModuleByteCode))
|
|
| 745 | +checkByteCodeFromObject hsc_env iface mod_sum = do
|
|
| 752 | 746 | let
|
| 753 | 747 | obj_fn = ml_bytecode_file (ms_location mod_sum)
|
| 754 | - obj_date = ms_bytecode_date mod_sum
|
|
| 755 | - if_date = ms_iface_date mod_sum
|
|
| 756 | - case (,) <$> obj_date <*> if_date of
|
|
| 757 | - Just (obj_date, if_date)
|
|
| 758 | - | obj_date >= if_date -> do
|
|
| 759 | - -- Don't force this if we reuse the linkable already loaded into memory, but we have to check
|
|
| 760 | - -- that the one we have on disk would be suitable as well.
|
|
| 761 | - linkable <- unsafeInterleaveIO $ do
|
|
| 762 | - bco <- ByteCode.readBinByteCode hsc_env obj_fn
|
|
| 763 | - return $ mkOnlyModuleByteCodeLinkable bco
|
|
| 764 | - return $ UpToDateItem linkable
|
|
| 765 | - _ -> return $ outOfDateItemBecause MissingBytecode Nothing
|
|
| 748 | + case mi_sr_bytecode_hash =<< mi_self_recomp_info iface of
|
|
| 749 | + Nothing -> return $ outOfDateItemBecause MissingBytecode Nothing
|
|
| 750 | + Just expected_hash -> do
|
|
| 751 | + exists <- doesFileExist obj_fn
|
|
| 752 | + if not exists
|
|
| 753 | + then return $ outOfDateItemBecause MissingBytecode Nothing
|
|
| 754 | + else do
|
|
| 755 | + disk_hash <- ByteCode.readBinByteCodeHash hsc_env obj_fn
|
|
| 756 | + if disk_hash /= expected_hash
|
|
| 757 | + then return $ outOfDateItemBecause MissingBytecode Nothing
|
|
| 758 | + else do
|
|
| 759 | + -- Don't force this if we reuse the linkable already loaded into memory, but we have to check
|
|
| 760 | + -- that the one we have on disk would be suitable as well.
|
|
| 761 | + linkable <- unsafeInterleaveIO $ do
|
|
| 762 | + bco <- ByteCode.readBinByteCode hsc_env obj_fn
|
|
| 763 | + return $ mkOnlyModuleByteCodeLinkable bco
|
|
| 764 | + return $ UpToDateItem linkable
|
|
| 766 | 765 | |
| 767 | 766 | -- | Attempt to load bytecode from whole core bindings in the interface if they exist.
|
| 768 | 767 | -- This is a legacy code-path, these days it should be preferred to use the bytecode object linkable.
|
| ... | ... | @@ -941,11 +941,27 @@ hscGenBackendPipeline pipe_env hsc_env mod_sum result = do |
| 941 | 941 | -- Add the object linkable to the potential bytecode linkable which was generated in HscBackend.
|
| 942 | 942 | return (mlinkable { homeMod_object = Just linkable })
|
| 943 | 943 | |
| 944 | + miface' <- case result of
|
|
| 945 | + HscRecomp { hscs_old_iface_hash = mb_old_iface_hash }
|
|
| 946 | + | backendWritesFiles (backend (hsc_dflags hsc_env)) -> do
|
|
| 947 | + let bc_hash = case recompLinkables_bytecode final_linkable of
|
|
| 948 | + NormalLinkable mb_bc -> fmap linkableHash mb_bc
|
|
| 949 | + WholeCoreBindingsLinkable {} -> Nothing
|
|
| 950 | + patched = addIfaceArtifactHashes
|
|
| 951 | + (fmap linkableHash (recompLinkables_object final_linkable))
|
|
| 952 | + bc_hash
|
|
| 953 | + miface
|
|
| 954 | + -- See Note [Writing interface files]
|
|
| 955 | + liftIO $ hscMaybeWriteIface (hsc_logger hsc_env) (hsc_dflags hsc_env)
|
|
| 956 | + False patched mb_old_iface_hash (ms_location mod_sum)
|
|
| 957 | + return patched
|
|
| 958 | + _ -> return miface
|
|
| 959 | + |
|
| 944 | 960 | -- when building ghc-internal with --make (e.g. with cabal-install), we want
|
| 945 | 961 | -- the virtual interface for gHC_PRIM in the cache, not the empty one.
|
| 946 | 962 | let miface_final
|
| 947 | 963 | | ms_mod mod_sum == gHC_PRIM = getGhcPrimIface (hsc_hooks hsc_env)
|
| 948 | - | otherwise = miface
|
|
| 964 | + | otherwise = miface'
|
|
| 949 | 965 | return (miface_final, final_linkable)
|
| 950 | 966 | |
| 951 | 967 | asPipeline :: P m => Bool -> PipeEnv -> HscEnv -> Maybe ModLocation -> FilePath -> m (Maybe ObjFile)
|
| ... | ... | @@ -58,6 +58,8 @@ import GHC.Unit.State |
| 58 | 58 | import GHC.Unit.Home
|
| 59 | 59 | import GHC.Data.Maybe
|
| 60 | 60 | import GHC.Iface.Make
|
| 61 | +import GHC.Iface.Recomp (addIfaceArtifactHashes)
|
|
| 62 | +import GHC.Linker.Types (linkableHash)
|
|
| 61 | 63 | import GHC.Driver.Config.Parser
|
| 62 | 64 | import GHC.Parser.Header
|
| 63 | 65 | import GHC.Data.StringBuffer
|
| ... | ... | @@ -563,8 +565,6 @@ runHscBackendPhase pipe_env hsc_env mod_name src_flavour location result = do |
| 563 | 565 | |
| 564 | 566 | final_iface <- mkFullIface hsc_env partial_iface stg_infos cg_infos iface_stubs iface_files
|
| 565 | 567 | |
| 566 | - -- See Note [Writing interface files]
|
|
| 567 | - hscMaybeWriteIface logger dflags False final_iface mb_old_iface_hash mod_location
|
|
| 568 | 568 | mlinkable <-
|
| 569 | 569 | if gopt Opt_ByteCodeAndObjectCode dflags
|
| 570 | 570 | then do
|
| ... | ... | @@ -583,9 +583,10 @@ runHscBackendPhase pipe_env hsc_env mod_name src_flavour location result = do |
| 583 | 583 | -- In interpreted mode the regular codeGen backend is not run so we
|
| 584 | 584 | -- generate a interface without codeGen info.
|
| 585 | 585 | do
|
| 586 | - final_iface <- mkFullIface hsc_env partial_iface Nothing Nothing NoStubs []
|
|
| 587 | - hscMaybeWriteIface logger dflags True final_iface mb_old_iface_hash location
|
|
| 586 | + final_iface0 <- mkFullIface hsc_env partial_iface Nothing Nothing NoStubs []
|
|
| 588 | 587 | bc <- generateAndWriteByteCodeLinkable hsc_env (mkCgInteractiveGuts cgguts) mod_location
|
| 588 | + let final_iface = addIfaceArtifactHashes Nothing (Just (linkableHash bc)) final_iface0
|
|
| 589 | + hscMaybeWriteIface logger dflags True final_iface mb_old_iface_hash location
|
|
| 589 | 590 | return ([], final_iface, emptyHomeModInfoLinkable { homeMod_bytecode = Just bc } , panic "interpreter")
|
| 590 | 591 | |
| 591 | 592 | |
| ... | ... | @@ -699,7 +700,6 @@ runHscPhase pipe_env hsc_env0 input_fn src_flavour = do |
| 699 | 700 | hie_date <- modificationTimeIfExists hie_file
|
| 700 | 701 | o_mod <- modificationTimeIfExists o_file
|
| 701 | 702 | dyn_o_mod <- modificationTimeIfExists dyn_o_file
|
| 702 | - bytecode_date <- modificationTimeIfExists (ml_bytecode_file_ospath location)
|
|
| 703 | 703 | |
| 704 | 704 | -- Tell the finder cache about this module
|
| 705 | 705 | mod <- do
|
| ... | ... | @@ -721,7 +721,6 @@ runHscPhase pipe_env hsc_env0 input_fn src_flavour = do |
| 721 | 721 | ms_parsed_mod = Nothing,
|
| 722 | 722 | ms_iface_date = hi_date,
|
| 723 | 723 | ms_hie_date = hie_date,
|
| 724 | - ms_bytecode_date = bytecode_date,
|
|
| 725 | 724 | ms_textual_imps = imps,
|
| 726 | 725 | ms_srcimps = src_imps }
|
| 727 | 726 |
| ... | ... | @@ -13,6 +13,7 @@ module GHC.Iface.Recomp |
| 13 | 13 | , recompileRequired
|
| 14 | 14 | , addFingerprints
|
| 15 | 15 | , mkSelfRecomp
|
| 16 | + , addIfaceArtifactHashes
|
|
| 16 | 17 | )
|
| 17 | 18 | where
|
| 18 | 19 | |
| ... | ... | @@ -1226,7 +1227,9 @@ mkSelfRecomp hsc_env this_mod src_hash usages = do |
| 1226 | 1227 | , mi_sr_opt_hash = opt_hash
|
| 1227 | 1228 | , mi_sr_plugin_hash = plugin_hash
|
| 1228 | 1229 | , mi_sr_src_hash = src_hash
|
| 1229 | - , mi_sr_usages = usages })
|
|
| 1230 | + , mi_sr_usages = usages
|
|
| 1231 | + , mi_sr_object_hash = Nothing
|
|
| 1232 | + , mi_sr_bytecode_hash = Nothing })
|
|
| 1230 | 1233 | |
| 1231 | 1234 | -- | Add fingerprints for top-level declarations to a 'ModIface'.
|
| 1232 | 1235 | --
|
| ... | ... | @@ -1273,6 +1276,20 @@ addFingerprints hsc_env iface0 = do |
| 1273 | 1276 | --
|
| 1274 | 1277 | return final_iface
|
| 1275 | 1278 | |
| 1279 | +addIfaceArtifactHashes :: Maybe Fingerprint -> Maybe Fingerprint -> ModIface -> ModIface
|
|
| 1280 | +addIfaceArtifactHashes mb_obj mb_bc iface =
|
|
| 1281 | + case mi_self_recomp_info iface of
|
|
| 1282 | + Nothing -> iface
|
|
| 1283 | + Just sr ->
|
|
| 1284 | + let iface' = set_mi_self_recomp
|
|
| 1285 | + (Just sr { mi_sr_object_hash = mb_obj, mi_sr_bytecode_hash = mb_bc })
|
|
| 1286 | + iface
|
|
| 1287 | + !iface_hash = computeFingerprint putNameLiterally
|
|
| 1288 | + (mi_mod_hash iface',
|
|
| 1289 | + mi_self_recomp_info iface',
|
|
| 1290 | + mi_deps iface')
|
|
| 1291 | + in set_mi_iface_hash iface_hash iface'
|
|
| 1292 | + |
|
| 1276 | 1293 | |
| 1277 | 1294 | |
| 1278 | 1295 | -- The ABI hash should depend on everything in IfacePublic
|
| ... | ... | @@ -80,17 +80,23 @@ data IfaceSelfRecomp = |
| 80 | 80 | -- ^ Hash of hpc flags
|
| 81 | 81 | , mi_sr_plugin_hash :: !Fingerprint
|
| 82 | 82 | -- ^ Hash of plugins
|
| 83 | + , mi_sr_object_hash :: !(Maybe Fingerprint)
|
|
| 84 | + -- ^ Hash of the object file this compilation produced
|
|
| 85 | + , mi_sr_bytecode_hash :: !(Maybe Fingerprint)
|
|
| 86 | + -- ^ Hash of the bytecode this compilation produced
|
|
| 83 | 87 | }
|
| 84 | 88 | |
| 85 | 89 | |
| 86 | 90 | instance Binary IfaceSelfRecomp where
|
| 87 | - put_ bh (IfaceSelfRecomp{mi_sr_src_hash, mi_sr_usages, mi_sr_flag_hash, mi_sr_opt_hash, mi_sr_hpc_hash, mi_sr_plugin_hash}) = do
|
|
| 91 | + put_ bh (IfaceSelfRecomp{mi_sr_src_hash, mi_sr_usages, mi_sr_flag_hash, mi_sr_opt_hash, mi_sr_hpc_hash, mi_sr_plugin_hash, mi_sr_object_hash, mi_sr_bytecode_hash}) = do
|
|
| 88 | 92 | put_ bh mi_sr_src_hash
|
| 89 | 93 | lazyPut bh mi_sr_usages
|
| 90 | 94 | put_ bh mi_sr_flag_hash
|
| 91 | 95 | put_ bh mi_sr_opt_hash
|
| 92 | 96 | put_ bh mi_sr_hpc_hash
|
| 93 | 97 | put_ bh mi_sr_plugin_hash
|
| 98 | + put_ bh mi_sr_object_hash
|
|
| 99 | + put_ bh mi_sr_bytecode_hash
|
|
| 94 | 100 | |
| 95 | 101 | get bh = do
|
| 96 | 102 | src_hash <- get bh
|
| ... | ... | @@ -99,22 +105,26 @@ instance Binary IfaceSelfRecomp where |
| 99 | 105 | opt_hash <- get bh
|
| 100 | 106 | hpc_hash <- get bh
|
| 101 | 107 | plugin_hash <- get bh
|
| 102 | - return $ IfaceSelfRecomp { mi_sr_src_hash = src_hash, mi_sr_usages = usages, mi_sr_flag_hash = flag_hash, mi_sr_opt_hash = opt_hash, mi_sr_hpc_hash = hpc_hash, mi_sr_plugin_hash = plugin_hash }
|
|
| 108 | + object_hash <- get bh
|
|
| 109 | + bytecode_hash <- get bh
|
|
| 110 | + return $ IfaceSelfRecomp { mi_sr_src_hash = src_hash, mi_sr_usages = usages, mi_sr_flag_hash = flag_hash, mi_sr_opt_hash = opt_hash, mi_sr_hpc_hash = hpc_hash, mi_sr_plugin_hash = plugin_hash, mi_sr_object_hash = object_hash, mi_sr_bytecode_hash = bytecode_hash }
|
|
| 103 | 111 | |
| 104 | 112 | instance Outputable IfaceSelfRecomp where
|
| 105 | - ppr (IfaceSelfRecomp{mi_sr_src_hash, mi_sr_usages, mi_sr_flag_hash, mi_sr_opt_hash, mi_sr_hpc_hash, mi_sr_plugin_hash})
|
|
| 113 | + ppr (IfaceSelfRecomp{mi_sr_src_hash, mi_sr_usages, mi_sr_flag_hash, mi_sr_opt_hash, mi_sr_hpc_hash, mi_sr_plugin_hash, mi_sr_object_hash, mi_sr_bytecode_hash})
|
|
| 106 | 114 | = vcat [text "Self-Recomp"
|
| 107 | 115 | , nest 2 (vcat [ text "src hash:" <+> ppr mi_sr_src_hash
|
| 108 | 116 | , text "flags:" <+> pprFingerprintWithValue missingExtraFlagInfo (fmap pprIfaceDynFlags mi_sr_flag_hash)
|
| 109 | 117 | , text "opt hash:" <+> ppr mi_sr_opt_hash
|
| 110 | 118 | , text "hpc hash:" <+> ppr mi_sr_hpc_hash
|
| 111 | 119 | , text "plugin hash:" <+> ppr mi_sr_plugin_hash
|
| 120 | + , text "object hash:" <+> ppr mi_sr_object_hash
|
|
| 121 | + , text "bytecode hash:" <+> ppr mi_sr_bytecode_hash
|
|
| 112 | 122 | , text "usages:" <+> ppr (map pprUsage mi_sr_usages)
|
| 113 | 123 | ])]
|
| 114 | 124 | |
| 115 | 125 | instance NFData IfaceSelfRecomp where
|
| 116 | - rnf (IfaceSelfRecomp src_hash usages flag_hash opt_hash hpc_hash plugin_hash)
|
|
| 117 | - = rnf src_hash `seq` rnf usages `seq` rnf flag_hash `seq` rnf opt_hash `seq` rnf hpc_hash `seq` rnf plugin_hash `seq` ()
|
|
| 126 | + rnf (IfaceSelfRecomp src_hash usages flag_hash opt_hash hpc_hash plugin_hash object_hash bytecode_hash)
|
|
| 127 | + = rnf src_hash `seq` rnf usages `seq` rnf flag_hash `seq` rnf opt_hash `seq` rnf hpc_hash `seq` rnf plugin_hash `seq` rnf object_hash `seq` rnf bytecode_hash `seq` ()
|
|
| 118 | 128 | |
| 119 | 129 | pprFingerprintWithValue :: SDoc -> FingerprintWithValue SDoc -> SDoc
|
| 120 | 130 | pprFingerprintWithValue missingInfo (FingerprintWithValue fp mflags)
|
| ... | ... | @@ -95,6 +95,7 @@ import GHC.Unit.External (ExternalPackageState (..)) |
| 95 | 95 | import GHC.Unit.Module
|
| 96 | 96 | import GHC.Unit.Module.ModNodeKey
|
| 97 | 97 | import GHC.Unit.Module.Graph
|
| 98 | +import GHC.Unit.Module.Stage (ModuleStage (..))
|
|
| 98 | 99 | import GHC.Unit.Module.ModIface
|
| 99 | 100 | import GHC.Unit.State as Packages
|
| 100 | 101 | |
| ... | ... | @@ -713,7 +714,9 @@ get_reachable_nodes hsc_env mods |
| 713 | 714 | go :: ModuleGraph -> IO ([Module], UniqDSet UnitId)
|
| 714 | 715 | go mg = do
|
| 715 | 716 | let mod_keys = map (hmgModKey mg) mods
|
| 716 | - all_reachable = mod_keys ++ map mkNodeKey (mgReachableLoop mg mod_keys)
|
|
| 717 | + reached = mgReachableStage mg [ (k, RunStage) | k <- mod_keys ]
|
|
| 718 | + all_reachable = nubOrd $
|
|
| 719 | + mod_keys ++ [ k | (k, RunStage) <- reached ]
|
|
| 717 | 720 | (mods_s, pkgs_s) <- partitionEithers <$> mapMaybeM get_mod_info all_reachable
|
| 718 | 721 | return (mods_s, mkUniqDSet pkgs_s)
|
| 719 | 722 |
| ... | ... | @@ -79,6 +79,7 @@ module GHC.Unit.Module.Graph |
| 79 | 79 | -- transitive closure of Z?
|
| 80 | 80 | , mgReachable
|
| 81 | 81 | , mgReachableLoop
|
| 82 | + , mgReachableStage
|
|
| 82 | 83 | , mgQuery
|
| 83 | 84 | , ZeroScopeKey(..)
|
| 84 | 85 | , mgQueryZero
|
| ... | ... | @@ -191,6 +192,7 @@ data ModuleGraph = ModuleGraph |
| 191 | 192 | , mg_graph :: (ReachabilityIndex SummaryNode, NodeKey -> Maybe SummaryNode)
|
| 192 | 193 | , mg_loop_graph :: (ReachabilityIndex SummaryNode, NodeKey -> Maybe SummaryNode)
|
| 193 | 194 | , mg_zero_graph :: (ReachabilityIndex ZeroSummaryNode, ZeroScopeKey -> Maybe ZeroSummaryNode)
|
| 195 | + , mg_stage_graph :: (ReachabilityIndex StageSummaryNode, (NodeKey, ModuleStage) -> Maybe StageSummaryNode)
|
|
| 194 | 196 | |
| 195 | 197 | -- `mg_graph` and `mg_loop_graph` cached transitive dependency calculations
|
| 196 | 198 | -- so that a lot of work is not repeated whenever the transitive
|
| ... | ... | @@ -230,6 +232,7 @@ emptyMG :: ModuleGraph |
| 230 | 232 | emptyMG = ModuleGraph [] (graphReachability emptyGraph, const Nothing)
|
| 231 | 233 | (graphReachability emptyGraph, const Nothing)
|
| 232 | 234 | (graphReachability emptyGraph, const Nothing)
|
| 235 | + (cyclicGraphReachability emptyGraph, const Nothing)
|
|
| 233 | 236 | False
|
| 234 | 237 | emptyUniqMap
|
| 235 | 238 | |
| ... | ... | @@ -588,6 +591,12 @@ mgReachableLoop mg nk = map summaryNodeSummary modules_below where |
| 588 | 591 | modules_below =
|
| 589 | 592 | allReachableMany td_map (mapMaybe lookup_node nk)
|
| 590 | 593 | |
| 594 | +mgReachableStage :: ModuleGraph -> [(NodeKey, ModuleStage)] -> [(NodeKey, ModuleStage)]
|
|
| 595 | +mgReachableStage mg nk = map stageSummaryNodeSummary modules_below where
|
|
| 596 | + (td_map, lookup_node) = mg_stage_graph mg
|
|
| 597 | + modules_below =
|
|
| 598 | + allReachableMany td_map (mapMaybe lookup_node nk)
|
|
| 599 | + |
|
| 591 | 600 | |
| 592 | 601 | -- | @'mgQueryZero' g root target@ answers the question: can we reach @target@ from @root@
|
| 593 | 602 | -- in the module graph @g@, only using normal (level 0) imports?
|
| ... | ... | @@ -1079,6 +1088,7 @@ extendMG ModuleGraph{..} node = |
| 1079 | 1088 | , mg_graph = mkTransDeps new_mss
|
| 1080 | 1089 | , mg_loop_graph = mkTransLoopDeps new_mss
|
| 1081 | 1090 | , mg_zero_graph = mkTransZeroDeps new_mss
|
| 1091 | + , mg_stage_graph = mkStageDeps new_mss
|
|
| 1082 | 1092 | , mg_has_holes = mg_has_holes || maybe False isHsigFile (moduleNodeInfoHscSource =<< mgNodeIsModule node)
|
| 1083 | 1093 | , mg_home_module_name_providers_map = mkHomeModuleNameProvidersMap new_mss
|
| 1084 | 1094 | }
|
| ... | ... | @@ -43,6 +43,7 @@ module GHC.Unit.Module.ModIface |
| 43 | 43 | , set_mi_sig_of
|
| 44 | 44 | , set_mi_hsc_src
|
| 45 | 45 | , set_mi_self_recomp
|
| 46 | + , set_mi_iface_hash
|
|
| 46 | 47 | , set_mi_hi_bytes
|
| 47 | 48 | , set_mi_deps
|
| 48 | 49 | , set_mi_exports
|
| ... | ... | @@ -979,6 +980,9 @@ set_mi_mod_info val iface = clear_mi_hi_bytes $ iface { mi_mod_info_ = val } |
| 979 | 980 | set_mi_self_recomp :: Maybe IfaceSelfRecomp-> ModIface_ phase -> ModIface_ phase
|
| 980 | 981 | set_mi_self_recomp val iface = clear_mi_hi_bytes $ iface { mi_self_recomp_ = val }
|
| 981 | 982 | |
| 983 | +set_mi_iface_hash :: Fingerprint -> ModIface_ phase -> ModIface_ phase
|
|
| 984 | +set_mi_iface_hash val iface = clear_mi_hi_bytes $ iface { mi_iface_hash_ = val }
|
|
| 985 | + |
|
| 982 | 986 | set_mi_hi_bytes :: IfaceBinHandle phase -> ModIface_ phase -> ModIface_ phase
|
| 983 | 987 | set_mi_hi_bytes val iface = iface { mi_hi_bytes_ = val }
|
| 984 | 988 |
| ... | ... | @@ -75,8 +75,6 @@ data ModSummary |
| 75 | 75 | -- ^ Timestamp of object, if we have one
|
| 76 | 76 | ms_dyn_obj_date :: !(Maybe UTCTime),
|
| 77 | 77 | -- ^ Timestamp of dynamic object, if we have one
|
| 78 | - ms_bytecode_date :: Maybe UTCTime,
|
|
| 79 | - -- ^ Timestamp of bytecode object, if we have one
|
|
| 80 | 78 | ms_iface_date :: Maybe UTCTime,
|
| 81 | 79 | -- ^ Timestamp of hi file, if we have one
|
| 82 | 80 | -- See Note [When source is considered modified] and #9243
|