/compiler/GHC/Types/Name/Set.hs

https://github.com/bgamari/ghc · Haskell · 224 lines · 123 code · 37 blank · 64 comment · 1 complexity · e00bf5eabe027b081cd225243dfa5617 MD5 · raw file

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