36d8e4c4fd7c60bef10f01ad82d419d0c4c9967b
[ghc.git] / compiler / utils / FastTypes.lhs
1 %
2 % (c) The University of Glasgow, 2000-2006
3 %
4 \section{Fast integers, etc... booleans moved to FastBool for using panic}
5
6 \begin{code}
7 {-# LANGUAGE CPP, MagicHash #-}
8
9 --Even if the optimizer could handle boxed arithmetic equally well,
10 --this helps automatically check the sources to make sure that
11 --it's only used in an appropriate pattern of efficiency.
12 --(it also makes `let`s and `case`s stricter...)
13
14 -- | Fast integers, characters and pointer types for use in many parts of GHC
15 module FastTypes (
16     -- * FastInt
17     FastInt,
18
19     -- ** Getting in and out of FastInt
20     _ILIT, iBox, iUnbox,
21
22     -- ** Arithmetic on FastInt
23     (+#), (-#), (*#), quotFastInt, negateFastInt,
24     --quotRemFastInt is difficult because unboxed values can't
25     --be tupled, but unboxed tuples aren't portable.  Just use
26     -- nuisance boxed quotRem and rely on optimization.
27     (==#), (/=#), (<#), (<=#), (>=#), (>#),
28     minFastInt, maxFastInt,
29     --prefer to distinguish operations, not types, between
30     --signed and unsigned.
31     --left-shift is the same for 'signed' and 'unsigned' numbers
32     shiftLFastInt,
33     --right-shift isn't the same for negative numbers (ones with
34     --the highest-order bit '1').  If you don't care because the
35     --number you're shifting is always nonnegative, use the '_' version
36     --which should just be the fastest one.
37     shiftR_FastInt,
38     --"L' = logical or unsigned shift; 'A' = arithmetic or signed shift
39     shiftRLFastInt, shiftRAFastInt,
40     bitAndFastInt, bitOrFastInt,
41     --add more operations to this file as you need them
42
43     -- * FastChar
44     FastChar,
45
46     -- ** Getting in and out of FastChar
47     _CLIT, cBox, cUnbox,
48
49     -- ** Operations on FastChar
50     fastOrd, fastChr, eqFastChar,
51     --note, fastChr is "unsafe"Chr: it doesn't check for
52     --character values above the range of Unicode
53
54     -- * FastPtr
55     FastPtr,
56
57     -- ** Getting in and out of FastPtr
58     pBox, pUnbox,
59
60     -- ** Casting FastPtrs
61     castFastPtr
62   ) where
63
64 #include "HsVersions.h"
65
66 #if defined(__GLASGOW_HASKELL__)
67
68 -- Import the beggars
69 import ExtsCompat46
70
71 type FastInt = Int#
72
73 --in case it's a macro, don't lexically feed an argument!
74 --e.g. #define _ILIT(x) (x#) , #define _ILIT(x) (x :: FastInt)
75 _ILIT = \(I# x) -> x
76 --perhaps for accomodating caseless-leading-underscore treatment,
77 --something like _iLIT or iLIT would be better?
78
79 iBox x = I# x
80 iUnbox (I# x) = x
81 quotFastInt   = quotInt#
82 negateFastInt = negateInt#
83
84 --I think uncheckedIShiftL# and uncheckedIShiftRL# are the same
85 --as uncheckedShiftL# and uncheckedShiftRL# ...
86 --should they be used? How new are they?
87 --They existed as far back as GHC 6.0 at least...
88 shiftLFastInt x y = uncheckedIShiftL# x y
89 shiftR_FastInt x y = uncheckedIShiftRL# x y
90 shiftRLFastInt x y = uncheckedIShiftRL# x y
91 shiftRAFastInt x y = uncheckedIShiftRA# x y
92 --{-# INLINE shiftLNonnegativeFastInt #-}
93 --{-# INLINE shiftRNonnegativeFastInt #-}
94 --shiftLNonnegativeFastInt n p = word2Int#((int2Word# n) `uncheckedShiftL#` p)
95 --shiftRNonnegativeFastInt n p = word2Int#((int2Word# n) `uncheckedShiftRL#` p)
96 bitAndFastInt x y = word2Int# (and# (int2Word# x) (int2Word# y))
97 bitOrFastInt x y = word2Int# (or# (int2Word# x) (int2Word# y))
98
99 type FastChar = Char#
100 _CLIT = \(C# c) -> c
101 cBox c = C# c
102 cUnbox (C# c) = c
103 fastOrd c = ord# c
104 fastChr x = chr# x
105 eqFastChar a b = eqChar# a b
106
107 --note that the type-parameter doesn't provide any safety
108 --when it's a synonym, but as long as we keep it compiling
109 --with and without __GLASGOW_HASKELL__ defined, it's fine.
110 type FastPtr a = Addr#
111 pBox p = Ptr p
112 pUnbox (Ptr p) = p
113 castFastPtr p = p
114
115 #else /* ! __GLASGOW_HASKELL__ */
116
117 import Data.Char (ord, chr)
118
119 import Data.Bits
120 import Data.Word (Word) --is it a good idea to assume this exists too?
121 --does anyone need shiftRLFastInt? (apparently yes.)
122
123 import Foreign.Ptr
124
125 type FastInt = Int
126 _ILIT x = x
127 iBox x = x
128 iUnbox x = x
129 (+#) = (+)
130 (-#) = (-)
131 (*#) = (*)
132 quotFastInt   = quot
133 --quotRemFastInt = quotRem
134 negateFastInt = negate
135 (==#) = (==)
136 (/=#) = (/=)
137 (<#)  = (<)
138 (<=#) = (<=)
139 (>=#) = (>=)
140 (>#)  = (>)
141 shiftLFastInt = shiftL
142 shiftR_FastInt = shiftR
143 shiftRAFastInt = shiftR
144 shiftRLFastInt n p = fromIntegral (shiftR (fromIntegral n :: Word) p)
145 --shiftLFastInt n p = n * (2 ^ p)
146 --assuming quot-Int is faster and the
147 --same for nonnegative arguments than div-Int
148 --shiftR_FastInt n p = n `quot` (2 ^ p)
149 --shiftRAFastInt n p = n `div` (2 ^ p)
150 --I couldn't figure out how to implement without Word nor Bits
151 --shiftRLFastInt n p = fromIntegral ((fromIntegral n :: Word) `quot` (2 ^ (fromIntegral p :: Word)))
152
153 bitAndFastInt = (.&.)
154 bitOrFastInt = (.|.)
155
156 type FastBool = Bool
157 fastBool x = x
158 isFastTrue x = x
159 -- make sure these are as strict as the unboxed version,
160 -- so that the performance characteristics match
161 fastOr False False = False
162 fastOr _ _ = True
163 fastAnd True True = True
164 fastAnd _ _ = False
165
166 type FastChar = Char
167 _CLIT c = c
168 cBox c = c
169 cUnbox c = c
170 fastOrd = ord
171 fastChr = chr  --or unsafeChr if there was a standard location for it
172 eqFastChar = (==)
173
174 type FastPtr a = Ptr a
175 pBox p = p
176 pUnbox p = p
177 castFastPtr = castPtr
178
179 --These are among the type-signatures necessary for !ghc to compile
180 -- but break ghc (can't give a signature for an import...)
181 --Note that the comparisons actually do return Bools not FastBools.
182 (+#), (-#), (*#) :: FastInt -> FastInt -> FastInt
183 (==#), (/=#), (<#), (<=#), (>=#), (>#) :: FastInt -> FastInt -> Bool
184
185 #endif /* ! __GLASGOW_HASKELL__ */
186
187 minFastInt, maxFastInt :: FastInt -> FastInt -> FastInt
188 minFastInt x y = if x <# y then x else y
189 maxFastInt x y = if x <# y then y else x
190
191 -- type-signatures will improve the non-ghc-specific versions
192 -- and keep things accurate (and ABLE to compile!)
193 _ILIT :: Int -> FastInt
194 iBox :: FastInt -> Int
195 iUnbox :: Int -> FastInt
196
197 quotFastInt :: FastInt -> FastInt -> FastInt
198 negateFastInt :: FastInt -> FastInt
199 shiftLFastInt, shiftR_FastInt, shiftRAFastInt, shiftRLFastInt
200    :: FastInt -> FastInt -> FastInt
201 bitAndFastInt, bitOrFastInt :: FastInt -> FastInt -> FastInt
202
203 _CLIT :: Char -> FastChar
204 cBox :: FastChar -> Char
205 cUnbox :: Char -> FastChar
206 fastOrd :: FastChar -> FastInt
207 fastChr :: FastInt -> FastChar
208 eqFastChar :: FastChar -> FastChar -> Bool
209
210 pBox :: FastPtr a -> Ptr a
211 pUnbox :: Ptr a -> FastPtr a
212 castFastPtr :: FastPtr a -> FastPtr b
213
214 \end{code}