X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=compiler%2FbasicTypes%2FUniqSupply.lhs;h=29d5b17c87f55c024d3b9b523f671b688c6f74af;hb=a594f2fe4a1f7fa6805fb3aa79a1b7617b343a33;hp=c228eeb5708740740059a5850a1d3383c8d5f2d2;hpb=7fc749a43b4b6b85d234fa95d4928648259584f4;p=ghc-hetmet.git diff --git a/compiler/basicTypes/UniqSupply.lhs b/compiler/basicTypes/UniqSupply.lhs index c228eeb..29d5b17 100644 --- a/compiler/basicTypes/UniqSupply.lhs +++ b/compiler/basicTypes/UniqSupply.lhs @@ -23,6 +23,8 @@ module UniqSupply ( mapUs, mapAndUnzipUs, mapAndUnzip3Us, thenMaybeUs, mapAccumLUs, lazyThenUs, lazyMapUs, + module MonadUtils, mapAndUnzipM, + MonadUnique(..), mkSplitUniqSupply, splitUniqSupply, listSplitUniqSupply @@ -31,20 +33,16 @@ module UniqSupply ( #include "HsVersions.h" import Unique - -import GHC.Exts -import System.IO.Unsafe ( unsafeInterleaveIO ) +import FastTypes #if __GLASGOW_HASKELL__ >= 607 import GHC.IOBase (unsafeDupableInterleaveIO) #else +import System.IO.Unsafe ( unsafeInterleaveIO ) unsafeDupableInterleaveIO :: IO a -> IO a unsafeDupableInterleaveIO = unsafeInterleaveIO #endif -w2i x = word2Int# x -i2w x = int2Word# x -i2w_s x = (x :: Int#) \end{code} @@ -61,7 +59,7 @@ which will be distinct from the first and from all others. \begin{code} data UniqSupply - = MkSplitUniqSupply Int# -- make the Unique with this + = MkSplitUniqSupply FastInt -- make the Unique with this UniqSupply UniqSupply -- when split => these two supplies \end{code} @@ -76,21 +74,21 @@ uniqsFromSupply :: UniqSupply -> [Unique] -- Infinite \end{code} \begin{code} -mkSplitUniqSupply (C# c#) - = let - mask# = (i2w (ord# c#)) `uncheckedShiftL#` (i2w_s 24#) +mkSplitUniqSupply c + = case fastOrd (cUnbox c) `shiftLFastInt` _ILIT(24) of + mask -> let -- here comes THE MAGIC: -- This is one of the most hammered bits in the whole compiler - mk_supply# + mk_supply = unsafeDupableInterleaveIO ( - genSymZh >>= \ (I# u#) -> - mk_supply# >>= \ s1 -> - mk_supply# >>= \ s2 -> - return (MkSplitUniqSupply (w2i (mask# `or#` (i2w u#))) s1 s2) - ) - in - mk_supply# + genSymZh >>= \ u_ -> case iUnbox u_ of { u -> ( + mk_supply >>= \ s1 -> + mk_supply >>= \ s2 -> + return (MkSplitUniqSupply (mask `bitOrFastInt` u) s1 s2) + )}) + in + mk_supply foreign import ccall unsafe "genSymZh" genSymZh :: IO Int @@ -99,8 +97,8 @@ listSplitUniqSupply (MkSplitUniqSupply _ s1 s2) = s1 : listSplitUniqSupply s2 \end{code} \begin{code} -uniqFromSupply (MkSplitUniqSupply n _ _) = mkUniqueGrimily (I# n) -uniqsFromSupply (MkSplitUniqSupply n _ s2) = mkUniqueGrimily (I# n) : uniqsFromSupply s2 +uniqFromSupply (MkSplitUniqSupply n _ _) = mkUniqueGrimily (iBox n) +uniqsFromSupply (MkSplitUniqSupply n _ s2) = mkUniqueGrimily (iBox n) : uniqsFromSupply s2 \end{code} %************************************************************************ @@ -158,6 +156,23 @@ withUs f = USM (\us -> f us) -- Ha ha! getUs :: UniqSM UniqSupply getUs = USM (\us -> splitUniqSupply us) +-- | A monad for generating unique identifiers +class Monad m => MonadUnique m where + -- | Get a new UniqueSupply + getUniqueSupplyM :: m UniqSupply + -- | Get a new unique identifier + getUniqueM :: m Unique + -- | Get an infinite list of new unique identifiers + getUniquesM :: m [Unique] + + getUniqueM = liftM uniqFromSupply getUniqueSupplyM + getUniquesM = liftM uniqsFromSupply getUniqueSupplyM + +instance MonadUnique UniqSM where + getUniqueSupplyM = USM (\us -> splitUniqSupply us) + getUniqueM = getUniqueUs + getUniquesM = getUniquesUs + getUniqueUs :: UniqSM Unique getUniqueUs = USM (\us -> case splitUniqSupply us of (us1,us2) -> (uniqFromSupply us1, us2))