summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Pickering <matthewtpickering@gmail.com>2022-04-25 14:40:19 +0100
committerMarge Bot <ben+marge-bot@smart-cactus.org>2022-04-29 04:11:29 -0400
commit8ed571353c0d6d7e7039686809ea95309bfb32d4 (patch)
tree93ba3675393a39196d4b0d3ff1417ed1bfecd634
parent22cf46980ad9b57eb428e7be045a1bc198b6380d (diff)
downloadhaskell-8ed571353c0d6d7e7039686809ea95309bfb32d4.tar.gz
Provide efficient unionMG function for combining two module graphs.
This function is used by API clients (hls). This supercedes !6922
-rw-r--r--compiler/GHC/Unit/Module/Graph.hs29
1 files changed, 25 insertions, 4 deletions
diff --git a/compiler/GHC/Unit/Module/Graph.hs b/compiler/GHC/Unit/Module/Graph.hs
index e77b38a33f..06f3fcdc68 100644
--- a/compiler/GHC/Unit/Module/Graph.hs
+++ b/compiler/GHC/Unit/Module/Graph.hs
@@ -11,6 +11,7 @@ module GHC.Unit.Module.Graph
, extendMG
, extendMGInst
, extendMG'
+ , unionMG
, isTemplateHaskellOrQQNonBoot
, filterToposortToModules
, mapMG
@@ -65,6 +66,8 @@ import GHC.Linker.Static.Utils
import Data.Bifunctor
import Data.Either
+import Data.Function
+import GHC.Data.List.SetOps
-- | A '@ModuleGraphNode@' is a node in the '@ModuleGraph@'.
-- Edges between nodes mark dependencies arising from module imports
@@ -99,6 +102,12 @@ instance Outputable ModuleGraphNode where
ModuleNode nks ms -> ppr (ms_mnwib ms) <+> ppr nks
LinkNode uid _ -> text "LN:" <+> ppr uid
+instance Eq ModuleGraphNode where
+ (==) = (==) `on` mkNodeKey
+
+instance Ord ModuleGraphNode where
+ compare = compare `on` mkNodeKey
+
data NodeKey = NodeKey_Unit {-# UNPACK #-} !InstantiatedUnit
| NodeKey_Module {-# UNPACK #-} !ModNodeKeyWithUid
| NodeKey_Link !UnitId
@@ -149,6 +158,16 @@ mapMG f mg@ModuleGraph{..} = mg
, mg_non_boot = mapModuleEnv f mg_non_boot
}
+unionMG :: ModuleGraph -> ModuleGraph -> ModuleGraph
+unionMG a b =
+ let new_mss = nubOrdBy compare $ mg_mss a `mappend` mg_mss b
+ in ModuleGraph {
+ mg_mss = new_mss
+ , mg_trans_deps = mkTransDeps new_mss
+ , mg_non_boot = mg_non_boot a `plusModuleEnv` mg_non_boot b
+ }
+
+
mgTransDeps :: ModuleGraph -> Map.Map NodeKey (Set.Set NodeKey)
mgTransDeps = mg_trans_deps
@@ -176,14 +195,16 @@ isTemplateHaskellOrQQNonBoot ms =
extendMG :: ModuleGraph -> [NodeKey] -> ModSummary -> ModuleGraph
extendMG ModuleGraph{..} deps ms = ModuleGraph
{ mg_mss = ModuleNode deps ms : mg_mss
- , mg_trans_deps = td
+ , mg_trans_deps = mkTransDeps (ModuleNode deps ms : mg_mss)
, mg_non_boot = case isBootSummary ms of
IsBoot -> mg_non_boot
NotBoot -> extendModuleEnv mg_non_boot (ms_mod ms) ms
}
- where
- (gg, _lookup_node) = moduleGraphNodes False (ModuleNode deps ms : mg_mss)
- td = allReachable gg (mkNodeKey . node_payload)
+
+mkTransDeps :: [ModuleGraphNode] -> Map.Map NodeKey (Set.Set NodeKey)
+mkTransDeps mss =
+ let (gg, _lookup_node) = moduleGraphNodes False mss
+ in allReachable gg (mkNodeKey . node_payload)
extendMGInst :: ModuleGraph -> UnitId -> InstantiatedUnit -> ModuleGraph
extendMGInst mg uid depUnitId = mg