summaryrefslogtreecommitdiff
path: root/compiler
diff options
context:
space:
mode:
authorEdward Z. Yang <ezyang@cs.stanford.edu>2014-12-27 10:50:01 -0800
committerEdward Z. Yang <ezyang@cs.stanford.edu>2015-01-03 11:56:14 -0800
commit2223e196b2dc5340d70e58be011c279d381b4319 (patch)
tree3c587547990df7c62d73598f9dfe991afb0b4880 /compiler
parentaf4d99803ea7676f88f250ad56a8c31c1c8cd5bc (diff)
downloadhaskell-2223e196b2dc5340d70e58be011c279d381b4319.tar.gz
Fix #9243 so recompilation avoidance works with -fno-code
Summary: Where we track timestamps of object files, also track timestamps for interface files. When -fno-code -fwrite-interface is enabled, use the interface file timestamp as an extra check to see if the files are up-to-date. We had to apply this logic to one-shot and make modes. This fix would be good to merge into 7.10; it makes using -fno-code -fwrite-interface for flywheel type checking usable. Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu> Test Plan: validate and new test cases Reviewers: austin Subscribers: carter, thomie Differential Revision: https://phabricator.haskell.org/D596 GHC Trac Issues: #9243
Diffstat (limited to 'compiler')
-rw-r--r--compiler/main/DriverPipeline.hs19
-rw-r--r--compiler/main/GhcMake.hs40
-rw-r--r--compiler/main/HscTypes.hs4
3 files changed, 57 insertions, 6 deletions
diff --git a/compiler/main/DriverPipeline.hs b/compiler/main/DriverPipeline.hs
index e8be29759b..6d597f9437 100644
--- a/compiler/main/DriverPipeline.hs
+++ b/compiler/main/DriverPipeline.hs
@@ -30,7 +30,7 @@ module DriverPipeline (
runPhase, exeFileName,
mkExtraObjToLinkIntoBinary, mkNoteObjsToLinkIntoBinary,
maybeCreateManifest, runPhase_MoveBinary,
- linkingNeeded, checkLinkInfo
+ linkingNeeded, checkLinkInfo, writeInterfaceOnlyMode
) where
#include "HsVersions.h"
@@ -935,6 +935,11 @@ runPhase (RealPhase (Hsc src_flavour)) input_fn dflags0
location <- getLocation src_flavour mod_name
let o_file = ml_obj_file location -- The real object file
+ hi_file = ml_hi_file location
+ dest_file | writeInterfaceOnlyMode dflags
+ = hi_file
+ | otherwise
+ = o_file
-- Figure out if the source has changed, for recompilation avoidance.
--
@@ -952,10 +957,10 @@ runPhase (RealPhase (Hsc src_flavour)) input_fn dflags0
-- (b) we aren't going all the way to .o file (e.g. ghc -S)
then return SourceModified
-- Otherwise look at file modification dates
- else do o_file_exists <- doesFileExist o_file
- if not o_file_exists
+ else do dest_file_exists <- doesFileExist dest_file
+ if not dest_file_exists
then return SourceModified -- Need to recompile
- else do t2 <- getModificationUTCTime o_file
+ else do t2 <- getModificationUTCTime dest_file
if t2 > src_timestamp
then return SourceUnmodified
else return SourceModified
@@ -975,6 +980,7 @@ runPhase (RealPhase (Hsc src_flavour)) input_fn dflags0
ms_location = location,
ms_hs_date = src_timestamp,
ms_obj_date = Nothing,
+ ms_iface_date = Nothing,
ms_textual_imps = imps,
ms_srcimps = src_imps }
@@ -2248,6 +2254,11 @@ joinObjectFiles dflags o_files output_fn = do
-- -----------------------------------------------------------------------------
-- Misc.
+writeInterfaceOnlyMode :: DynFlags -> Bool
+writeInterfaceOnlyMode dflags =
+ gopt Opt_WriteInterface dflags &&
+ HscNothing == hscTarget dflags
+
-- | What phase to run after one of the backend code generators has run
hscPostBackendPhase :: DynFlags -> HscSource -> HscTarget -> Phase
hscPostBackendPhase _ HsBootFile _ = StopLn
diff --git a/compiler/main/GhcMake.hs b/compiler/main/GhcMake.hs
index 1fb6f71af2..cd670b36cd 100644
--- a/compiler/main/GhcMake.hs
+++ b/compiler/main/GhcMake.hs
@@ -1136,6 +1136,15 @@ upsweep old_hpt stable_mods cleanup sccs = do
upsweep' old_hpt1 done' mods (mod_index+1) nmods
+maybeGetIfaceDate :: DynFlags -> ModLocation -> IO (Maybe UTCTime)
+maybeGetIfaceDate dflags location
+ | writeInterfaceOnlyMode dflags
+ -- Minor optimization: it should be harmless to check the hi file location
+ -- always, but it's better to avoid hitting the filesystem if possible.
+ = modificationTimeIfExists (ml_hi_file location)
+ | otherwise
+ = return Nothing
+
-- | Compile a single module. Always produce a Linkable for it if
-- successful. If no compilation happened, return the old Linkable.
upsweep_mod :: HscEnv
@@ -1150,6 +1159,7 @@ upsweep_mod hsc_env old_hpt (stable_obj, stable_bco) summary mod_index nmods
this_mod_name = ms_mod_name summary
this_mod = ms_mod summary
mb_obj_date = ms_obj_date summary
+ mb_if_date = ms_iface_date summary
obj_fn = ml_obj_file (ms_location summary)
hs_date = ms_hs_date summary
@@ -1287,11 +1297,26 @@ upsweep_mod hsc_env old_hpt (stable_obj, stable_bco) summary mod_index nmods
linkable <- liftIO $ findObjectLinkable this_mod obj_fn obj_date
compile_it_discard_iface (Just linkable) SourceUnmodified
+ -- See Note [Recompilation checking when typechecking only]
+ | writeInterfaceOnlyMode dflags,
+ Just if_date <- mb_if_date,
+ if_date >= hs_date -> do
+ liftIO $ debugTraceMsg (hsc_dflags hsc_env) 5
+ (text "skipping tc'd mod:" <+> ppr this_mod_name)
+ compile_it Nothing SourceUnmodified
+
_otherwise -> do
liftIO $ debugTraceMsg (hsc_dflags hsc_env) 5
(text "compiling mod:" <+> ppr this_mod_name)
compile_it Nothing SourceModified
+-- Note [Recompilation checking when typechecking only]
+-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+-- If we are compiling with -fno-code -fwrite-interface, there won't
+-- be any object code that we can compare against, nor should there
+-- be: we're *just* generating interface files. In this case, we
+-- want to check if the interface file is new, in lieu of the object
+-- file. See also Trac #9243.
-- Filter modules in the HPT
@@ -1691,6 +1716,7 @@ summariseFile hsc_env old_summaries file mb_phase obj_allowed maybe_buf
| Just old_summary <- findSummaryBySourceFile old_summaries file
= do
let location = ms_location old_summary
+ dflags = hsc_dflags hsc_env
src_timestamp <- get_src_timestamp
-- The file exists; we checked in getRootSummary above.
@@ -1707,7 +1733,9 @@ summariseFile hsc_env old_summaries file mb_phase obj_allowed maybe_buf
|| obj_allowed -- bug #1205
then liftIO $ getObjTimestamp location NotBoot
else return Nothing
- return old_summary{ ms_obj_date = obj_timestamp }
+ hi_timestamp <- maybeGetIfaceDate dflags location
+ return old_summary{ ms_obj_date = obj_timestamp
+ , ms_iface_date = hi_timestamp }
else
new_summary src_timestamp
@@ -1745,6 +1773,8 @@ summariseFile hsc_env old_summaries file mb_phase obj_allowed maybe_buf
then liftIO $ modificationTimeIfExists (ml_obj_file location)
else return Nothing
+ hi_timestamp <- maybeGetIfaceDate dflags location
+
return (ModSummary { ms_mod = mod, ms_hsc_src = hsc_src,
ms_location = location,
ms_hspp_file = hspp_fn,
@@ -1752,6 +1782,7 @@ summariseFile hsc_env old_summaries file mb_phase obj_allowed maybe_buf
ms_hspp_buf = Just buf,
ms_srcimps = srcimps, ms_textual_imps = the_imps,
ms_hs_date = src_timestamp,
+ ms_iface_date = hi_timestamp,
ms_obj_date = obj_timestamp })
findSummaryBySourceFile :: [ModSummary] -> FilePath -> Maybe ModSummary
@@ -1808,7 +1839,9 @@ summariseModule hsc_env old_summary_map is_boot (L loc wanted_mod)
|| obj_allowed -- bug #1205
then getObjTimestamp location is_boot
else return Nothing
- return (Just (Right old_summary{ ms_obj_date = obj_timestamp }))
+ hi_timestamp <- maybeGetIfaceDate dflags location
+ return (Just (Right old_summary{ ms_obj_date = obj_timestamp
+ , ms_iface_date = hi_timestamp}))
| otherwise =
-- source changed: re-summarise.
new_summary location (ms_mod old_summary) src_fn src_timestamp
@@ -1880,6 +1913,8 @@ summariseModule hsc_env old_summary_map is_boot (L loc wanted_mod)
then getObjTimestamp location is_boot
else return Nothing
+ hi_timestamp <- maybeGetIfaceDate dflags location
+
return (Just (Right (ModSummary { ms_mod = mod,
ms_hsc_src = hsc_src,
ms_location = location,
@@ -1889,6 +1924,7 @@ summariseModule hsc_env old_summary_map is_boot (L loc wanted_mod)
ms_srcimps = srcimps,
ms_textual_imps = the_imps,
ms_hs_date = src_timestamp,
+ ms_iface_date = hi_timestamp,
ms_obj_date = obj_timestamp })))
diff --git a/compiler/main/HscTypes.hs b/compiler/main/HscTypes.hs
index 29ee78c2b3..2d3203934c 100644
--- a/compiler/main/HscTypes.hs
+++ b/compiler/main/HscTypes.hs
@@ -2357,6 +2357,10 @@ data ModSummary
-- ^ Timestamp of source file
ms_obj_date :: Maybe UTCTime,
-- ^ Timestamp of object, if we have one
+ ms_iface_date :: Maybe UTCTime,
+ -- ^ Timestamp of hi file, if we *only* are typechecking (it is
+ -- 'Nothing' otherwise.
+ -- See Note [Recompilation checking when typechecking only] and #9243
ms_srcimps :: [Located (ImportDecl RdrName)],
-- ^ Source imports of the module
ms_textual_imps :: [Located (ImportDecl RdrName)],