PageRenderTime 44ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/compiler/basicTypes/NameSet.hs

http://github.com/ghc/ghc
Haskell | 213 lines | 118 code | 34 blank | 61 comment | 1 complexity | a874168de25e86614293f156e34afdc3 MD5 | raw file
Possible License(s): MIT, BSD-3-Clause, GPL-3.0
  1. {-
  2. (c) The University of Glasgow 2006
  3. (c) The GRASP/AQUA Project, Glasgow University, 1998
  4. -}
  5. {-# LANGUAGE CPP #-}
  6. module NameSet (
  7. -- * Names set type
  8. NameSet,
  9. -- ** Manipulating these sets
  10. emptyNameSet, unitNameSet, mkNameSet, unionNameSet, unionNameSets,
  11. minusNameSet, elemNameSet, extendNameSet, extendNameSetList,
  12. delFromNameSet, delListFromNameSet, isEmptyNameSet, filterNameSet,
  13. intersectsNameSet, intersectNameSet,
  14. nameSetAny, nameSetAll, nameSetElemsStable,
  15. -- * Free variables
  16. FreeVars,
  17. -- ** Manipulating sets of free variables
  18. isEmptyFVs, emptyFVs, plusFVs, plusFV,
  19. mkFVs, addOneFV, unitFV, delFV, delFVs,
  20. intersectFVs,
  21. -- * Defs and uses
  22. Defs, Uses, DefUse, DefUses,
  23. -- ** Manipulating defs and uses
  24. emptyDUs, usesOnly, mkDUs, plusDU,
  25. findUses, duDefs, duUses, allUses
  26. ) where
  27. #include "HsVersions.h"
  28. import Name
  29. import UniqSet
  30. import UniqFM
  31. import Data.List (sortBy)
  32. {-
  33. ************************************************************************
  34. * *
  35. \subsection[Sets of names}
  36. * *
  37. ************************************************************************
  38. -}
  39. type NameSet = UniqSet Name
  40. emptyNameSet :: NameSet
  41. unitNameSet :: Name -> NameSet
  42. extendNameSetList :: NameSet -> [Name] -> NameSet
  43. extendNameSet :: NameSet -> Name -> NameSet
  44. mkNameSet :: [Name] -> NameSet
  45. unionNameSet :: NameSet -> NameSet -> NameSet
  46. unionNameSets :: [NameSet] -> NameSet
  47. minusNameSet :: NameSet -> NameSet -> NameSet
  48. elemNameSet :: Name -> NameSet -> Bool
  49. isEmptyNameSet :: NameSet -> Bool
  50. delFromNameSet :: NameSet -> Name -> NameSet
  51. delListFromNameSet :: NameSet -> [Name] -> NameSet
  52. filterNameSet :: (Name -> Bool) -> NameSet -> NameSet
  53. intersectNameSet :: NameSet -> NameSet -> NameSet
  54. intersectsNameSet :: NameSet -> NameSet -> Bool
  55. -- ^ True if there is a non-empty intersection.
  56. -- @s1 `intersectsNameSet` s2@ doesn't compute @s2@ if @s1@ is empty
  57. isEmptyNameSet = isEmptyUniqSet
  58. emptyNameSet = emptyUniqSet
  59. unitNameSet = unitUniqSet
  60. mkNameSet = mkUniqSet
  61. extendNameSetList = addListToUniqSet
  62. extendNameSet = addOneToUniqSet
  63. unionNameSet = unionUniqSets
  64. unionNameSets = unionManyUniqSets
  65. minusNameSet = minusUniqSet
  66. elemNameSet = elementOfUniqSet
  67. delFromNameSet = delOneFromUniqSet
  68. filterNameSet = filterUniqSet
  69. intersectNameSet = intersectUniqSets
  70. delListFromNameSet set ns = foldl delFromNameSet set ns
  71. intersectsNameSet s1 s2 = not (isEmptyNameSet (s1 `intersectNameSet` s2))
  72. nameSetAny :: (Name -> Bool) -> NameSet -> Bool
  73. nameSetAny = uniqSetAny
  74. nameSetAll :: (Name -> Bool) -> NameSet -> Bool
  75. nameSetAll = uniqSetAll
  76. -- | Get the elements of a NameSet with some stable ordering.
  77. -- This only works for Names that originate in the source code or have been
  78. -- tidied.
  79. -- See Note [Deterministic UniqFM] to learn about nondeterminism
  80. nameSetElemsStable :: NameSet -> [Name]
  81. nameSetElemsStable ns =
  82. sortBy stableNameCmp $ nonDetEltsUFM ns
  83. -- It's OK to use nonDetEltsUFM here because we immediately sort
  84. -- with stableNameCmp
  85. {-
  86. ************************************************************************
  87. * *
  88. \subsection{Free variables}
  89. * *
  90. ************************************************************************
  91. These synonyms are useful when we are thinking of free variables
  92. -}
  93. type FreeVars = NameSet
  94. plusFV :: FreeVars -> FreeVars -> FreeVars
  95. addOneFV :: FreeVars -> Name -> FreeVars
  96. unitFV :: Name -> FreeVars
  97. emptyFVs :: FreeVars
  98. plusFVs :: [FreeVars] -> FreeVars
  99. mkFVs :: [Name] -> FreeVars
  100. delFV :: Name -> FreeVars -> FreeVars
  101. delFVs :: [Name] -> FreeVars -> FreeVars
  102. intersectFVs :: FreeVars -> FreeVars -> FreeVars
  103. isEmptyFVs :: NameSet -> Bool
  104. isEmptyFVs = isEmptyNameSet
  105. emptyFVs = emptyNameSet
  106. plusFVs = unionNameSets
  107. plusFV = unionNameSet
  108. mkFVs = mkNameSet
  109. addOneFV = extendNameSet
  110. unitFV = unitNameSet
  111. delFV n s = delFromNameSet s n
  112. delFVs ns s = delListFromNameSet s ns
  113. intersectFVs = intersectNameSet
  114. {-
  115. ************************************************************************
  116. * *
  117. Defs and uses
  118. * *
  119. ************************************************************************
  120. -}
  121. -- | A set of names that are defined somewhere
  122. type Defs = NameSet
  123. -- | A set of names that are used somewhere
  124. type Uses = NameSet
  125. -- | @(Just ds, us) =>@ The use of any member of the @ds@
  126. -- implies that all the @us@ are used too.
  127. -- Also, @us@ may mention @ds@.
  128. --
  129. -- @Nothing =>@ Nothing is defined in this group, but
  130. -- nevertheless all the uses are essential.
  131. -- Used for instance declarations, for example
  132. type DefUse = (Maybe Defs, Uses)
  133. -- | A number of 'DefUse's in dependency order: earlier 'Defs' scope over later 'Uses'
  134. -- In a single (def, use) pair, the defs also scope over the uses
  135. type DefUses = [DefUse]
  136. emptyDUs :: DefUses
  137. emptyDUs = []
  138. usesOnly :: Uses -> DefUses
  139. usesOnly uses = [(Nothing, uses)]
  140. mkDUs :: [(Defs,Uses)] -> DefUses
  141. mkDUs pairs = [(Just defs, uses) | (defs,uses) <- pairs]
  142. plusDU :: DefUses -> DefUses -> DefUses
  143. plusDU = (++)
  144. duDefs :: DefUses -> Defs
  145. duDefs dus = foldr get emptyNameSet dus
  146. where
  147. get (Nothing, _u1) d2 = d2
  148. get (Just d1, _u1) d2 = d1 `unionNameSet` d2
  149. allUses :: DefUses -> Uses
  150. -- ^ Just like 'duUses', but 'Defs' are not eliminated from the 'Uses' returned
  151. allUses dus = foldr get emptyNameSet dus
  152. where
  153. get (_d1, u1) u2 = u1 `unionNameSet` u2
  154. duUses :: DefUses -> Uses
  155. -- ^ Collect all 'Uses', regardless of whether the group is itself used,
  156. -- but remove 'Defs' on the way
  157. duUses dus = foldr get emptyNameSet dus
  158. where
  159. get (Nothing, rhs_uses) uses = rhs_uses `unionNameSet` uses
  160. get (Just defs, rhs_uses) uses = (rhs_uses `unionNameSet` uses)
  161. `minusNameSet` defs
  162. findUses :: DefUses -> Uses -> Uses
  163. -- ^ Given some 'DefUses' and some 'Uses', find all the uses, transitively.
  164. -- The result is a superset of the input 'Uses'; and includes things defined
  165. -- in the input 'DefUses' (but only if they are used)
  166. findUses dus uses
  167. = foldr get uses dus
  168. where
  169. get (Nothing, rhs_uses) uses
  170. = rhs_uses `unionNameSet` uses
  171. get (Just defs, rhs_uses) uses
  172. | defs `intersectsNameSet` uses -- Used
  173. || nameSetAny (startsWithUnderscore . nameOccName) defs
  174. -- At least one starts with an "_",
  175. -- so treat the group as used
  176. = rhs_uses `unionNameSet` uses
  177. | otherwise -- No def is used
  178. = uses