2 % (c) The AQUA Project, Glasgow University, 1994-1996
4 \section[UniqFM]{Specialised finite maps, for things with @Uniques@}
6 Based on @FiniteMaps@ (as you would expect).
8 Basically, the things need to be in class @Uniquable@, and we use the
9 @uniqueOf@ method to grab their @Uniques@.
11 (A similar thing to @UniqSet@, as opposed to @Set@.)
14 #if defined(COMPILING_GHC)
15 #include "HsVersions.h"
16 #define IF_NOT_GHC(a) {--}
18 #define ASSERT(e) {--}
19 #define IF_NOT_GHC(a) a
23 UniqFM, -- abstract type
24 Uniquable(..), -- class to go with it
34 addListToUFM_Directly,
35 IF_NOT_GHC(addToUFM_C COMMA)
44 IF_NOT_GHC(intersectUFM_C COMMA)
45 IF_NOT_GHC(foldUFM COMMA)
50 lookupUFM, lookupUFM_Directly,
51 lookupWithDefaultUFM, lookupWithDefaultUFM_Directly,
56 #if defined(COMPILING_GHC)
58 import {-hide from mkdependHS-}
59 Name ( Name ) -- specialising only
60 import {-hide from mkdependHS-}
61 RnHsSyn ( RnName ) -- specialising only
64 import Unique ( Unique, u2i, mkUniqueGrimily )
66 import Pretty ( SYN_IE(Pretty), PrettyRep )
67 import PprStyle ( PprStyle )
68 import SrcLoc ( SrcLoc )
70 #if ! OMIT_NATIVE_CODEGEN
73 #define IF_NCG(a) {--}
77 %************************************************************************
79 \subsection{The @UniqFM@ type, and signatures for the functions}
81 %************************************************************************
83 We use @FiniteMaps@, with a (@uniqueOf@-able) @Unique@ as ``key''.
86 emptyUFM :: UniqFM elt
87 isNullUFM :: UniqFM elt -> Bool
88 unitUFM :: Uniquable key => key -> elt -> UniqFM elt
89 unitDirectlyUFM -- got the Unique already
90 :: Unique -> elt -> UniqFM elt
91 listToUFM :: Uniquable key => [(key,elt)] -> UniqFM elt
93 :: [(Unique, elt)] -> UniqFM elt
95 addToUFM :: Uniquable key => UniqFM elt -> key -> elt -> UniqFM elt
96 addListToUFM :: Uniquable key => UniqFM elt -> [(key,elt)] -> UniqFM elt
98 :: UniqFM elt -> Unique -> elt -> UniqFM elt
100 addToUFM_C :: Uniquable key => (elt -> elt -> elt)
101 -> UniqFM elt -> key -> elt -> UniqFM elt
102 addListToUFM_C :: Uniquable key => (elt -> elt -> elt)
103 -> UniqFM elt -> [(key,elt)]
106 delFromUFM :: Uniquable key => UniqFM elt -> key -> UniqFM elt
107 delListFromUFM :: Uniquable key => UniqFM elt -> [key] -> UniqFM elt
108 delFromUFM_Directly :: UniqFM elt -> Unique -> UniqFM elt
110 plusUFM :: UniqFM elt -> UniqFM elt -> UniqFM elt
112 plusUFM_C :: (elt -> elt -> elt)
113 -> UniqFM elt -> UniqFM elt -> UniqFM elt
115 minusUFM :: UniqFM elt -> UniqFM elt -> UniqFM elt
117 intersectUFM :: UniqFM elt -> UniqFM elt -> UniqFM elt
118 intersectUFM_C :: (elt -> elt -> elt)
119 -> UniqFM elt -> UniqFM elt -> UniqFM elt
120 foldUFM :: (elt -> a -> a) -> a -> UniqFM elt -> a
121 mapUFM :: (elt1 -> elt2) -> UniqFM elt1 -> UniqFM elt2
122 filterUFM :: (elt -> Bool) -> UniqFM elt -> UniqFM elt
124 sizeUFM :: UniqFM elt -> Int
126 lookupUFM :: Uniquable key => UniqFM elt -> key -> Maybe elt
127 lookupUFM_Directly -- when you've got the Unique already
128 :: UniqFM elt -> Unique -> Maybe elt
130 :: Uniquable key => UniqFM elt -> elt -> key -> elt
131 lookupWithDefaultUFM_Directly
132 :: UniqFM elt -> elt -> Unique -> elt
134 eltsUFM :: UniqFM elt -> [elt]
135 ufmToList :: UniqFM elt -> [(Unique, elt)]
138 %************************************************************************
140 \subsection{The @IdFinMap@ and @TyVarFinMap@ specialisations for Ids/TyVars}
142 %************************************************************************
145 #ifdef __GLASGOW_HASKELL__
146 -- I don't think HBC was too happy about this (WDP 94/10)
149 addListToUFM :: UniqFM elt -> [(Name, elt)] -> UniqFM elt
150 , UniqFM elt -> [(RnName, elt)] -> UniqFM elt
153 addListToUFM_C :: (elt -> elt -> elt) -> UniqFM elt -> [(Name, elt)] -> UniqFM elt
154 , (elt -> elt -> elt) -> UniqFM elt -> [(RnName,elt)] -> UniqFM elt
157 addToUFM :: UniqFM elt -> Unique -> elt -> UniqFM elt
160 listToUFM :: [(Unique, elt)] -> UniqFM elt
161 , [(RnName, elt)] -> UniqFM elt
164 lookupUFM :: UniqFM elt -> Name -> Maybe elt
165 , UniqFM elt -> RnName -> Maybe elt
166 , UniqFM elt -> Unique -> Maybe elt
169 lookupWithDefaultUFM :: UniqFM elt -> elt -> RnName -> elt
172 #endif {- __GLASGOW_HASKELL__ -}
175 %************************************************************************
177 \subsection{Andy Gill's underlying @UniqFM@ machinery}
179 %************************************************************************
181 ``Uniq Finite maps'' are the heart and soul of the compiler's
182 lookup-tables/environments. Important stuff! It works well with
183 Dense and Sparse ranges.
184 Both @Uq@ Finite maps and @Hash@ Finite Maps
185 are built ontop of Int Finite Maps.
187 This code is explained in the paper:
189 A Gill, S Peyton Jones, B O'Sullivan, W Partain and Aqua Friends
190 "A Cheap balancing act that grows on a tree"
191 Glasgow FP Workshop, Sep 1994, pp??-??
194 %************************************************************************
196 \subsubsection{The @UniqFM@ type, and signatures for the functions}
198 %************************************************************************
200 @UniqFM a@ is a mapping from Unique to a.
202 First, the DataType itself; which is either a Node, a Leaf, or an Empty.
207 | LeafUFM FAST_INT ele
208 | NodeUFM FAST_INT -- the switching
209 FAST_INT -- the delta
213 class Uniquable a where
214 uniqueOf :: a -> Unique
216 -- for debugging only :-)
218 instance Text (UniqFM a) where
219 showsPrec _ (NodeUFM a b t1 t2) =
220 showString "NodeUFM " . shows (IBOX(a))
221 . showString " " . shows (IBOX(b))
222 . showString " (" . shows t1
223 . showString ") (" . shows t2
225 showsPrec _ (LeafUFM x a) = showString "LeafUFM " . shows (IBOX(x))
226 showsPrec _ (EmptyUFM) = id
230 %************************************************************************
232 \subsubsection{The @UniqFM@ functions}
234 %************************************************************************
236 First the ways of building a UniqFM.
240 unitUFM key elt = mkLeafUFM (u2i (uniqueOf key)) elt
241 unitDirectlyUFM key elt = mkLeafUFM (u2i key) elt
243 listToUFM key_elt_pairs
244 = addListToUFM_C use_snd EmptyUFM key_elt_pairs
246 listToUFM_Directly uniq_elt_pairs
247 = addListToUFM_directly_C use_snd EmptyUFM uniq_elt_pairs
250 Now ways of adding things to UniqFMs.
252 There is an alternative version of @addListToUFM_C@, that uses @plusUFM@,
253 but the semantics of this operation demands a linear insertion;
254 perhaps the version without the combinator function
255 could be optimised using it.
258 addToUFM fm key elt = addToUFM_C use_snd fm key elt
260 addToUFM_Directly fm u elt = insert_ele use_snd fm (u2i u) elt
262 addToUFM_C combiner fm key elt
263 = insert_ele combiner fm (u2i (uniqueOf key)) elt
265 addListToUFM fm key_elt_pairs = addListToUFM_C use_snd fm key_elt_pairs
266 addListToUFM_Directly fm uniq_elt_pairs = addListToUFM_directly_C use_snd fm uniq_elt_pairs
268 addListToUFM_C combiner fm key_elt_pairs
269 = foldl (\ fm (k, e) -> insert_ele combiner fm (u2i (uniqueOf k)) e)
272 addListToUFM_directly_C combiner fm uniq_elt_pairs
273 = foldl (\ fm (k, e) -> insert_ele combiner fm (u2i k) e)
277 Now ways of removing things from UniqFM.
280 delListFromUFM fm lst = foldl delFromUFM fm lst
282 delFromUFM fm key = delete fm (u2i (uniqueOf key))
283 delFromUFM_Directly fm u = delete fm (u2i u)
285 delete EmptyUFM _ = EmptyUFM
286 delete fm key = del_ele fm
288 del_ele :: UniqFM a -> UniqFM a
290 del_ele lf@(LeafUFM j _)
291 | j _EQ_ key = EmptyUFM
292 | otherwise = lf -- no delete!
294 del_ele nd@(NodeUFM j p t1 t2)
296 = mkSLNodeUFM (NodeUFMData j p) (del_ele t1) t2
298 = mkLSNodeUFM (NodeUFMData j p) t1 (del_ele t2)
300 del_ele _ = panic "Found EmptyUFM FM when rec-deleting"
303 Now ways of adding two UniqFM's together.
306 plusUFM tr1 tr2 = plusUFM_C use_snd tr1 tr2
308 plusUFM_C f EmptyUFM tr = tr
309 plusUFM_C f tr EmptyUFM = tr
310 plusUFM_C f fm1 fm2 = mix_trees fm1 fm2
312 mix_trees (LeafUFM i a) t2 = insert_ele (flip f) t2 i a
313 mix_trees t1 (LeafUFM i a) = insert_ele f t1 i a
315 mix_trees left_t@(NodeUFM j p t1 t2) right_t@(NodeUFM j' p' t1' t2')
317 (ask_about_common_ancestor
321 -- Given a disjoint j,j' (p >^ p' && p' >^ p):
325 -- t1 t2 t1' t2' j j'
330 mix_branches (NewRoot nd False)
331 = mkLLNodeUFM nd left_t right_t
332 mix_branches (NewRoot nd True)
333 = mkLLNodeUFM nd right_t left_t
339 -- t1 t2 t1' t2' t1 + t1' t2 + t2'
341 mix_branches (SameRoot)
342 = mkSSNodeUFM (NodeUFMData j p)
345 -- Now the 4 different other ways; all like this:
347 -- Given j >^ j' (and, say, j > j')
351 -- t1 t2 t1' t2' t1 t2 + j'
354 mix_branches (LeftRoot Leftt) -- | trace "LL" True
357 (mix_trees t1 right_t)
360 mix_branches (LeftRoot Rightt) -- | trace "LR" True
364 (mix_trees t2 right_t)
366 mix_branches (RightRoot Leftt) -- | trace "RL" True
369 (mix_trees left_t t1')
372 mix_branches (RightRoot Rightt) -- | trace "RR" True
376 (mix_trees left_t t2')
378 mix_trees _ _ = panic "EmptyUFM found when inserting into plusInt"
381 And ways of subtracting them. First the base cases,
382 then the full D&C approach.
385 minusUFM EmptyUFM _ = EmptyUFM
386 minusUFM t1 EmptyUFM = t1
387 minusUFM fm1 fm2 = minus_trees fm1 fm2
390 -- Notice the asymetry of subtraction
392 minus_trees lf@(LeafUFM i a) t2 =
397 minus_trees t1 (LeafUFM i _) = delete t1 i
399 minus_trees left_t@(NodeUFM j p t1 t2) right_t@(NodeUFM j' p' t1' t2')
401 (ask_about_common_ancestor
405 -- Given a disjoint j,j' (p >^ p' && p' >^ p):
409 -- t1 t2 t1' t2' t1 t2
414 minus_branches (NewRoot nd _) = left_t
420 -- t1 t2 t1' t2' t1 + t1' t2 + t2'
422 minus_branches (SameRoot)
423 = mkSSNodeUFM (NodeUFMData j p)
426 -- Now the 4 different other ways; all like this:
427 -- again, with asymatry
430 -- The left is above the right
432 minus_branches (LeftRoot Leftt)
435 (minus_trees t1 right_t)
437 minus_branches (LeftRoot Rightt)
441 (minus_trees t2 right_t)
444 -- The right is above the left
446 minus_branches (RightRoot Leftt)
447 = minus_trees left_t t1'
448 minus_branches (RightRoot Rightt)
449 = minus_trees left_t t2'
451 minus_trees _ _ = panic "EmptyUFM found when insering into plusInt"
454 And taking the intersection of two UniqFM's.
457 intersectUFM t1 t2 = intersectUFM_C use_snd t1 t2
459 intersectUFM_C f EmptyUFM _ = EmptyUFM
460 intersectUFM_C f _ EmptyUFM = EmptyUFM
461 intersectUFM_C f fm1 fm2 = intersect_trees fm1 fm2
463 intersect_trees (LeafUFM i a) t2 =
466 Just b -> mkLeafUFM i (f a b)
468 intersect_trees t1 (LeafUFM i a) =
471 Just b -> mkLeafUFM i (f b a)
473 intersect_trees left_t@(NodeUFM j p t1 t2) right_t@(NodeUFM j' p' t1' t2')
475 (ask_about_common_ancestor
479 -- Given a disjoint j,j' (p >^ p' && p' >^ p):
482 -- / \ + / \ ==> EmptyUFM
487 intersect_branches (NewRoot nd _) = EmptyUFM
493 -- t1 t2 t1' t2' t1 x t1' t2 x t2'
495 intersect_branches (SameRoot)
496 = mkSSNodeUFM (NodeUFMData j p)
497 (intersect_trees t1 t1')
498 (intersect_trees t2 t2')
499 -- Now the 4 different other ways; all like this:
501 -- Given j >^ j' (and, say, j > j')
505 -- t1 t2 t1' t2' t1' t2'
507 -- This does cut down the search space quite a bit.
509 intersect_branches (LeftRoot Leftt)
510 = intersect_trees t1 right_t
511 intersect_branches (LeftRoot Rightt)
512 = intersect_trees t2 right_t
513 intersect_branches (RightRoot Leftt)
514 = intersect_trees left_t t1'
515 intersect_branches (RightRoot Rightt)
516 = intersect_trees left_t t2'
518 intersect_trees x y = panic ("EmptyUFM found when intersecting trees")
521 Now the usual set of `collection' operators, like map, fold, etc.
524 foldUFM fn a EmptyUFM = a
525 foldUFM fn a fm = fold_tree fn a fm
527 mapUFM fn EmptyUFM = EmptyUFM
528 mapUFM fn fm = map_tree fn fm
530 filterUFM fn EmptyUFM = EmptyUFM
531 filterUFM fn fm = filter_tree fn fm
534 Note, this takes a long time, O(n), but
535 because we dont want to do this very often, we put up with this.
536 O'rable, but how often do we look at the size of
541 sizeUFM (NodeUFM _ _ t1 t2) = sizeUFM t1 + sizeUFM t2
542 sizeUFM (LeafUFM _ _) = 1
544 isNullUFM EmptyUFM = True
548 looking up in a hurry is the {\em whole point} of this binary tree lark.
549 Lookup up a binary tree is easy (and fast).
552 lookupUFM fm key = lookUp fm (u2i (uniqueOf key))
553 lookupUFM_Directly fm key = lookUp fm (u2i key)
555 lookupWithDefaultUFM fm deflt key
556 = case lookUp fm (u2i (uniqueOf key)) of
560 lookupWithDefaultUFM_Directly fm deflt key
561 = case lookUp fm (u2i key) of
565 lookUp EmptyUFM _ = Nothing
566 lookUp fm i = lookup_tree fm
568 lookup_tree :: UniqFM a -> Maybe a
570 lookup_tree (LeafUFM j b)
572 | otherwise = Nothing
573 lookup_tree (NodeUFM j p t1 t2)
574 | j _GT_ i = lookup_tree t1
575 | otherwise = lookup_tree t2
577 lookup_tree EmptyUFM = panic "lookup Failed"
580 folds are *wonderful* things.
583 eltsUFM EmptyUFM = []
584 eltsUFM fm = fold_tree (:) [] fm
586 ufmToList EmptyUFM = []
588 = fold_tree (\ iu elt rest -> (mkUniqueGrimily iu, elt) : rest) [] fm
590 fold_tree f a (NodeUFM _ _ t1 t2) = fold_tree f (fold_tree f a t2) t1
591 fold_tree f a (LeafUFM iu obj) = f iu obj a
593 fold_tree f a EmptyUFM = panic "Should Never fold over an EmptyUFM"
596 %************************************************************************
598 \subsubsection{The @UniqFM@ type, and its functions}
600 %************************************************************************
602 You should always use these to build the tree.
603 There are 4 versions of mkNodeUFM, depending on
604 the strictness of the two sub-tree arguments.
605 The strictness is used *both* to prune out
606 empty trees, *and* to improve performance,
607 stoping needless thunks lying around.
608 The rule of thumb (from experence with these trees)
609 is make thunks strict, but data structures lazy.
610 If in doubt, use mkSSNodeUFM, which has the `strongest'
611 functionality, but may do a few needless evaluations.
614 mkLeafUFM :: FAST_INT -> a -> UniqFM a
615 mkLeafUFM i a = LeafUFM i a
617 -- The *ONLY* ways of building a NodeUFM.
619 mkSSNodeUFM (NodeUFMData j p) EmptyUFM t2 = t2
620 mkSSNodeUFM (NodeUFMData j p) t1 EmptyUFM = t1
621 mkSSNodeUFM (NodeUFMData j p) t1 t2
622 = ASSERT(correctNodeUFM (IBOX(j)) (IBOX(p)) t1 t2)
625 mkSLNodeUFM (NodeUFMData j p) EmptyUFM t2 = t2
626 mkSLNodeUFM (NodeUFMData j p) t1 t2
627 = ASSERT(correctNodeUFM (IBOX(j)) (IBOX(p)) t1 t2)
630 mkLSNodeUFM (NodeUFMData j p) t1 EmptyUFM = t1
631 mkLSNodeUFM (NodeUFMData j p) t1 t2
632 = ASSERT(correctNodeUFM (IBOX(j)) (IBOX(p)) t1 t2)
635 mkLLNodeUFM (NodeUFMData j p) t1 t2
636 = ASSERT(correctNodeUFM (IBOX(j)) (IBOX(p)) t1 t2)
646 correctNodeUFM j p t1 t2
647 = correct (j-p) (j-1) p t1 && correct j ((j-1)+p) p t2
649 correct low high _ (LeafUFM i _)
650 = low <= IBOX(i) && IBOX(i) <= high
651 correct low high above_p (NodeUFM j p _ _)
652 = low <= IBOX(j) && IBOX(j) <= high && above_p > IBOX(p)
653 correct _ _ _ EmptyUFM = panic "EmptyUFM stored inside a tree"
656 Note: doing SAT on this by hand seems to make it worse. Todo: Investigate,
657 and if necessary do $\lambda$ lifting on our functions that are bound.
667 insert_ele f EmptyUFM i new = mkLeafUFM i new
669 insert_ele f (LeafUFM j old) i new
671 mkLLNodeUFM (getCommonNodeUFMData
676 | j _EQ_ i = mkLeafUFM j (f old new)
678 mkLLNodeUFM (getCommonNodeUFMData
684 insert_ele f n@(NodeUFM j p t1 t2) i a
686 = if (i _GE_ (j _SUB_ p))
687 then mkSLNodeUFM (NodeUFMData j p) (insert_ele f t1 i a) t2
688 else mkLLNodeUFM (getCommonNodeUFMData
694 = if (i _LE_ ((j _SUB_ ILIT(1)) _ADD_ p))
695 then mkLSNodeUFM (NodeUFMData j p) t1 (insert_ele f t2 i a)
696 else mkLLNodeUFM (getCommonNodeUFMData
703 This has got a left to right ordering.
706 fold_tree f a (NodeUFM _ _ t1 t2) = fold_tree f (fold_tree f a t2) t1
707 fold_tree f a (LeafUFM _ obj) = f obj a
709 fold_tree f a EmptyUFM = panic "Should Never fold over an EmptyUFM"
713 map_tree f (NodeUFM j p t1 t2)
714 = mkSSNodeUFM (NodeUFMData j p) (map_tree f t1) (map_tree f t2)
715 map_tree f (LeafUFM i obj)
716 = mkLeafUFM i (f obj)
718 map_tree f _ = panic "map_tree failed"
722 filter_tree f nd@(NodeUFM j p t1 t2)
723 = mkSSNodeUFM (NodeUFMData j p) (filter_tree f t1) (filter_tree f t2)
725 filter_tree f lf@(LeafUFM i obj)
727 | otherwise = EmptyUFM
730 %************************************************************************
732 \subsubsection{The @UniqFM@ type, and signatures for the functions}
734 %************************************************************************
738 This is the information that is held inside a NodeUFM, packaged up for
743 = NodeUFMData FAST_INT
747 This is the information used when computing new NodeUFMs.
750 data Side = Leftt | Rightt -- NB: avoid 1.3 names "Left" and "Right"
752 = LeftRoot Side -- which side is the right down ?
753 | RightRoot Side -- which side is the left down ?
754 | SameRoot -- they are the same !
755 | NewRoot NodeUFMData -- here's the new, common, root
756 Bool -- do you need to swap left and right ?
759 This specifies the relationship between NodeUFMData and CalcNodeUFMData.
762 indexToRoot :: FAST_INT -> NodeUFMData
766 l = (ILIT(1) :: FAST_INT)
768 NodeUFMData (((i `shiftR_` l) `shiftL_` l) _ADD_ ILIT(1)) l
770 getCommonNodeUFMData :: NodeUFMData -> NodeUFMData -> NodeUFMData
772 getCommonNodeUFMData (NodeUFMData i p) (NodeUFMData i2 p2)
773 | p _EQ_ p2 = getCommonNodeUFMData_ p j j2
774 | p _LT_ p2 = getCommonNodeUFMData_ p2 (j _QUOT_ (p2 _QUOT_ p)) j2
775 | otherwise = getCommonNodeUFMData_ p j (j2 _QUOT_ (p _QUOT_ p2))
777 l = (ILIT(1) :: FAST_INT)
778 j = i _QUOT_ (p `shiftL_` l)
779 j2 = i2 _QUOT_ (p2 `shiftL_` l)
781 getCommonNodeUFMData_ :: FAST_INT -> FAST_INT -> FAST_INT -> NodeUFMData
783 getCommonNodeUFMData_ p j j_
785 = NodeUFMData (((j `shiftL_` l) _ADD_ l) _MUL_ p) p
787 = getCommonNodeUFMData_ (p `shiftL_` l) (j `shiftR_` l) (j_ `shiftR_` l)
789 ask_about_common_ancestor :: NodeUFMData -> NodeUFMData -> CommonRoot
791 ask_about_common_ancestor x@(NodeUFMData j p) y@(NodeUFMData j2 p2)
792 | j _EQ_ j2 = SameRoot
794 = case getCommonNodeUFMData x y of
795 nd@(NodeUFMData j3 p3)
796 | j3 _EQ_ j -> LeftRoot (decideSide (j _GT_ j2))
797 | j3 _EQ_ j2 -> RightRoot (decideSide (j _LT_ j2))
798 | otherwise -> NewRoot nd (j _GT_ j2)
800 decideSide :: Bool -> Side
801 decideSide True = Leftt
802 decideSide False = Rightt
805 This might be better in Util.lhs ?
808 Now the bit twiddling functions.
810 shiftL_ :: FAST_INT -> FAST_INT -> FAST_INT
811 shiftR_ :: FAST_INT -> FAST_INT -> FAST_INT
813 #if __GLASGOW_HASKELL__
814 {-# INLINE shiftL_ #-}
815 {-# INLINE shiftR_ #-}
816 shiftL_ n p = word2Int#((int2Word# n) `shiftL#` p)
817 shiftR_ n p = word2Int#((int2Word# n) `shiftr` p)
819 shiftr x y = shiftRA# x y
822 shiftL_ n p = n * (2 ^ p)
823 shiftR_ n p = n `quot` (2 ^ p)
828 Andy's extras: ToDo: to Util.
831 use_fst :: a -> b -> a
834 use_snd :: a -> b -> b