{-# LANGUAGE CPP, BangPatterns, MagicHash #-}
module Unique (
Unique, Uniquable(..),
uNIQUE_BITS,
hasKey,
pprUniqueAlways,
mkUniqueGrimily,
getKey,
mkUnique, unpkUnique,
eqUnique, ltUnique,
deriveUnique,
newTagUnique,
initTyVarUnique,
initExitJoinUnique,
nonDetCmpUnique,
isValidKnownKeyUnique,
mkAlphaTyVarUnique,
mkPrimOpIdUnique, mkPrimOpWrapperUnique,
mkPreludeMiscIdUnique, mkPreludeDataConUnique,
mkPreludeTyConUnique, mkPreludeClassUnique,
mkCoVarUnique,
mkVarOccUnique, mkDataOccUnique, mkTvOccUnique, mkTcOccUnique,
mkRegSingleUnique, mkRegPairUnique, mkRegClassUnique, mkRegSubUnique,
mkCostCentreUnique,
mkBuiltinUnique,
mkPseudoUniqueD,
mkPseudoUniqueE,
mkPseudoUniqueH,
tyConRepNameUnique,
dataConWorkerUnique, dataConTyRepNameUnique
) where
#include "HsVersions.h"
#include "Unique.h"
import GhcPrelude
import BasicTypes
import FastString
import Outputable
import Util
import GHC.Exts (indexCharOffAddr#, Char(..), Int(..))
import Data.Char ( chr, ord )
import Data.Bits
newtype Unique = MkUnique Int
{-# INLINE uNIQUE_BITS #-}
uNIQUE_BITS :: Int
uNIQUE_BITS :: Int
uNIQUE_BITS = Int -> Int
forall b. FiniteBits b => b -> Int
finiteBitSize (0 :: Int) Int -> Int -> Int
forall a. Num a => a -> a -> a
- UNIQUE_TAG_BITS
unpkUnique :: Unique -> (Char, Int)
mkUniqueGrimily :: Int -> Unique
getKey :: Unique -> Int
incrUnique :: Unique -> Unique
stepUnique :: Unique -> Int -> Unique
deriveUnique :: Unique -> Int -> Unique
newTagUnique :: Unique -> Char -> Unique
mkUniqueGrimily :: Int -> Unique
mkUniqueGrimily = Int -> Unique
MkUnique
{-# INLINE getKey #-}
getKey :: Unique -> Int
getKey (MkUnique x :: Int
x) = Int
x
incrUnique :: Unique -> Unique
incrUnique (MkUnique i :: Int
i) = Int -> Unique
MkUnique (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1)
stepUnique :: Unique -> Int -> Unique
stepUnique (MkUnique i :: Int
i) n :: Int
n = Int -> Unique
MkUnique (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
n)
deriveUnique :: Unique -> Int -> Unique
deriveUnique (MkUnique i :: Int
i) delta :: Int
delta = Char -> Int -> Unique
mkUnique 'X' (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
delta)
newTagUnique :: Unique -> Char -> Unique
newTagUnique u :: Unique
u c :: Char
c = Char -> Int -> Unique
mkUnique Char
c Int
i where (_,i :: Int
i) = Unique -> (Char, Int)
unpkUnique Unique
u
uniqueMask :: Int
uniqueMask :: Int
uniqueMask = (1 Int -> Int -> Int
forall a. Bits a => a -> Int -> a
`shiftL` Int
uNIQUE_BITS) Int -> Int -> Int
forall a. Num a => a -> a -> a
- 1
mkUnique :: Char -> Int -> Unique
mkUnique :: Char -> Int -> Unique
mkUnique c :: Char
c i :: Int
i
= Int -> Unique
MkUnique (Int
tag Int -> Int -> Int
forall a. Bits a => a -> a -> a
.|. Int
bits)
where
tag :: Int
tag = Char -> Int
ord Char
c Int -> Int -> Int
forall a. Bits a => a -> Int -> a
`shiftL` Int
uNIQUE_BITS
bits :: Int
bits = Int
i Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. Int
uniqueMask
unpkUnique :: Unique -> (Char, Int)
unpkUnique (MkUnique u :: Int
u)
= let
tag :: Char
tag = Int -> Char
chr (Int
u Int -> Int -> Int
forall a. Bits a => a -> Int -> a
`shiftR` Int
uNIQUE_BITS)
i :: Int
i = Int
u Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. Int
uniqueMask
in
(Char
tag, Int
i)
isValidKnownKeyUnique :: Unique -> Bool
isValidKnownKeyUnique :: Unique -> Bool
isValidKnownKeyUnique u :: Unique
u =
case Unique -> (Char, Int)
unpkUnique Unique
u of
(c :: Char
c, x :: Int
x) -> Char -> Int
ord Char
c Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< 0xff Bool -> Bool -> Bool
&& Int
x Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= (1 Int -> Int -> Int
forall a. Bits a => a -> Int -> a
`shiftL` 22)
class Uniquable a where
getUnique :: a -> Unique
hasKey :: Uniquable a => a -> Unique -> Bool
x :: a
x hasKey :: a -> Unique -> Bool
`hasKey` k :: Unique
k = a -> Unique
forall a. Uniquable a => a -> Unique
getUnique a
x Unique -> Unique -> Bool
forall a. Eq a => a -> a -> Bool
== Unique
k
instance Uniquable FastString where
getUnique :: FastString -> Unique
getUnique fs :: FastString
fs = Int -> Unique
mkUniqueGrimily (FastString -> Int
uniqueOfFS FastString
fs)
instance Uniquable Int where
getUnique :: Int -> Unique
getUnique i :: Int
i = Int -> Unique
mkUniqueGrimily Int
i
eqUnique :: Unique -> Unique -> Bool
eqUnique :: Unique -> Unique -> Bool
eqUnique (MkUnique u1 :: Int
u1) (MkUnique u2 :: Int
u2) = Int
u1 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
u2
ltUnique :: Unique -> Unique -> Bool
ltUnique :: Unique -> Unique -> Bool
ltUnique (MkUnique u1 :: Int
u1) (MkUnique u2 :: Int
u2) = Int
u1 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
u2
nonDetCmpUnique :: Unique -> Unique -> Ordering
nonDetCmpUnique :: Unique -> Unique -> Ordering
nonDetCmpUnique (MkUnique u1 :: Int
u1) (MkUnique u2 :: Int
u2)
= if Int
u1 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
u2 then Ordering
EQ else if Int
u1 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
u2 then Ordering
LT else Ordering
GT
instance Eq Unique where
a :: Unique
a == :: Unique -> Unique -> Bool
== b :: Unique
b = Unique -> Unique -> Bool
eqUnique Unique
a Unique
b
a :: Unique
a /= :: Unique -> Unique -> Bool
/= b :: Unique
b = Bool -> Bool
not (Unique -> Unique -> Bool
eqUnique Unique
a Unique
b)
instance Uniquable Unique where
getUnique :: Unique -> Unique
getUnique u :: Unique
u = Unique
u
showUnique :: Unique -> String
showUnique :: Unique -> String
showUnique uniq :: Unique
uniq
= case Unique -> (Char, Int)
unpkUnique Unique
uniq of
(tag :: Char
tag, u :: Int
u) -> Char -> Int -> String -> String
finish_show Char
tag Int
u (Int -> String
iToBase62 Int
u)
finish_show :: Char -> Int -> String -> String
finish_show :: Char -> Int -> String -> String
finish_show 't' u :: Int
u _pp_u :: String
_pp_u | Int
u Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< 26
=
[Int -> Char
chr (Char -> Int
ord 'a' Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
u)]
finish_show tag :: Char
tag _ pp_u :: String
pp_u = Char
tag Char -> String -> String
forall a. a -> [a] -> [a]
: String
pp_u
pprUniqueAlways :: Unique -> SDoc
pprUniqueAlways :: Unique -> SDoc
pprUniqueAlways u :: Unique
u
= String -> SDoc
text (Unique -> String
showUnique Unique
u)
instance Outputable Unique where
ppr :: Unique -> SDoc
ppr = Unique -> SDoc
pprUniqueAlways
instance Show Unique where
show :: Unique -> String
show uniq :: Unique
uniq = Unique -> String
showUnique Unique
uniq
iToBase62 :: Int -> String
iToBase62 :: Int -> String
iToBase62 n_ :: Int
n_
= ASSERT(n_ >= 0) go n_ ""
where
go :: Int -> String -> String
go n :: Int
n cs :: String
cs | Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< 62
= let !c :: Char
c = Int -> Char
chooseChar62 Int
n in Char
c Char -> String -> String
forall a. a -> [a] -> [a]
: String
cs
| Bool
otherwise
= Int -> String -> String
go Int
q (Char
c Char -> String -> String
forall a. a -> [a] -> [a]
: String
cs) where (!Int
q, r :: Int
r) = Int -> Int -> (Int, Int)
forall a. Integral a => a -> a -> (a, a)
quotRem Int
n 62
!c :: Char
c = Int -> Char
chooseChar62 Int
r
chooseChar62 :: Int -> Char
{-# INLINE chooseChar62 #-}
chooseChar62 :: Int -> Char
chooseChar62 (I# n :: Int#
n) = Char# -> Char
C# (Addr# -> Int# -> Char#
indexCharOffAddr# Addr#
chars62 Int#
n)
chars62 :: Addr#
chars62 = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"#
mkAlphaTyVarUnique :: Int -> Unique
mkPreludeClassUnique :: Int -> Unique
mkPreludeTyConUnique :: Int -> Unique
mkPreludeDataConUnique :: Arity -> Unique
mkPrimOpIdUnique :: Int -> Unique
mkPrimOpWrapperUnique :: Int -> Unique
mkPreludeMiscIdUnique :: Int -> Unique
mkCoVarUnique :: Int -> Unique
mkAlphaTyVarUnique :: Int -> Unique
mkAlphaTyVarUnique i :: Int
i = Char -> Int -> Unique
mkUnique '1' Int
i
mkCoVarUnique :: Int -> Unique
mkCoVarUnique i :: Int
i = Char -> Int -> Unique
mkUnique 'g' Int
i
mkPreludeClassUnique :: Int -> Unique
mkPreludeClassUnique i :: Int
i = Char -> Int -> Unique
mkUnique '2' Int
i
mkPreludeTyConUnique :: Int -> Unique
mkPreludeTyConUnique i :: Int
i = Char -> Int -> Unique
mkUnique '3' (2Int -> Int -> Int
forall a. Num a => a -> a -> a
*Int
i)
tyConRepNameUnique :: Unique -> Unique
tyConRepNameUnique :: Unique -> Unique
tyConRepNameUnique u :: Unique
u = Unique -> Unique
incrUnique Unique
u
mkPreludeDataConUnique :: Int -> Unique
mkPreludeDataConUnique i :: Int
i = Char -> Int -> Unique
mkUnique '6' (3Int -> Int -> Int
forall a. Num a => a -> a -> a
*Int
i)
dataConTyRepNameUnique, dataConWorkerUnique :: Unique -> Unique
dataConWorkerUnique :: Unique -> Unique
dataConWorkerUnique u :: Unique
u = Unique -> Unique
incrUnique Unique
u
dataConTyRepNameUnique :: Unique -> Unique
dataConTyRepNameUnique u :: Unique
u = Unique -> Int -> Unique
stepUnique Unique
u 2
mkPrimOpIdUnique :: Int -> Unique
mkPrimOpIdUnique op :: Int
op = Char -> Int -> Unique
mkUnique '9' (2Int -> Int -> Int
forall a. Num a => a -> a -> a
*Int
op)
mkPrimOpWrapperUnique :: Int -> Unique
mkPrimOpWrapperUnique op :: Int
op = Char -> Int -> Unique
mkUnique '9' (2Int -> Int -> Int
forall a. Num a => a -> a -> a
*Int
opInt -> Int -> Int
forall a. Num a => a -> a -> a
+1)
mkPreludeMiscIdUnique :: Int -> Unique
mkPreludeMiscIdUnique i :: Int
i = Char -> Int -> Unique
mkUnique '0' Int
i
initTyVarUnique :: Unique
initTyVarUnique :: Unique
initTyVarUnique = Char -> Int -> Unique
mkUnique 't' 0
mkPseudoUniqueD, mkPseudoUniqueE, mkPseudoUniqueH,
mkBuiltinUnique :: Int -> Unique
mkBuiltinUnique :: Int -> Unique
mkBuiltinUnique i :: Int
i = Char -> Int -> Unique
mkUnique 'B' Int
i
mkPseudoUniqueD :: Int -> Unique
mkPseudoUniqueD i :: Int
i = Char -> Int -> Unique
mkUnique 'D' Int
i
mkPseudoUniqueE :: Int -> Unique
mkPseudoUniqueE i :: Int
i = Char -> Int -> Unique
mkUnique 'E' Int
i
mkPseudoUniqueH :: Int -> Unique
mkPseudoUniqueH i :: Int
i = Char -> Int -> Unique
mkUnique 'H' Int
i
mkRegSingleUnique, mkRegPairUnique, mkRegSubUnique, mkRegClassUnique :: Int -> Unique
mkRegSingleUnique :: Int -> Unique
mkRegSingleUnique = Char -> Int -> Unique
mkUnique 'R'
mkRegSubUnique :: Int -> Unique
mkRegSubUnique = Char -> Int -> Unique
mkUnique 'S'
mkRegPairUnique :: Int -> Unique
mkRegPairUnique = Char -> Int -> Unique
mkUnique 'P'
mkRegClassUnique :: Int -> Unique
mkRegClassUnique = Char -> Int -> Unique
mkUnique 'L'
mkCostCentreUnique :: Int -> Unique
mkCostCentreUnique :: Int -> Unique
mkCostCentreUnique = Char -> Int -> Unique
mkUnique 'C'
mkVarOccUnique, mkDataOccUnique, mkTvOccUnique, mkTcOccUnique :: FastString -> Unique
mkVarOccUnique :: FastString -> Unique
mkVarOccUnique fs :: FastString
fs = Char -> Int -> Unique
mkUnique 'i' (FastString -> Int
uniqueOfFS FastString
fs)
mkDataOccUnique :: FastString -> Unique
mkDataOccUnique fs :: FastString
fs = Char -> Int -> Unique
mkUnique 'd' (FastString -> Int
uniqueOfFS FastString
fs)
mkTvOccUnique :: FastString -> Unique
mkTvOccUnique fs :: FastString
fs = Char -> Int -> Unique
mkUnique 'v' (FastString -> Int
uniqueOfFS FastString
fs)
mkTcOccUnique :: FastString -> Unique
mkTcOccUnique fs :: FastString
fs = Char -> Int -> Unique
mkUnique 'c' (FastString -> Int
uniqueOfFS FastString
fs)
initExitJoinUnique :: Unique
initExitJoinUnique :: Unique
initExitJoinUnique = Char -> Int -> Unique
mkUnique 's' 0