From ce426964baf58f76ad4681d8a26f671c10ad4f7e Mon Sep 17 00:00:00 2001 From: Simon Marlow Date: Tue, 12 Jan 2010 22:58:53 +0000 Subject: [PATCH] Do some recompilation avoidance in GHC.loadModule GHC.loadModule compiles a module after it has been parsed and typechecked explicity. If we are compiling to object code and there is a valid object file already on disk, then we can skip the compilation step. This is useful in Haddock, when processing a package that uses Template Haskell and hence needs actual compilation, and the package has already been compiled. As usual, the recomp avoidance can be disabled with -fforce-recomp. --- compiler/main/GHC.hs | 24 +++++++++++++++++------- compiler/main/HscMain.lhs | 17 +++++++++++++++++ 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/compiler/main/GHC.hs b/compiler/main/GHC.hs index c01a433..f8a4dbb 100644 --- a/compiler/main/GHC.hs +++ b/compiler/main/GHC.hs @@ -1115,25 +1115,35 @@ loadModule :: (TypecheckedMod mod, GhcMonad m) => mod -> m mod loadModule tcm = do let ms = modSummary tcm let mod = ms_mod_name ms + let loc = ms_location ms let (tcg, _details) = tm_internals tcm hpt_new <- withTempSession (\e -> e { hsc_dflags = ms_hspp_opts ms }) $ do let compilerBackend comp env ms' _ _mb_old_iface _ = withTempSession (\_ -> env) $ - hscBackend comp tcg ms' - Nothing + hscBackend comp tcg ms' Nothing + hsc_env <- getSession - mod_info - <- compile' (compilerBackend hscNothingCompiler - ,compilerBackend hscInteractiveCompiler - ,compilerBackend hscBatchCompiler) - hsc_env ms 1 1 Nothing Nothing + mod_info <- do + mb_linkable <- + case ms_obj_date ms of + Just t | t > ms_hs_date ms -> do + l <- liftIO $ findObjectLinkable (ms_mod ms) + (ml_obj_file loc) t + return (Just l) + _otherwise -> return Nothing + + compile' (compilerBackend hscNothingCompiler + ,compilerBackend hscInteractiveCompiler + ,hscCheckRecompBackend hscBatchCompiler tcg) + hsc_env ms 1 1 Nothing mb_linkable -- compile' shouldn't change the environment return $ addToUFM (hsc_HPT hsc_env) mod mod_info modifySession $ \e -> e{ hsc_HPT = hpt_new } return tcm + -- | This is the way to get access to the Core bindings corresponding -- to a module. 'compileToCore' parses, typechecks, and -- desugars the module, then returns the resulting Core module (consisting of diff --git a/compiler/main/HscMain.lhs b/compiler/main/HscMain.lhs index 9f91b4d..d5ad093 100644 --- a/compiler/main/HscMain.lhs +++ b/compiler/main/HscMain.lhs @@ -24,6 +24,7 @@ module HscMain , hscCompileBatch -- :: Compiler (HscStatus, ModIface, ModDetails) , hscCompileNothing -- :: Compiler (HscStatus, ModIface, ModDetails) , hscCompileInteractive -- :: Compiler (InteractiveStatus, ModIface, ModDetails) + , hscCheckRecompBackend , HscStatus' (..) , InteractiveStatus, HscStatus @@ -382,6 +383,22 @@ genericHscCompile compiler hscMessage -> do hscMessage mb_mod_index True mod_summary hscRecompile compiler mod_summary mb_old_hash +hscCheckRecompBackend :: HsCompiler a -> TcGblEnv -> Compiler a +hscCheckRecompBackend compiler tc_result + hsc_env mod_summary source_unchanged mb_old_iface _m_of_n = + withTempSession (\_ -> hsc_env) $ do + (recomp_reqd, mb_checked_iface) + <- {-# SCC "checkOldIface" #-} + liftIO $ checkOldIface hsc_env mod_summary + source_unchanged mb_old_iface + + let mb_old_hash = fmap mi_iface_hash mb_checked_iface + case mb_checked_iface of + Just iface | not recomp_reqd + -> hscNoRecomp compiler iface{ mi_globals = Just (tcg_rdr_env tc_result) } + _otherwise + -> hscBackend compiler tc_result mod_summary mb_old_hash + genericHscRecompile :: GhcMonad m => HsCompiler a -> ModSummary -> Maybe Fingerprint -- 1.7.10.4