Commit 5ff8ce7f authored by milan's avatar milan
Browse files

Replace FiniteMap and UniqFM with counterparts from containers.

The original interfaces are kept. There is small performance improvement:
- when compiling for five nofib, we get following speedups:
    Average                -----           -2.5%
    Average                -----           -0.6%
    Average                -----           -0.5%
    Average                -----           -5.5%
    Average                -----          -10.3%
- when compiling HPC ten times, we get:
    switches                          oldmaps   newmaps
    -O -fasm                          117.402s  116.081s (98.87%)
    -O -fasm -fregs-graph             119.993s  118.735s (98.95%)
    -O -fasm -fregs-iterative         120.191s  118.607s (98.68%)
parent 71c7067b
...@@ -27,10 +27,6 @@ import FastTypes ...@@ -27,10 +27,6 @@ import FastTypes
-- NOTE: This only works for arcitectures with just RcInteger and RcDouble -- NOTE: This only works for arcitectures with just RcInteger and RcDouble
-- (which are disjoint) ie. x86, x86_64 and ppc -- (which are disjoint) ie. x86, x86_64 and ppc
-- --
-- BL 2007/09
-- Doing a nice fold over the UniqSet makes trivColorable use
-- 32% of total compile time and 42% of total alloc when compiling SHA1.lhs from darcs.
--
-- The number of allocatable regs is hard coded here so we can do a fast -- The number of allocatable regs is hard coded here so we can do a fast
-- comparision in trivColorable. -- comparision in trivColorable.
-- --
...@@ -92,17 +88,42 @@ accSqueeze ...@@ -92,17 +88,42 @@ accSqueeze
-> UniqFM reg -> UniqFM reg
-> FastInt -> FastInt
accSqueeze count maxCount squeeze ufm accSqueeze count maxCount squeeze ufm = acc count (eltsUFM ufm)
= case ufm of where acc count [] = count
NodeUFM _ _ left right acc count _ | count >=# maxCount = count
-> case accSqueeze count maxCount squeeze right of acc count (r:rs) = acc (count +# squeeze r) rs
count' -> case count' >=# maxCount of
False -> accSqueeze count' maxCount squeeze left {- Note [accSqueeze]
True -> count' ~~~~~~~~~~~~~~~~~~~~
BL 2007/09
LeafUFM _ reg -> count +# squeeze reg Doing a nice fold over the UniqSet makes trivColorable use
EmptyUFM -> count 32% of total compile time and 42% of total alloc when compiling SHA1.lhs from darcs.
Therefore the UniqFM is made non-abstract and we use custom fold.
MS 2010/04
When converting UniqFM to use Data.IntMap, the fold cannot use UniqFM internal
representation any more. But it is imperative that the assSqueeze stops
the folding if the count gets greater or equal to maxCount. We thus convert
UniqFM to a (lazy) list, do the fold and stops if necessary, which was
the most efficient variant tried. Benchmark compiling 10-times SHA1.lhs follows.
(original = previous implementation, folding = fold of the whole UFM,
lazyFold = the current implementation,
hackFold = using internal representation of Data.IntMap)
original folding hackFold lazyFold
-O -fasm (used everywhere) 31.509s 30.387s 30.791s 30.603s
100.00% 96.44% 97.72% 97.12%
-fregs-graph 67.938s 74.875s 62.673s 64.679s
100.00% 110.21% 92.25% 95.20%
-fregs-iterative 89.761s 143.913s 81.075s 86.912s
100.00% 160.33% 90.32% 96.83%
-fnew-codegen 38.225s 37.142s 37.551s 37.119s
100.00% 97.17% 98.24% 97.11%
-fnew-codegen -fregs-graph 91.786s 91.51s 87.368s 86.88s
100.00% 99.70% 95.19% 94.65%
-fnew-codegen -fregs-iterative 206.72s 343.632s 194.694s 208.677s
100.00% 166.23% 94.18% 100.95%
-}
trivColorable trivColorable
:: (RegClass -> VirtualReg -> FastInt) :: (RegClass -> VirtualReg -> FastInt)
......
This diff is collapsed.
This diff is collapsed.
...@@ -11,140 +11,105 @@ Basically, the things need to be in class @Uniquable@. ...@@ -11,140 +11,105 @@ Basically, the things need to be in class @Uniquable@.
\begin{code} \begin{code}
module UniqSet ( module UniqSet (
-- * Unique set type -- * Unique set type
UniqSet, -- abstract type: NOT UniqSet, -- type synonym for UniqFM a
-- ** Manipulating these sets -- ** Manipulating these sets
mkUniqSet, uniqSetToList, emptyUniqSet, unitUniqSet, emptyUniqSet,
addOneToUniqSet, addListToUniqSet, addOneToUniqSet_C, unitUniqSet,
delOneFromUniqSet, delListFromUniqSet, delOneFromUniqSet_Directly, mkUniqSet,
unionUniqSets, unionManyUniqSets, minusUniqSet, addOneToUniqSet, addOneToUniqSet_C, addListToUniqSet,
elementOfUniqSet, mapUniqSet, intersectUniqSets, delOneFromUniqSet, delOneFromUniqSet_Directly, delListFromUniqSet,
isEmptyUniqSet, filterUniqSet, sizeUniqSet, foldUniqSet, unionUniqSets, unionManyUniqSets,
elemUniqSet_Directly, lookupUniqSet, hashUniqSet minusUniqSet,
intersectUniqSets,
foldUniqSet,
mapUniqSet,
elementOfUniqSet,
elemUniqSet_Directly,
filterUniqSet,
sizeUniqSet,
isEmptyUniqSet,
lookupUniqSet,
uniqSetToList,
) where ) where
import Maybes
import UniqFM import UniqFM
import Unique import Unique
#if ! OMIT_NATIVE_CODEGEN
#define IF_NCG(a) a
#else
#define IF_NCG(a) {--}
#endif
\end{code} \end{code}
%************************************************************************ %************************************************************************
%* * %* *
\subsection{The @UniqSet@ type} \subsection{The signature of the module}
%* * %* *
%************************************************************************ %************************************************************************
We use @UniqFM@, with a (@getUnique@-able) @Unique@ as ``key''
and the thing itself as the ``value'' (for later retrieval).
\begin{code} \begin{code}
--data UniqSet a = MkUniqSet (FiniteMap Unique a) : NOT
type UniqSet a = UniqFM a
#define MkUniqSet {--}
emptyUniqSet :: UniqSet a emptyUniqSet :: UniqSet a
emptyUniqSet = MkUniqSet emptyUFM
unitUniqSet :: Uniquable a => a -> UniqSet a unitUniqSet :: Uniquable a => a -> UniqSet a
unitUniqSet x = MkUniqSet (unitUFM x x)
uniqSetToList :: UniqSet a -> [a]
uniqSetToList (MkUniqSet set) = eltsUFM set
foldUniqSet :: (a -> b -> b) -> b -> UniqSet a -> b
foldUniqSet k z (MkUniqSet set) = foldUFM k z set
mkUniqSet :: Uniquable a => [a] -> UniqSet a mkUniqSet :: Uniquable a => [a] -> UniqSet a
mkUniqSet xs = MkUniqSet (listToUFM [ (x, x) | x <- xs])
addOneToUniqSet :: Uniquable a => UniqSet a -> a -> UniqSet a addOneToUniqSet :: Uniquable a => UniqSet a -> a -> UniqSet a
addOneToUniqSet (MkUniqSet set) x = MkUniqSet (addToUFM set x x) addOneToUniqSet_C :: Uniquable a => (a -> a -> a) -> UniqSet a -> a -> UniqSet a
addListToUniqSet :: Uniquable a => UniqSet a -> [a] -> UniqSet a
addOneToUniqSet_C :: Uniquable a
=> (a -> a -> a) -> UniqSet a -> a -> UniqSet a
addOneToUniqSet_C f (MkUniqSet set) x = MkUniqSet (addToUFM_C f set x x)
delOneFromUniqSet :: Uniquable a => UniqSet a -> a -> UniqSet a delOneFromUniqSet :: Uniquable a => UniqSet a -> a -> UniqSet a
delOneFromUniqSet (MkUniqSet set) x = MkUniqSet (delFromUFM set x)
delOneFromUniqSet_Directly :: Uniquable a => UniqSet a -> Unique -> UniqSet a delOneFromUniqSet_Directly :: Uniquable a => UniqSet a -> Unique -> UniqSet a
delOneFromUniqSet_Directly (MkUniqSet set) u
= MkUniqSet (delFromUFM_Directly set u)
delListFromUniqSet :: Uniquable a => UniqSet a -> [a] -> UniqSet a delListFromUniqSet :: Uniquable a => UniqSet a -> [a] -> UniqSet a
delListFromUniqSet (MkUniqSet set) xs = MkUniqSet (delListFromUFM set xs)
addListToUniqSet :: Uniquable a => UniqSet a -> [a] -> UniqSet a
addListToUniqSet (MkUniqSet set) xs = MkUniqSet (addListToUFM set [(x,x) | x<-xs])
unionUniqSets :: UniqSet a -> UniqSet a -> UniqSet a unionUniqSets :: UniqSet a -> UniqSet a -> UniqSet a
unionUniqSets (MkUniqSet set1) (MkUniqSet set2) = MkUniqSet (plusUFM set1 set2)
unionManyUniqSets :: [UniqSet a] -> UniqSet a unionManyUniqSets :: [UniqSet a] -> UniqSet a
-- = foldr unionUniqSets emptyUniqSet ss
unionManyUniqSets [] = emptyUniqSet
unionManyUniqSets [s] = s
unionManyUniqSets (s:ss) = s `unionUniqSets` unionManyUniqSets ss
minusUniqSet :: UniqSet a -> UniqSet a -> UniqSet a minusUniqSet :: UniqSet a -> UniqSet a -> UniqSet a
minusUniqSet (MkUniqSet set1) (MkUniqSet set2) = MkUniqSet (minusUFM set1 set2)
filterUniqSet :: (a -> Bool) -> UniqSet a -> UniqSet a
filterUniqSet pred (MkUniqSet set) = MkUniqSet (filterUFM pred set)
intersectUniqSets :: UniqSet a -> UniqSet a -> UniqSet a intersectUniqSets :: UniqSet a -> UniqSet a -> UniqSet a
intersectUniqSets (MkUniqSet set1) (MkUniqSet set2) = MkUniqSet (intersectUFM set1 set2)
foldUniqSet :: (a -> b -> b) -> b -> UniqSet a -> b
mapUniqSet :: (a -> b) -> UniqSet a -> UniqSet b
elementOfUniqSet :: Uniquable a => a -> UniqSet a -> Bool elementOfUniqSet :: Uniquable a => a -> UniqSet a -> Bool
elementOfUniqSet x (MkUniqSet set) = maybeToBool (lookupUFM set x) elemUniqSet_Directly :: Unique -> UniqSet a -> Bool
filterUniqSet :: (a -> Bool) -> UniqSet a -> UniqSet a
sizeUniqSet :: UniqSet a -> Int
isEmptyUniqSet :: UniqSet a -> Bool
lookupUniqSet :: Uniquable a => UniqSet a -> a -> Maybe a lookupUniqSet :: Uniquable a => UniqSet a -> a -> Maybe a
lookupUniqSet (MkUniqSet set) x = lookupUFM set x uniqSetToList :: UniqSet a -> [a]
\end{code}
%************************************************************************
%* *
\subsection{Implementation using ``UniqFM''}
%* *
%************************************************************************
elemUniqSet_Directly :: Unique -> UniqSet a -> Bool \begin{code}
elemUniqSet_Directly x (MkUniqSet set) = maybeToBool (lookupUFM_Directly set x)
sizeUniqSet :: UniqSet a -> Int type UniqSet a = UniqFM a
sizeUniqSet (MkUniqSet set) = sizeUFM set
hashUniqSet :: UniqSet a -> Int emptyUniqSet = emptyUFM
hashUniqSet (MkUniqSet set) = hashUFM set unitUniqSet x = unitUFM x x
mkUniqSet = foldl addOneToUniqSet emptyUniqSet
isEmptyUniqSet :: UniqSet a -> Bool addOneToUniqSet set x = addToUFM set x x
isEmptyUniqSet (MkUniqSet set) = isNullUFM set {-SLOW: sizeUFM set == 0-} addOneToUniqSet_C f set x = addToUFM_C f set x x
addListToUniqSet = foldl addOneToUniqSet
-- | Invariant: the mapping function doesn't change the unique delOneFromUniqSet = delFromUFM
mapUniqSet :: (a -> b) -> UniqSet a -> UniqSet b delOneFromUniqSet_Directly = delFromUFM_Directly
mapUniqSet f (MkUniqSet set) = MkUniqSet (mapUFM f set) delListFromUniqSet = delListFromUFM
\end{code}
unionUniqSets = plusUFM
unionManyUniqSets [] = emptyUniqSet
unionManyUniqSets sets = foldr1 unionUniqSets sets
minusUniqSet = minusUFM
intersectUniqSets = intersectUFM
foldUniqSet = foldUFM
mapUniqSet = mapUFM
elementOfUniqSet = elemUFM
elemUniqSet_Directly = elemUFM_Directly
filterUniqSet = filterUFM
sizeUniqSet = sizeUFM
isEmptyUniqSet = isNullUFM
lookupUniqSet = lookupUFM
uniqSetToList = eltsUFM
\begin{code}
#ifdef __GLASGOW_HASKELL__
{-# SPECIALIZE
addOneToUniqSet :: UniqSet Unique -> Unique -> UniqSet Unique
#-}
-- These next three specialisations disabled as importing Name creates a
-- loop, and getting the Uniquable Name instance in particular is tricky.
{- SPECIALIZE
elementOfUniqSet :: Name -> UniqSet Name -> Bool
, Unique -> UniqSet Unique -> Bool
-}
{- SPECIALIZE
mkUniqSet :: [Name] -> UniqSet Name
-}
{- SPECIALIZE
unitUniqSet :: Name -> UniqSet Name
, Unique -> UniqSet Unique
-}
#endif
\end{code} \end{code}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment