summaryrefslogtreecommitdiff
path: root/compiler/main/GHC.hs
diff options
context:
space:
mode:
authorBartosz Nitka <niteria@gmail.com>2017-06-27 12:55:17 -0400
committerBen Gamari <ben@smart-cactus.org>2017-06-27 13:34:05 -0400
commitb0708588e87554899c2efc80a2d3eba353dbe926 (patch)
tree03817b07a5c542a45d6058cf19a09efeaf5037bc /compiler/main/GHC.hs
parent6567c815135e93f8550d526f81d13f31c0cd92b6 (diff)
downloadhaskell-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.hs23
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