Split Reg into vreg/hreg and add register pairs
[ghc-hetmet.git] / compiler / utils / UniqSet.lhs
1 %
2 % (c) The University of Glasgow 2006
3 % (c) The AQUA Project, Glasgow University, 1994-1998
4 %
5 \section[UniqSet]{Specialised sets, for things with @Uniques@}
6
7 Based on @UniqFMs@ (as you would expect).
8
9 Basically, the things need to be in class @Uniquable@.
10
11 \begin{code}
12 module UniqSet (
13         -- * Unique set type
14         UniqSet,    -- abstract type: NOT
15
16         -- ** Manipulating these sets
17         mkUniqSet, uniqSetToList, emptyUniqSet, unitUniqSet,
18         addOneToUniqSet, addListToUniqSet, addOneToUniqSet_C,
19         delOneFromUniqSet, delListFromUniqSet, delOneFromUniqSet_Directly,
20         unionUniqSets, unionManyUniqSets, minusUniqSet,
21         elementOfUniqSet, mapUniqSet, intersectUniqSets,
22         isEmptyUniqSet, filterUniqSet, sizeUniqSet, foldUniqSet,
23         elemUniqSet_Directly, lookupUniqSet, hashUniqSet
24     ) where
25
26 import Maybes
27 import UniqFM
28 import Unique
29
30 #if ! OMIT_NATIVE_CODEGEN
31 #define IF_NCG(a) a
32 #else
33 #define IF_NCG(a) {--}
34 #endif
35 \end{code}
36
37 %************************************************************************
38 %*                                                                      *
39 \subsection{The @UniqSet@ type}
40 %*                                                                      *
41 %************************************************************************
42
43 We use @UniqFM@, with a (@getUnique@-able) @Unique@ as ``key''
44 and the thing itself as the ``value'' (for later retrieval).
45
46 \begin{code}
47 --data UniqSet a = MkUniqSet (FiniteMap Unique a) : NOT
48
49 type UniqSet a = UniqFM a
50 #define MkUniqSet {--}
51
52 emptyUniqSet :: UniqSet a
53 emptyUniqSet = MkUniqSet emptyUFM
54
55 unitUniqSet :: Uniquable a => a -> UniqSet a
56 unitUniqSet x = MkUniqSet (unitUFM x x)
57
58 uniqSetToList :: UniqSet a -> [a]
59 uniqSetToList (MkUniqSet set) = eltsUFM set
60
61 foldUniqSet :: (a -> b -> b) -> b -> UniqSet a -> b
62 foldUniqSet k z (MkUniqSet set) = foldUFM k z set
63
64 mkUniqSet :: Uniquable a => [a]  -> UniqSet a
65 mkUniqSet xs = MkUniqSet (listToUFM [ (x, x) | x <- xs])
66
67 addOneToUniqSet :: Uniquable a => UniqSet a -> a -> UniqSet a
68 addOneToUniqSet (MkUniqSet set) x = MkUniqSet (addToUFM set x x)
69
70 addOneToUniqSet_C :: Uniquable a
71                   => (a -> a -> a) -> UniqSet a -> a -> UniqSet a
72 addOneToUniqSet_C f (MkUniqSet set) x = MkUniqSet (addToUFM_C f set x x)
73
74 delOneFromUniqSet :: Uniquable a => UniqSet a -> a -> UniqSet a
75 delOneFromUniqSet (MkUniqSet set) x = MkUniqSet (delFromUFM set x)
76
77 delOneFromUniqSet_Directly :: Uniquable a => UniqSet a -> Unique -> UniqSet a
78 delOneFromUniqSet_Directly (MkUniqSet set) u
79     = MkUniqSet (delFromUFM_Directly set u)
80
81 delListFromUniqSet :: Uniquable a => UniqSet a -> [a] -> UniqSet a
82 delListFromUniqSet (MkUniqSet set) xs = MkUniqSet (delListFromUFM set xs)
83
84 addListToUniqSet :: Uniquable a => UniqSet a -> [a] -> UniqSet a
85 addListToUniqSet (MkUniqSet set) xs = MkUniqSet (addListToUFM set [(x,x) | x<-xs])
86
87 unionUniqSets :: UniqSet a -> UniqSet a -> UniqSet a
88 unionUniqSets (MkUniqSet set1) (MkUniqSet set2) = MkUniqSet (plusUFM set1 set2)
89
90 unionManyUniqSets :: [UniqSet a] -> UniqSet a
91 -- = foldr unionUniqSets emptyUniqSet ss
92 unionManyUniqSets []     = emptyUniqSet
93 unionManyUniqSets [s]    = s
94 unionManyUniqSets (s:ss) = s `unionUniqSets` unionManyUniqSets ss
95
96 minusUniqSet  :: UniqSet a -> UniqSet a -> UniqSet a
97 minusUniqSet (MkUniqSet set1) (MkUniqSet set2) = MkUniqSet (minusUFM set1 set2)
98
99 filterUniqSet :: (a -> Bool) -> UniqSet a -> UniqSet a
100 filterUniqSet pred (MkUniqSet set) = MkUniqSet (filterUFM pred set)
101
102 intersectUniqSets :: UniqSet a -> UniqSet a -> UniqSet a
103 intersectUniqSets (MkUniqSet set1) (MkUniqSet set2) = MkUniqSet (intersectUFM set1 set2)
104
105 elementOfUniqSet :: Uniquable a => a -> UniqSet a -> Bool
106 elementOfUniqSet x (MkUniqSet set) = maybeToBool (lookupUFM set x)
107
108 lookupUniqSet :: Uniquable a => UniqSet a -> a -> Maybe a
109 lookupUniqSet (MkUniqSet set) x = lookupUFM set x
110
111 elemUniqSet_Directly :: Unique -> UniqSet a -> Bool
112 elemUniqSet_Directly x (MkUniqSet set) = maybeToBool (lookupUFM_Directly set x)
113
114 sizeUniqSet :: UniqSet a -> Int
115 sizeUniqSet (MkUniqSet set) = sizeUFM set
116
117 hashUniqSet :: UniqSet a -> Int
118 hashUniqSet (MkUniqSet set) = hashUFM set
119
120 isEmptyUniqSet :: UniqSet a -> Bool
121 isEmptyUniqSet (MkUniqSet set) = isNullUFM set {-SLOW: sizeUFM set == 0-}
122
123 -- | Invariant: the mapping function doesn't change the unique
124 mapUniqSet :: (a -> b) -> UniqSet a -> UniqSet b
125 mapUniqSet f (MkUniqSet set) = MkUniqSet (mapUFM f set)
126 \end{code}
127
128 \begin{code}
129 #ifdef __GLASGOW_HASKELL__
130 {-# SPECIALIZE
131     addOneToUniqSet :: UniqSet Unique -> Unique -> UniqSet Unique
132     #-}
133
134 -- These next three specialisations disabled as importing Name creates a
135 -- loop, and getting the Uniquable Name instance in particular is tricky.
136
137 {- SPECIALIZE
138     elementOfUniqSet :: Name -> UniqSet Name -> Bool
139                       , Unique -> UniqSet Unique -> Bool
140     -}
141 {- SPECIALIZE
142     mkUniqSet :: [Name] -> UniqSet Name
143     -}
144
145 {- SPECIALIZE
146     unitUniqSet :: Name -> UniqSet Name
147                  , Unique -> UniqSet Unique
148     -}
149 #endif
150 \end{code}