PageRenderTime 53ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/compiler/basicTypes/VarSet.hs

http://github.com/ghc/ghc
Haskell | 334 lines | 192 code | 62 blank | 80 comment | 0 complexity | 5f1e5ac56a5d692fd93e36f2f89b6558 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, 1992-1998
  4. -}
  5. {-# LANGUAGE CPP #-}
  6. module VarSet (
  7. -- * Var, Id and TyVar set types
  8. VarSet, IdSet, TyVarSet, CoVarSet, TyCoVarSet,
  9. -- ** Manipulating these sets
  10. emptyVarSet, unitVarSet, mkVarSet,
  11. extendVarSet, extendVarSetList, extendVarSet_C,
  12. elemVarSet, subVarSet,
  13. unionVarSet, unionVarSets, mapUnionVarSet,
  14. intersectVarSet, intersectsVarSet, disjointVarSet,
  15. isEmptyVarSet, delVarSet, delVarSetList, delVarSetByKey,
  16. minusVarSet, filterVarSet,
  17. varSetAny, varSetAll,
  18. transCloVarSet, fixVarSet,
  19. lookupVarSet, lookupVarSetByName,
  20. sizeVarSet, seqVarSet,
  21. elemVarSetByKey, partitionVarSet,
  22. pluralVarSet, pprVarSet,
  23. -- * Deterministic Var set types
  24. DVarSet, DIdSet, DTyVarSet, DTyCoVarSet,
  25. -- ** Manipulating these sets
  26. emptyDVarSet, unitDVarSet, mkDVarSet,
  27. extendDVarSet, extendDVarSetList,
  28. elemDVarSet, dVarSetElems, subDVarSet,
  29. unionDVarSet, unionDVarSets, mapUnionDVarSet,
  30. intersectDVarSet, intersectsDVarSet, disjointDVarSet,
  31. isEmptyDVarSet, delDVarSet, delDVarSetList,
  32. minusDVarSet, foldDVarSet, filterDVarSet,
  33. dVarSetMinusVarSet,
  34. transCloDVarSet,
  35. sizeDVarSet, seqDVarSet,
  36. partitionDVarSet,
  37. dVarSetToVarSet,
  38. ) where
  39. #include "HsVersions.h"
  40. import Var ( Var, TyVar, CoVar, TyCoVar, Id )
  41. import Unique
  42. import Name ( Name )
  43. import UniqSet
  44. import UniqDSet
  45. import UniqFM( disjointUFM, pluralUFM, pprUFM )
  46. import UniqDFM( disjointUDFM, udfmToUfm )
  47. import Outputable (SDoc)
  48. -- | A non-deterministic Variable Set
  49. --
  50. -- A non-deterministic set of variables.
  51. -- See Note [Deterministic UniqFM] in UniqDFM for explanation why it's not
  52. -- deterministic and why it matters. Use DVarSet if the set eventually
  53. -- gets converted into a list or folded over in a way where the order
  54. -- changes the generated code, for example when abstracting variables.
  55. type VarSet = UniqSet Var
  56. -- | Identifier Set
  57. type IdSet = UniqSet Id
  58. -- | Type Variable Set
  59. type TyVarSet = UniqSet TyVar
  60. -- | Coercion Variable Set
  61. type CoVarSet = UniqSet CoVar
  62. -- | Type or Coercion Variable Set
  63. type TyCoVarSet = UniqSet TyCoVar
  64. emptyVarSet :: VarSet
  65. intersectVarSet :: VarSet -> VarSet -> VarSet
  66. unionVarSet :: VarSet -> VarSet -> VarSet
  67. unionVarSets :: [VarSet] -> VarSet
  68. mapUnionVarSet :: (a -> VarSet) -> [a] -> VarSet
  69. -- ^ map the function over the list, and union the results
  70. unitVarSet :: Var -> VarSet
  71. extendVarSet :: VarSet -> Var -> VarSet
  72. extendVarSetList:: VarSet -> [Var] -> VarSet
  73. elemVarSet :: Var -> VarSet -> Bool
  74. delVarSet :: VarSet -> Var -> VarSet
  75. delVarSetList :: VarSet -> [Var] -> VarSet
  76. minusVarSet :: VarSet -> VarSet -> VarSet
  77. isEmptyVarSet :: VarSet -> Bool
  78. mkVarSet :: [Var] -> VarSet
  79. lookupVarSet :: VarSet -> Var -> Maybe Var
  80. -- Returns the set element, which may be
  81. -- (==) to the argument, but not the same as
  82. lookupVarSetByName :: VarSet -> Name -> Maybe Var
  83. sizeVarSet :: VarSet -> Int
  84. filterVarSet :: (Var -> Bool) -> VarSet -> VarSet
  85. extendVarSet_C :: (Var->Var->Var) -> VarSet -> Var -> VarSet
  86. delVarSetByKey :: VarSet -> Unique -> VarSet
  87. elemVarSetByKey :: Unique -> VarSet -> Bool
  88. partitionVarSet :: (Var -> Bool) -> VarSet -> (VarSet, VarSet)
  89. emptyVarSet = emptyUniqSet
  90. unitVarSet = unitUniqSet
  91. extendVarSet = addOneToUniqSet
  92. extendVarSetList= addListToUniqSet
  93. intersectVarSet = intersectUniqSets
  94. intersectsVarSet:: VarSet -> VarSet -> Bool -- True if non-empty intersection
  95. disjointVarSet :: VarSet -> VarSet -> Bool -- True if empty intersection
  96. subVarSet :: VarSet -> VarSet -> Bool -- True if first arg is subset of second
  97. -- (s1 `intersectsVarSet` s2) doesn't compute s2 if s1 is empty;
  98. -- ditto disjointVarSet, subVarSet
  99. unionVarSet = unionUniqSets
  100. unionVarSets = unionManyUniqSets
  101. elemVarSet = elementOfUniqSet
  102. minusVarSet = minusUniqSet
  103. delVarSet = delOneFromUniqSet
  104. delVarSetList = delListFromUniqSet
  105. isEmptyVarSet = isEmptyUniqSet
  106. mkVarSet = mkUniqSet
  107. lookupVarSet = lookupUniqSet
  108. lookupVarSetByName = lookupUniqSet
  109. sizeVarSet = sizeUniqSet
  110. filterVarSet = filterUniqSet
  111. extendVarSet_C = addOneToUniqSet_C
  112. delVarSetByKey = delOneFromUniqSet_Directly
  113. elemVarSetByKey = elemUniqSet_Directly
  114. partitionVarSet = partitionUniqSet
  115. mapUnionVarSet get_set xs = foldr (unionVarSet . get_set) emptyVarSet xs
  116. -- See comments with type signatures
  117. intersectsVarSet s1 s2 = not (s1 `disjointVarSet` s2)
  118. disjointVarSet s1 s2 = disjointUFM s1 s2
  119. subVarSet s1 s2 = isEmptyVarSet (s1 `minusVarSet` s2)
  120. varSetAny :: (Var -> Bool) -> VarSet -> Bool
  121. varSetAny = uniqSetAny
  122. varSetAll :: (Var -> Bool) -> VarSet -> Bool
  123. varSetAll = uniqSetAll
  124. -- There used to exist mapVarSet, see Note [Unsound mapUniqSet] in UniqSet for
  125. -- why it got removed.
  126. fixVarSet :: (VarSet -> VarSet) -- Map the current set to a new set
  127. -> VarSet -> VarSet
  128. -- (fixVarSet f s) repeatedly applies f to the set s,
  129. -- until it reaches a fixed point.
  130. fixVarSet fn vars
  131. | new_vars `subVarSet` vars = vars
  132. | otherwise = fixVarSet fn new_vars
  133. where
  134. new_vars = fn vars
  135. transCloVarSet :: (VarSet -> VarSet)
  136. -- Map some variables in the set to
  137. -- extra variables that should be in it
  138. -> VarSet -> VarSet
  139. -- (transCloVarSet f s) repeatedly applies f to new candidates, adding any
  140. -- new variables to s that it finds thereby, until it reaches a fixed point.
  141. --
  142. -- The function fn could be (Var -> VarSet), but we use (VarSet -> VarSet)
  143. -- for efficiency, so that the test can be batched up.
  144. -- It's essential that fn will work fine if given new candidates
  145. -- one at at time; ie fn {v1,v2} = fn v1 `union` fn v2
  146. -- Use fixVarSet if the function needs to see the whole set all at once
  147. transCloVarSet fn seeds
  148. = go seeds seeds
  149. where
  150. go :: VarSet -- Accumulating result
  151. -> VarSet -- Work-list; un-processed subset of accumulating result
  152. -> VarSet
  153. -- Specification: go acc vs = acc `union` transClo fn vs
  154. go acc candidates
  155. | isEmptyVarSet new_vs = acc
  156. | otherwise = go (acc `unionVarSet` new_vs) new_vs
  157. where
  158. new_vs = fn candidates `minusVarSet` acc
  159. seqVarSet :: VarSet -> ()
  160. seqVarSet s = sizeVarSet s `seq` ()
  161. -- | Determines the pluralisation suffix appropriate for the length of a set
  162. -- in the same way that plural from Outputable does for lists.
  163. pluralVarSet :: VarSet -> SDoc
  164. pluralVarSet = pluralUFM
  165. -- | Pretty-print a non-deterministic set.
  166. -- The order of variables is non-deterministic and for pretty-printing that
  167. -- shouldn't be a problem.
  168. -- Having this function helps contain the non-determinism created with
  169. -- nonDetEltsUFM.
  170. -- Passing a list to the pretty-printing function allows the caller
  171. -- to decide on the order of Vars (eg. toposort them) without them having
  172. -- to use nonDetEltsUFM at the call site. This prevents from let-binding
  173. -- non-deterministically ordered lists and reusing them where determinism
  174. -- matters.
  175. pprVarSet :: VarSet -- ^ The things to be pretty printed
  176. -> ([Var] -> SDoc) -- ^ The pretty printing function to use on the
  177. -- elements
  178. -> SDoc -- ^ 'SDoc' where the things have been pretty
  179. -- printed
  180. pprVarSet = pprUFM
  181. -- Deterministic VarSet
  182. -- See Note [Deterministic UniqFM] in UniqDFM for explanation why we need
  183. -- DVarSet.
  184. -- | Deterministic Variable Set
  185. type DVarSet = UniqDSet Var
  186. -- | Deterministic Identifier Set
  187. type DIdSet = UniqDSet Id
  188. -- | Deterministic Type Variable Set
  189. type DTyVarSet = UniqDSet TyVar
  190. -- | Deterministic Type or Coercion Variable Set
  191. type DTyCoVarSet = UniqDSet TyCoVar
  192. emptyDVarSet :: DVarSet
  193. emptyDVarSet = emptyUniqDSet
  194. unitDVarSet :: Var -> DVarSet
  195. unitDVarSet = unitUniqDSet
  196. mkDVarSet :: [Var] -> DVarSet
  197. mkDVarSet = mkUniqDSet
  198. extendDVarSet :: DVarSet -> Var -> DVarSet
  199. extendDVarSet = addOneToUniqDSet
  200. elemDVarSet :: Var -> DVarSet -> Bool
  201. elemDVarSet = elementOfUniqDSet
  202. dVarSetElems :: DVarSet -> [Var]
  203. dVarSetElems = uniqDSetToList
  204. subDVarSet :: DVarSet -> DVarSet -> Bool
  205. subDVarSet s1 s2 = isEmptyDVarSet (s1 `minusDVarSet` s2)
  206. unionDVarSet :: DVarSet -> DVarSet -> DVarSet
  207. unionDVarSet = unionUniqDSets
  208. unionDVarSets :: [DVarSet] -> DVarSet
  209. unionDVarSets = unionManyUniqDSets
  210. -- | Map the function over the list, and union the results
  211. mapUnionDVarSet :: (a -> DVarSet) -> [a] -> DVarSet
  212. mapUnionDVarSet get_set xs = foldr (unionDVarSet . get_set) emptyDVarSet xs
  213. intersectDVarSet :: DVarSet -> DVarSet -> DVarSet
  214. intersectDVarSet = intersectUniqDSets
  215. -- | True if empty intersection
  216. disjointDVarSet :: DVarSet -> DVarSet -> Bool
  217. disjointDVarSet s1 s2 = disjointUDFM s1 s2
  218. -- | True if non-empty intersection
  219. intersectsDVarSet :: DVarSet -> DVarSet -> Bool
  220. intersectsDVarSet s1 s2 = not (s1 `disjointDVarSet` s2)
  221. isEmptyDVarSet :: DVarSet -> Bool
  222. isEmptyDVarSet = isEmptyUniqDSet
  223. delDVarSet :: DVarSet -> Var -> DVarSet
  224. delDVarSet = delOneFromUniqDSet
  225. minusDVarSet :: DVarSet -> DVarSet -> DVarSet
  226. minusDVarSet = minusUniqDSet
  227. dVarSetMinusVarSet :: DVarSet -> VarSet -> DVarSet
  228. dVarSetMinusVarSet = uniqDSetMinusUniqSet
  229. foldDVarSet :: (Var -> a -> a) -> a -> DVarSet -> a
  230. foldDVarSet = foldUniqDSet
  231. filterDVarSet :: (Var -> Bool) -> DVarSet -> DVarSet
  232. filterDVarSet = filterUniqDSet
  233. sizeDVarSet :: DVarSet -> Int
  234. sizeDVarSet = sizeUniqDSet
  235. -- | Partition DVarSet according to the predicate given
  236. partitionDVarSet :: (Var -> Bool) -> DVarSet -> (DVarSet, DVarSet)
  237. partitionDVarSet = partitionUniqDSet
  238. -- | Delete a list of variables from DVarSet
  239. delDVarSetList :: DVarSet -> [Var] -> DVarSet
  240. delDVarSetList = delListFromUniqDSet
  241. seqDVarSet :: DVarSet -> ()
  242. seqDVarSet s = sizeDVarSet s `seq` ()
  243. -- | Add a list of variables to DVarSet
  244. extendDVarSetList :: DVarSet -> [Var] -> DVarSet
  245. extendDVarSetList = addListToUniqDSet
  246. -- | Convert a DVarSet to a VarSet by forgeting the order of insertion
  247. dVarSetToVarSet :: DVarSet -> VarSet
  248. dVarSetToVarSet = udfmToUfm
  249. -- | transCloVarSet for DVarSet
  250. transCloDVarSet :: (DVarSet -> DVarSet)
  251. -- Map some variables in the set to
  252. -- extra variables that should be in it
  253. -> DVarSet -> DVarSet
  254. -- (transCloDVarSet f s) repeatedly applies f to new candidates, adding any
  255. -- new variables to s that it finds thereby, until it reaches a fixed point.
  256. --
  257. -- The function fn could be (Var -> DVarSet), but we use (DVarSet -> DVarSet)
  258. -- for efficiency, so that the test can be batched up.
  259. -- It's essential that fn will work fine if given new candidates
  260. -- one at at time; ie fn {v1,v2} = fn v1 `union` fn v2
  261. transCloDVarSet fn seeds
  262. = go seeds seeds
  263. where
  264. go :: DVarSet -- Accumulating result
  265. -> DVarSet -- Work-list; un-processed subset of accumulating result
  266. -> DVarSet
  267. -- Specification: go acc vs = acc `union` transClo fn vs
  268. go acc candidates
  269. | isEmptyDVarSet new_vs = acc
  270. | otherwise = go (acc `unionDVarSet` new_vs) new_vs
  271. where
  272. new_vs = fn candidates `minusDVarSet` acc