X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Fcompiler%2FbasicTypes%2FUniqSupply.lhs;h=4f56474a52fe486066a5dc07e94ace0642a6b439;hb=83eef621e4a4fbb6c1343304ec638cafd6c9dc09;hp=81fec960964dff9c8e73d46c833f83503dbf3abb;hpb=0596517a9b4b2b32e5d375a986351102ac4540fc;p=ghc-hetmet.git diff --git a/ghc/compiler/basicTypes/UniqSupply.lhs b/ghc/compiler/basicTypes/UniqSupply.lhs index 81fec96..4f56474 100644 --- a/ghc/compiler/basicTypes/UniqSupply.lhs +++ b/ghc/compiler/basicTypes/UniqSupply.lhs @@ -1,35 +1,37 @@ % -% (c) The GRASP/AQUA Project, Glasgow University, 1992-1996 +% (c) The GRASP/AQUA Project, Glasgow University, 1992-1998 % \section[UniqSupply]{The @UniqueSupply@ data type and a (monadic) supply thereof} \begin{code} -#include "HsVersions.h" - module UniqSupply ( UniqSupply, -- Abstractly - getUnique, getUniques, -- basic ops + uniqFromSupply, uniqsFromSupply, -- basic ops - UniqSM(..), -- type: unique supply monad - initUs, thenUs, returnUs, + UniqSM, -- type: unique supply monad + initUs, initUs_, thenUs, thenUs_, returnUs, fixUs, getUs, setUs, + getUniqueUs, getUniquesUs, mapUs, mapAndUnzipUs, mapAndUnzip3Us, + thenMaybeUs, mapAccumLUs, + lazyThenUs, lazyMapUs, mkSplitUniqSupply, - splitUniqSupply, - - -- and the access functions for the `builtin' UniqueSupply - getBuiltinUniques, mkBuiltinUnique, - mkPseudoUnique1, mkPseudoUnique2, mkPseudoUnique3 + splitUniqSupply ) where -import Ubiq{-uitous-} +#include "HsVersions.h" import Unique -import Util +import Panic ( panic ) + +import GlaExts -import PreludeGlaST +#if __GLASGOW_HASKELL__ < 301 +import IOBase ( IO(..), IOResult(..) ) +#else +#endif w2i x = word2Int# x i2w x = int2Word# x @@ -62,39 +64,31 @@ data UniqSupply \end{code} \begin{code} -mkSplitUniqSupply :: Char -> PrimIO UniqSupply +mkSplitUniqSupply :: Char -> IO UniqSupply splitUniqSupply :: UniqSupply -> (UniqSupply, UniqSupply) -getUnique :: UniqSupply -> Unique -getUniques :: Int -> UniqSupply -> [Unique] +uniqFromSupply :: UniqSupply -> Unique +uniqsFromSupply :: Int -> UniqSupply -> [Unique] \end{code} \begin{code} -mkSplitUniqSupply (MkChar c#) +mkSplitUniqSupply (C# c#) = let mask# = (i2w (ord# c#)) `shiftL#` (i2w_s 24#) -- here comes THE MAGIC: + -- This is one of the most hammered bits in the whole compiler mk_supply# - = unsafe_interleave ( - mk_unique `thenPrimIO` \ uniq -> - mk_supply# `thenPrimIO` \ s1 -> - mk_supply# `thenPrimIO` \ s2 -> - returnPrimIO (MkSplitUniqSupply uniq s1 s2) + = unsafeInterleaveIO ( + mk_unique >>= \ uniq -> + mk_supply# >>= \ s1 -> + mk_supply# >>= \ s2 -> + return (MkSplitUniqSupply uniq s1 s2) ) - where - -- inlined copy of unsafeInterleavePrimIO; - -- this is the single-most-hammered bit of code - -- in the compiler.... - unsafe_interleave m s - = let - (r, new_s) = m s - in - (r, s) - - mk_unique = _ccall_ genSymZh `thenPrimIO` \ (W# u#) -> - returnPrimIO (MkInt (w2i (mask# `or#` u#))) + + mk_unique = _ccall_ genSymZh >>= \ (W# u#) -> + return (I# (w2i (mask# `or#` u#))) in mk_supply# @@ -102,13 +96,13 @@ splitUniqSupply (MkSplitUniqSupply _ s1 s2) = (s1, s2) \end{code} \begin{code} -getUnique (MkSplitUniqSupply (MkInt n) _ _) = mkUniqueGrimily n +uniqFromSupply (MkSplitUniqSupply (I# n) _ _) = mkUniqueGrimily n -getUniques i@(MkInt i#) supply = i# `get_from` supply +uniqsFromSupply (I# i) supply = i `get_from` supply where get_from 0# _ = [] - get_from n# (MkSplitUniqSupply (MkInt u#) _ s2) - = mkUniqueGrimily u# : get_from (n# `minusInt#` 1#) s2 + get_from n (MkSplitUniqSupply (I# u) _ s2) + = mkUniqueGrimily u : get_from (n -# 1#) s2 \end{code} %************************************************************************ @@ -118,43 +112,73 @@ getUniques i@(MkInt i#) supply = i# `get_from` supply %************************************************************************ \begin{code} -type UniqSM result = UniqSupply -> result - --- the initUs function also returns the final UniqSupply +type UniqSM result = UniqSupply -> (result, UniqSupply) -initUs :: UniqSupply -> UniqSM a -> (UniqSupply, a) +-- the initUs function also returns the final UniqSupply; initUs_ drops it +initUs :: UniqSupply -> UniqSM a -> (a,UniqSupply) +initUs init_us m = case m init_us of { (r,us) -> (r,us) } -initUs init_us m - = case (splitUniqSupply init_us) of { (s1, s2) -> - (s2, m s1) } +initUs_ :: UniqSupply -> UniqSM a -> a +initUs_ init_us m = case m init_us of { (r,us) -> r } {-# INLINE thenUs #-} +{-# INLINE lazyThenUs #-} {-# INLINE returnUs #-} {-# INLINE splitUniqSupply #-} \end{code} @thenUs@ is where we split the @UniqSupply@. \begin{code} -thenUs :: UniqSM a -> (a -> UniqSM b) -> UniqSM b +fixUs :: (a -> UniqSM a) -> UniqSM a +fixUs m us + = (r,us') where (r,us') = m r us +thenUs :: UniqSM a -> (a -> UniqSM b) -> UniqSM b thenUs expr cont us - = case (splitUniqSupply us) of { (s1, s2) -> - case (expr s1) of { result -> - cont result s2 }} -\end{code} + = case (expr us) of { (result, us') -> cont result us' } + +lazyThenUs :: UniqSM a -> (a -> UniqSM b) -> UniqSM b +lazyThenUs expr cont us + = let (result, us') = expr us in cont result us' + +thenUs_ :: UniqSM a -> UniqSM b -> UniqSM b +thenUs_ expr cont us + = case (expr us) of { (_, us') -> cont us' } + -\begin{code} returnUs :: a -> UniqSM a -returnUs result us = result +returnUs result us = (result, us) -mapUs :: (a -> UniqSM b) -> [a] -> UniqSM [b] +getUs :: UniqSM UniqSupply +getUs us = (us, panic "getUs: bad supply") + +setUs :: UniqSupply -> UniqSM () +setUs us old_us = ((), us) +getUniqueUs :: UniqSM Unique +getUniqueUs us = case splitUniqSupply us of + (us1,us2) -> (uniqFromSupply us1, us2) + +getUniquesUs :: Int -> UniqSM [Unique] +getUniquesUs n us = case splitUniqSupply us of + (us1,us2) -> (uniqsFromSupply n us1, us2) +\end{code} + +\begin{code} +mapUs :: (a -> UniqSM b) -> [a] -> UniqSM [b] mapUs f [] = returnUs [] mapUs f (x:xs) = f x `thenUs` \ r -> mapUs f xs `thenUs` \ rs -> returnUs (r:rs) +lazyMapUs :: (a -> UniqSM b) -> [a] -> UniqSM [b] +lazyMapUs f [] = returnUs [] +lazyMapUs f (x:xs) + = f x `lazyThenUs` \ r -> + lazyMapUs f xs `lazyThenUs` \ rs -> + returnUs (r:rs) + mapAndUnzipUs :: (a -> UniqSM (b,c)) -> [a] -> UniqSM ([b],[c]) mapAndUnzip3Us :: (a -> UniqSM (b,c,d)) -> [a] -> UniqSM ([b],[c],[d]) @@ -169,29 +193,22 @@ mapAndUnzip3Us f (x:xs) = f x `thenUs` \ (r1, r2, r3) -> mapAndUnzip3Us f xs `thenUs` \ (rs1, rs2, rs3) -> returnUs (r1:rs1, r2:rs2, r3:rs3) -\end{code} -%************************************************************************ -%* * -\subsubsection[UniqueSupplies-compiler]{@UniqueSupplies@ specific to the compiler} -%* * -%************************************************************************ - -\begin{code} -mkPseudoUnique1, mkPseudoUnique2, mkPseudoUnique3, - mkBuiltinUnique :: Int -> Unique - -mkBuiltinUnique i = mkUnique 'B' i -mkPseudoUnique1 i = mkUnique 'C' i -- used for getItsUnique on Regs -mkPseudoUnique2 i = mkUnique 'D' i -- ditto -mkPseudoUnique3 i = mkUnique 'E' i -- ditto - -getBuiltinUniques :: Int -> [Unique] -getBuiltinUniques n = map (mkUnique 'B') [1 .. n] -\end{code} - -The following runs a uniq monad expression, using builtin uniq values: -\begin{code} ---runBuiltinUs :: UniqSM a -> a ---runBuiltinUs m = snd (initUs uniqSupply_B m) +thenMaybeUs :: UniqSM (Maybe a) -> (a -> UniqSM (Maybe b)) -> UniqSM (Maybe b) +thenMaybeUs m k + = m `thenUs` \ result -> + case result of + Nothing -> returnUs Nothing + Just x -> k x + +mapAccumLUs :: (acc -> x -> UniqSM (acc, y)) + -> acc + -> [x] + -> UniqSM (acc, [y]) + +mapAccumLUs f b [] = returnUs (b, []) +mapAccumLUs f b (x:xs) + = f b x `thenUs` \ (b__2, x__2) -> + mapAccumLUs f b__2 xs `thenUs` \ (b__3, xs__2) -> + returnUs (b__3, x__2:xs__2) \end{code}