1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207
|
{-
(c) The University of Glasgow 2006
(c) The GRASP/AQUA Project, Glasgow University, 1992-1998
\section[NameEnv]{@NameEnv@: name environments}
-}
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE ScopedTypeVariables #-}
module GHC.Types.Name.Env (
-- * Var, Id and TyVar environments (maps)
NameEnv,
-- ** Manipulating these environments
mkNameEnv, mkNameEnvWith,
emptyNameEnv, isEmptyNameEnv,
unitNameEnv, nonDetNameEnvElts,
extendNameEnv_C, extendNameEnv_Acc, extendNameEnv,
extendNameEnvList, extendNameEnvList_C,
filterNameEnv, mapMaybeNameEnv, anyNameEnv,
plusNameEnv, plusNameEnv_C, plusNameEnv_CD, plusNameEnv_CD2, alterNameEnv,
lookupNameEnv, lookupNameEnv_NF, delFromNameEnv, delListFromNameEnv,
elemNameEnv, mapNameEnv, disjointNameEnv,
seqEltsNameEnv,
DNameEnv,
emptyDNameEnv,
isEmptyDNameEnv,
lookupDNameEnv,
delFromDNameEnv, filterDNameEnv,
mapDNameEnv,
adjustDNameEnv, alterDNameEnv, extendDNameEnv,
eltsDNameEnv, extendDNameEnv_C,
plusDNameEnv_C,
foldDNameEnv,
nonDetStrictFoldDNameEnv,
-- ** Dependency analysis
depAnal
) where
import GHC.Prelude
import GHC.Data.Graph.Directed
import GHC.Types.Name
import GHC.Types.Unique.FM
import GHC.Types.Unique.DFM
import GHC.Data.Maybe
{-
************************************************************************
* *
\subsection{Name environment}
* *
************************************************************************
-}
{-
Note [depAnal determinism]
~~~~~~~~~~~~~~~~~~~~~~~~~~
depAnal is deterministic provided it gets the nodes in a deterministic order.
The order of lists that get_defs and get_uses return doesn't matter, as these
are only used to construct the edges, and stronglyConnCompFromEdgedVertices is
deterministic even when the edges are not in deterministic order as explained
in Note [Deterministic SCC] in GHC.Data.Graph.Directed.
-}
depAnal :: forall node.
(node -> [Name]) -- Defs
-> (node -> [Name]) -- Uses
-> [node]
-> [SCC node]
-- Perform dependency analysis on a group of definitions,
-- where each definition may define more than one Name
--
-- The get_defs and get_uses functions are called only once per node
depAnal get_defs get_uses nodes
= stronglyConnCompFromEdgedVerticesUniq graph_nodes
where
graph_nodes = (map mk_node keyed_nodes) :: [Node Int node]
keyed_nodes = nodes `zip` [(1::Int)..]
mk_node (node, key) =
let !edges = (mapMaybe (lookupNameEnv key_map) (get_uses node))
in DigraphNode node key edges
key_map :: NameEnv Int -- Maps a Name to the key of the decl that defines it
key_map = mkNameEnv [(name,key) | (node, key) <- keyed_nodes, name <- get_defs node]
{-
************************************************************************
* *
\subsection{Name environment}
* *
************************************************************************
-}
-- | Name Environment
type NameEnv a = UniqFM Name a -- Domain is Name
emptyNameEnv :: NameEnv a
isEmptyNameEnv :: NameEnv a -> Bool
mkNameEnv :: [(Name,a)] -> NameEnv a
mkNameEnvWith :: (a -> Name) -> [a] -> NameEnv a
nonDetNameEnvElts :: NameEnv a -> [a]
alterNameEnv :: (Maybe a-> Maybe a) -> NameEnv a -> Name -> NameEnv a
extendNameEnv_C :: (a->a->a) -> NameEnv a -> Name -> a -> NameEnv a
extendNameEnv_Acc :: (a->b->b) -> (a->b) -> NameEnv b -> Name -> a -> NameEnv b
extendNameEnv :: NameEnv a -> Name -> a -> NameEnv a
plusNameEnv :: NameEnv a -> NameEnv a -> NameEnv a
plusNameEnv_C :: (a->a->a) -> NameEnv a -> NameEnv a -> NameEnv a
plusNameEnv_CD :: (a->a->a) -> NameEnv a -> a -> NameEnv a -> a -> NameEnv a
plusNameEnv_CD2 :: (Maybe a->Maybe a->a) -> NameEnv a -> NameEnv a -> NameEnv a
extendNameEnvList :: NameEnv a -> [(Name,a)] -> NameEnv a
extendNameEnvList_C :: (a->a->a) -> NameEnv a -> [(Name,a)] -> NameEnv a
delFromNameEnv :: NameEnv a -> Name -> NameEnv a
delListFromNameEnv :: NameEnv a -> [Name] -> NameEnv a
elemNameEnv :: Name -> NameEnv a -> Bool
unitNameEnv :: Name -> a -> NameEnv a
lookupNameEnv :: NameEnv a -> Name -> Maybe a
lookupNameEnv_NF :: NameEnv a -> Name -> a
filterNameEnv :: (elt -> Bool) -> NameEnv elt -> NameEnv elt
mapMaybeNameEnv :: (a -> Maybe b) -> NameEnv a -> NameEnv b
anyNameEnv :: (elt -> Bool) -> NameEnv elt -> Bool
mapNameEnv :: (elt1 -> elt2) -> NameEnv elt1 -> NameEnv elt2
disjointNameEnv :: NameEnv a -> NameEnv a -> Bool
seqEltsNameEnv :: (elt -> ()) -> NameEnv elt -> ()
nonDetNameEnvElts x = nonDetEltsUFM x
emptyNameEnv = emptyUFM
isEmptyNameEnv = isNullUFM
unitNameEnv x y = unitUFM x y
extendNameEnv x y z = addToUFM x y z
extendNameEnvList x l = addListToUFM x l
lookupNameEnv x y = lookupUFM x y
alterNameEnv = alterUFM
mkNameEnv l = listToUFM l
mkNameEnvWith f = mkNameEnv . map (\a -> (f a, a))
elemNameEnv x y = elemUFM x y
plusNameEnv x y = plusUFM x y
plusNameEnv_C f x y = plusUFM_C f x y
{-# INLINE plusNameEnv_CD #-}
plusNameEnv_CD f x d y b = plusUFM_CD f x d y b
plusNameEnv_CD2 f x y = plusUFM_CD2 f x y
extendNameEnv_C f x y z = addToUFM_C f x y z
mapNameEnv f x = mapUFM f x
extendNameEnv_Acc x y z a b = addToUFM_Acc x y z a b
extendNameEnvList_C x y z = addListToUFM_C x y z
delFromNameEnv x y = delFromUFM x y
delListFromNameEnv x y = delListFromUFM x y
filterNameEnv x y = filterUFM x y
mapMaybeNameEnv x y = mapMaybeUFM x y
anyNameEnv f x = foldUFM ((||) . f) False x
disjointNameEnv x y = disjointUFM x y
seqEltsNameEnv seqElt x = seqEltsUFM seqElt x
lookupNameEnv_NF env n = expectJust "lookupNameEnv_NF" (lookupNameEnv env n)
-- | Deterministic Name Environment
--
-- See Note [Deterministic UniqFM] in "GHC.Types.Unique.DFM" for explanation why
-- we need DNameEnv.
type DNameEnv a = UniqDFM Name a
emptyDNameEnv :: DNameEnv a
emptyDNameEnv = emptyUDFM
isEmptyDNameEnv :: DNameEnv a -> Bool
isEmptyDNameEnv = isNullUDFM
lookupDNameEnv :: DNameEnv a -> Name -> Maybe a
lookupDNameEnv = lookupUDFM
delFromDNameEnv :: DNameEnv a -> Name -> DNameEnv a
delFromDNameEnv = delFromUDFM
filterDNameEnv :: (a -> Bool) -> DNameEnv a -> DNameEnv a
filterDNameEnv = filterUDFM
mapDNameEnv :: (a -> b) -> DNameEnv a -> DNameEnv b
mapDNameEnv = mapUDFM
adjustDNameEnv :: (a -> a) -> DNameEnv a -> Name -> DNameEnv a
adjustDNameEnv = adjustUDFM
alterDNameEnv :: (Maybe a -> Maybe a) -> DNameEnv a -> Name -> DNameEnv a
alterDNameEnv = alterUDFM
extendDNameEnv :: DNameEnv a -> Name -> a -> DNameEnv a
extendDNameEnv = addToUDFM
extendDNameEnv_C :: (a -> a -> a) -> DNameEnv a -> Name -> a -> DNameEnv a
extendDNameEnv_C = addToUDFM_C
eltsDNameEnv :: DNameEnv a -> [a]
eltsDNameEnv = eltsUDFM
foldDNameEnv :: (a -> b -> b) -> b -> DNameEnv a -> b
foldDNameEnv = foldUDFM
plusDNameEnv_C :: (elt -> elt -> elt) -> DNameEnv elt -> DNameEnv elt -> DNameEnv elt
plusDNameEnv_C = plusUDFM_C
nonDetStrictFoldDNameEnv :: (a -> b -> b) -> b -> DNameEnv a -> b
nonDetStrictFoldDNameEnv = nonDetStrictFoldUDFM
|