diff options
author | Bartosz Nitka <niteria@gmail.com> | 2017-06-27 12:55:17 -0400 |
---|---|---|
committer | Ben Gamari <ben@smart-cactus.org> | 2017-06-27 13:34:05 -0400 |
commit | b0708588e87554899c2efc80a2d3eba353dbe926 (patch) | |
tree | 03817b07a5c542a45d6058cf19a09efeaf5037bc /compiler/main/GHC.hs | |
parent | 6567c815135e93f8550d526f81d13f31c0cd92b6 (diff) | |
download | haskell-b0708588e87554899c2efc80a2d3eba353dbe926.tar.gz |
Make module membership on ModuleGraph faster
When loading/reloading with a large number of modules
(>5000) the cost of linear lookups becomes significant.
The changes here made `:reload` go from 6s to 1s on my
test case.
The bottlenecks were `needsLinker` in `DriverPipeline` and
`getModLoop` in `GhcMake`.
Test Plan: ./validate
Reviewers: simonmar, austin, bgamari
Subscribers: rwbarton, thomie
Differential Revision: https://phabricator.haskell.org/D3646
Diffstat (limited to 'compiler/main/GHC.hs')
-rw-r--r-- | compiler/main/GHC.hs | 23 |
1 files changed, 9 insertions, 14 deletions
diff --git a/compiler/main/GHC.hs b/compiler/main/GHC.hs index 2102009019..3ca07f1443 100644 --- a/compiler/main/GHC.hs +++ b/compiler/main/GHC.hs @@ -23,7 +23,7 @@ module GHC ( gcatch, gbracket, gfinally, printException, handleSourceError, - needsTemplateHaskell, + needsTemplateHaskellOrQQ, -- * Flags and settings DynFlags(..), GeneralFlag(..), Severity(..), HscTarget(..), gopt, @@ -59,7 +59,8 @@ module GHC ( compileToCoreModule, compileToCoreSimplified, -- * Inspecting the module structure of the program - ModuleGraph, emptyMG, mapMG, + ModuleGraph, emptyMG, mapMG, mkModuleGraph, mgModSummaries, + mgLookupModule, ModSummary(..), ms_mod_name, ModLocation(..), getModSummary, getModuleGraph, @@ -873,7 +874,10 @@ type TypecheckedSource = LHsBinds GhcTc getModSummary :: GhcMonad m => ModuleName -> m ModSummary getModSummary mod = do mg <- liftM hsc_mod_graph getSession - case [ ms | ms <- mg, ms_mod_name ms == mod, not (isBootSummary ms) ] of + let mods_by_name = [ ms | ms <- mgModSummaries mg + , ms_mod_name ms == mod + , not (isBootSummary ms) ] + case mods_by_name of [] -> do dflags <- getDynFlags liftIO $ throwIO $ mkApiErr dflags (text "Module not part of module graph") [ms] -> return ms @@ -1023,7 +1027,7 @@ compileCore simplify fn = do _ <- load LoadAllTargets -- Then find dependencies modGraph <- depanal [] True - case find ((== fn) . msHsFilePath) modGraph of + case find ((== fn) . msHsFilePath) (mgModSummaries modGraph) of Just modSummary -> do -- Now we have the module name; -- parse, typecheck and desugar the module @@ -1075,15 +1079,6 @@ compileCore simplify fn = do getModuleGraph :: GhcMonad m => m ModuleGraph -- ToDo: DiGraph ModSummary getModuleGraph = liftM hsc_mod_graph getSession --- | Determines whether a set of modules requires Template Haskell. --- --- Note that if the session's 'DynFlags' enabled Template Haskell when --- 'depanal' was called, then each module in the returned module graph will --- have Template Haskell enabled whether it is actually needed or not. -needsTemplateHaskell :: ModuleGraph -> Bool -needsTemplateHaskell ms = - any (xopt LangExt.TemplateHaskell . ms_hspp_opts) ms - -- | Return @True@ <==> module is loaded. isLoaded :: GhcMonad m => ModuleName -> m Bool isLoaded m = withSession $ \hsc_env -> @@ -1120,7 +1115,7 @@ data ModuleInfo = ModuleInfo { getModuleInfo :: GhcMonad m => Module -> m (Maybe ModuleInfo) -- XXX: Maybe X getModuleInfo mdl = withSession $ \hsc_env -> do let mg = hsc_mod_graph hsc_env - if mdl `elem` map ms_mod mg + if mgElemModule mg mdl then liftIO $ getHomeModuleInfo hsc_env mdl else do {- if isHomeModule (hsc_dflags hsc_env) mdl |