diff options
author | Matthew Pickering <matthewtpickering@gmail.com> | 2022-12-27 10:12:36 +0000 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2023-01-24 05:37:52 -0500 |
commit | 4fe9eaff11ccf1fe185de2918aef4f96fd200c72 (patch) | |
tree | 16d5b2d4047afd65c4a0ba6251ce55f187fd9e4e | |
parent | 06cc0a9529f2fe0dfa40d9966a52a982653bfcb9 (diff) | |
download | haskell-4fe9eaff11ccf1fe185de2918aef4f96fd200c72.tar.gz |
Key ModSummary cache by UnitId as well as FilePath
Multiple units can refer to the same files without any problem. Just
another assumption which needs to be updated when we may have multiple
home units.
However, there is the invariant that within each unit each file only
maps to one module, so as long as we also key the cache by UnitId then
we are all good.
This led to some confusing behaviour in GHCi when reloading,
multipleHomeUnits_shared distils the essence of what can go wrong.
Fixes #22679
7 files changed, 21 insertions, 9 deletions
diff --git a/compiler/GHC/Driver/Make.hs b/compiler/GHC/Driver/Make.hs index eee37601f1..0e3348fd45 100644 --- a/compiler/GHC/Driver/Make.hs +++ b/compiler/GHC/Driver/Make.hs @@ -1580,11 +1580,13 @@ downsweep hsc_env old_summaries excl_mods allow_dup_roots logger = hsc_logger hsc_env roots = hsc_targets hsc_env - -- A cache from file paths to the already summarised modules. + -- A cache from file paths to the already summarised modules. The same file + -- can be used in multiple units so the map is also keyed by which unit the + -- file was used in. -- Reuse these if we can because the most expensive part of downsweep is -- reading the headers. - old_summary_map :: M.Map FilePath ModSummary - old_summary_map = M.fromList [(msHsFilePath ms, ms) | ms <- old_summaries] + old_summary_map :: M.Map (UnitId, FilePath) ModSummary + old_summary_map = M.fromList [((ms_unitid ms, msHsFilePath ms), ms) | ms <- old_summaries] getRootSummary :: Target -> IO (Either (UnitId, DriverMessages) ModSummary) getRootSummary Target { targetId = TargetFile file mb_phase @@ -1966,7 +1968,7 @@ mkRootMap summaries = Map.fromListWith (flip (++)) summariseFile :: HscEnv -> HomeUnit - -> M.Map FilePath ModSummary -- old summaries + -> M.Map (UnitId, FilePath) ModSummary -- old summaries -> FilePath -- source file name -> Maybe Phase -- start phase -> Maybe (StringBuffer,UTCTime) @@ -1974,9 +1976,8 @@ summariseFile summariseFile hsc_env' home_unit old_summaries src_fn mb_phase maybe_buf -- we can use a cached summary if one is available and the - -- source file hasn't changed, But we have to look up the summary - -- by source file, rather than module name as we do in summarise. - | Just old_summary <- M.lookup src_fn old_summaries + -- source file hasn't changed, + | Just old_summary <- M.lookup (homeUnitId home_unit, src_fn) old_summaries = do let location = ms_location $ old_summary @@ -2085,7 +2086,7 @@ data SummariseResult = summariseModule :: HscEnv -> HomeUnit - -> M.Map FilePath ModSummary + -> M.Map (UnitId, FilePath) ModSummary -- ^ Map of old summaries -> IsBootInterface -- True <=> a {-# SOURCE #-} import -> Located ModuleName -- Imported module to be summarised @@ -2146,7 +2147,7 @@ summariseModule hsc_env' home_unit old_summary_map is_boot (L _ wanted_mod) mb_p Right ms -> FoundHome ms new_summary_cache_check loc mod src_fn h - | Just old_summary <- Map.lookup src_fn old_summary_map = + | Just old_summary <- Map.lookup ((toUnitId (moduleUnit mod), src_fn)) old_summary_map = -- check the hash on the source file, and -- return the cached summary if it hasn't changed. If the diff --git a/testsuite/tests/driver/multipleHomeUnits/A.hs b/testsuite/tests/driver/multipleHomeUnits/A.hs new file mode 100644 index 0000000000..d843c00b78 --- /dev/null +++ b/testsuite/tests/driver/multipleHomeUnits/A.hs @@ -0,0 +1 @@ +module A where diff --git a/testsuite/tests/driver/multipleHomeUnits/all.T b/testsuite/tests/driver/multipleHomeUnits/all.T index ebee7b9f5d..d289a447a6 100644 --- a/testsuite/tests/driver/multipleHomeUnits/all.T +++ b/testsuite/tests/driver/multipleHomeUnits/all.T @@ -66,5 +66,10 @@ test('multipleHomeUnits_recomp', [copy_files,extra_files([ 'Recomp.hs', 'unitRec test('multipleHomeUnits_recomp_th', [filter_stdout_lines(r'.*Compiling.*'), copy_files, extra_files(['thRecomp.script', 'unitRecompTH', 'unitDep', 'RecompTH.hs', 'Dep.hs', '../../ghci/shell.hs']) , extra_run_opts('-v1 -unit @unitRecompTH -unit @unitDep')], ghci_script, ['thRecomp.script']) +test('multipleHomeUnits_shared', [extra_files([ 'A.hs', 'unitShared1', 'unitShared2'])], multiunit_compile, [['unitShared1', 'unitShared2'], '-fhide-source-paths']) + +test('multipleHomeUnits_shared_ghci', [extra_files([ 'shared.script', 'A.hs', 'unitShared1', 'unitShared2']), extra_run_opts('-unit @unitShared1 -unit @unitShared2')], ghci_script, ['shared.script']) + + diff --git a/testsuite/tests/driver/multipleHomeUnits/multipleHomeUnits_shared.stderr b/testsuite/tests/driver/multipleHomeUnits/multipleHomeUnits_shared.stderr new file mode 100644 index 0000000000..172ab096f1 --- /dev/null +++ b/testsuite/tests/driver/multipleHomeUnits/multipleHomeUnits_shared.stderr @@ -0,0 +1,2 @@ +[1 of 2] Compiling A[shared1] +[2 of 2] Compiling A[shared2] diff --git a/testsuite/tests/driver/multipleHomeUnits/shared.script b/testsuite/tests/driver/multipleHomeUnits/shared.script new file mode 100644 index 0000000000..38963a94f7 --- /dev/null +++ b/testsuite/tests/driver/multipleHomeUnits/shared.script @@ -0,0 +1 @@ +:r diff --git a/testsuite/tests/driver/multipleHomeUnits/unitShared1 b/testsuite/tests/driver/multipleHomeUnits/unitShared1 new file mode 100644 index 0000000000..3266a7c2a4 --- /dev/null +++ b/testsuite/tests/driver/multipleHomeUnits/unitShared1 @@ -0,0 +1 @@ +-i A -this-unit-id shared1 diff --git a/testsuite/tests/driver/multipleHomeUnits/unitShared2 b/testsuite/tests/driver/multipleHomeUnits/unitShared2 new file mode 100644 index 0000000000..75e32ae633 --- /dev/null +++ b/testsuite/tests/driver/multipleHomeUnits/unitShared2 @@ -0,0 +1 @@ +-i A -this-unit-id shared2 |