\begin{code}
module Unique (
- Unique, Uniquable(..), hasKey,
+ -- * Main data types
+ Unique, Uniquable(..),
+
+ -- ** Constructors, desctructors and operations on 'Unique's
+ hasKey,
pprUnique,
- mkUnique, -- Used in UniqSupply
mkUniqueGrimily, -- Used in UniqSupply only!
getKey, getKeyFastInt, -- Used in Var, UniqFM, Name only!
isTupleKey,
+ -- ** Making built-in uniques
+
-- now all the built-in Uniques (and functions to make them)
-- [the Oh-So-Wonderful Haskell module system wins again...]
mkAlphaTyVarUnique,
mkPreludeTyConUnique, mkPreludeClassUnique,
mkPArrDataConUnique,
+ mkVarOccUnique, mkDataOccUnique, mkTvOccUnique, mkTcOccUnique,
+ mkRegSingleUnique, mkRegPairUnique, mkRegClassUnique, mkRegSubUnique,
+
mkBuiltinUnique,
mkPseudoUniqueC,
mkPseudoUniqueD,
import FastTypes
import FastString
import Outputable
+-- import StaticFlags
#if defined(__GLASGOW_HASKELL__)
--just for implementing a fast [0,61) -> Char function
\begin{code}
--why not newtype Int?
+
+-- | The type of unique identifiers that are used in many places in GHC
+-- for fast ordering and equality tests. You should generate these with
+-- the functions from the 'UniqSupply' module
data Unique = MkUnique FastInt
\end{code}
The stuff about unique *supplies* is handled further down this module.
\begin{code}
-mkUnique :: Char -> Int -> Unique -- Builds a unique from pieces
unpkUnique :: Unique -> (Char, Int) -- The reverse
mkUniqueGrimily :: Int -> Unique -- A trap-door for UniqSupply
-- and as long as the Char fits in 8 bits, which we assume anyway!
+mkUnique :: Char -> Int -> Unique -- Builds a unique from pieces
+-- NOT EXPORTED, so that we can see all the Chars that
+-- are used in this one module
mkUnique c i
= MkUnique (tag `bitOrFastInt` bits)
where
- tag = fastOrd (cUnbox c) `shiftLFastInt` _ILIT(24)
- bits = iUnbox i `bitAndFastInt` _ILIT(16777215){-``0x00ffffff''-}
+ !tag = fastOrd (cUnbox c) `shiftLFastInt` _ILIT(24)
+ !bits = iUnbox i `bitAndFastInt` _ILIT(16777215){-``0x00ffffff''-}
unpkUnique (MkUnique u)
= let
%************************************************************************
\begin{code}
+-- | Class of things that we can obtain a 'Unique' from
class Uniquable a where
getUnique :: a -> Unique
\begin{code}
pprUnique :: Unique -> SDoc
pprUnique uniq
-#ifdef DEBUG
- | opt_SuppressUniques
- = empty -- Used exclusively to suppress uniques so you
- | otherwise -- can compare output easily
-#endif
+-- | opt_SuppressUniques
+-- = empty -- Used exclusively to suppress uniques so you
+-- | otherwise -- can compare output easily
= case unpkUnique uniq of
(tag, u) -> finish_ppr tag u (text (iToBase62 u))
#if defined(__GLASGOW_HASKELL__)
--then FastInt == Int#
chooseChar62 n = C# (indexCharOffAddr# chars62 n)
- chars62 = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"#
+ !chars62 = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"#
#else
--Haskell98 arrays are portable
chooseChar62 n = (!) chars62 n
X: uniques derived by deriveUnique
_: unifiable tyvars (above)
0-9: prelude things below
+ (no numbers left any more..)
+ :: (prelude) parallel array data constructors
other a-z: lower case chars for unique supplies. Used so far:
d desugarer
f AbsC flattener
g SimplStg
- l ndpFlatten
n Native codegen
r Hsc name cache
s simplifier
isTupleKey u = case unpkUnique u of
(tag,_) -> tag == '4' || tag == '5' || tag == '7' || tag == '8'
-mkPrimOpIdUnique op = mkUnique '9' op
-mkPreludeMiscIdUnique i = mkUnique '0' i
+mkPrimOpIdUnique op = mkUnique '9' op
+mkPreludeMiscIdUnique i = mkUnique '0' i
--- No numbers left anymore, so I pick something different for the character
--- tag
+-- No numbers left anymore, so I pick something different for the character tag
mkPArrDataConUnique a = mkUnique ':' (2*a)
-- The "tyvar uniques" print specially nicely: a, b, c, etc.
mkPseudoUniqueD i = mkUnique 'D' i -- used in NCG for getUnique on RealRegs
mkPseudoUniqueE i = mkUnique 'E' i -- used in NCG spiller to create spill VirtualRegs
mkPseudoUniqueH i = mkUnique 'H' i -- used in NCG spiller to create spill VirtualRegs
+
+mkRegSingleUnique, mkRegPairUnique, mkRegSubUnique, mkRegClassUnique :: Int -> Unique
+mkRegSingleUnique = mkUnique 'R'
+mkRegSubUnique = mkUnique 'S'
+mkRegPairUnique = mkUnique 'P'
+mkRegClassUnique = mkUnique 'L'
+
+mkVarOccUnique, mkDataOccUnique, mkTvOccUnique, mkTcOccUnique :: FastString -> Unique
+-- See Note [The Unique of an OccName] in OccName
+mkVarOccUnique fs = mkUnique 'i' (iBox (uniqueOfFS fs))
+mkDataOccUnique fs = mkUnique 'd' (iBox (uniqueOfFS fs))
+mkTvOccUnique fs = mkUnique 'v' (iBox (uniqueOfFS fs))
+mkTcOccUnique fs = mkUnique 'c' (iBox (uniqueOfFS fs))
\end{code}