/compiler/GHC/Types/Name/Env.hs

https://github.com/bgamari/ghc · Haskell · 205 lines · 128 code · 33 blank · 44 comment · 1 complexity · 86e2a4647ab53052d2b1d9b3a51b704b MD5 · raw file

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