2 % (c) The University of Glasgow, 2000-2006
4 \section{Fast integers, etc... booleans moved to FastBool for using panic}
8 --Even if the optimizer could handle boxed arithmetic equally well,
9 --this helps automatically check the sources to make sure that
10 --it's only used in an appropriate pattern of efficiency.
11 --(it also makes `let`s and `case`s stricter...)
14 FastInt, _ILIT, iBox, iUnbox,
15 (+#), (-#), (*#), quotFastInt, negateFastInt,
16 --quotRemFastInt is difficult because unboxed values can't
17 --be tupled, but unboxed tuples aren't portable. Just use
18 -- nuisance boxed quotRem and rely on optimization.
19 (==#), (/=#), (<#), (<=#), (>=#), (>#),
20 minFastInt, maxFastInt,
21 --prefer to distinguish operations, not types, between
22 --signed and unsigned.
23 --left-shift is the same for 'signed' and 'unsigned' numbers
25 --right-shift isn't the same for negative numbers (ones with
26 --the highest-order bit '1'). If you don't care because the
27 --number you're shifting is always nonnegative, use the '_' version
28 --which should just be the fastest one.
30 --"L' = logical or unsigned shift; 'A' = arithmetic or signed shift
31 shiftRLFastInt, shiftRAFastInt,
32 bitAndFastInt, bitOrFastInt,
33 --add more operations to this file as you need them
35 --note, fastChr is "unsafe"Chr: it doesn't check for
36 --character values above the range of Unicode
37 FastChar, _CLIT, cBox, cUnbox, fastOrd, fastChr, eqFastChar,
39 FastPtr, pBox, pUnbox, castFastPtr
42 #include "HsVersions.h"
44 #if defined(__GLASGOW_HASKELL__)
51 --in case it's a macro, don't lexically feed an argument!
52 --e.g. #define _ILIT(x) (x#) , #define _ILIT(x) (x :: FastInt)
54 --perhaps for accomodating caseless-leading-underscore treatment,
55 --something like _iLIT or iLIT would be better?
59 quotFastInt = quotInt#
60 negateFastInt = negateInt#
62 --I think uncheckedIShiftL# and uncheckedIShiftRL# are the same
63 --as uncheckedShiftL# and uncheckedShiftRL# ...
64 --should they be used? How new are they?
65 --They existed as far back as GHC 6.0 at least...
66 shiftLFastInt x y = uncheckedIShiftL# x y
67 shiftR_FastInt x y = uncheckedIShiftRL# x y
68 shiftRLFastInt x y = uncheckedIShiftRL# x y
69 shiftRAFastInt x y = uncheckedIShiftRA# x y
70 --{-# INLINE shiftLNonnegativeFastInt #-}
71 --{-# INLINE shiftRNonnegativeFastInt #-}
72 --shiftLNonnegativeFastInt n p = word2Int#((int2Word# n) `uncheckedShiftL#` p)
73 --shiftRNonnegativeFastInt n p = word2Int#((int2Word# n) `uncheckedShiftRL#` p)
74 bitAndFastInt x y = word2Int# (and# (int2Word# x) (int2Word# y))
75 bitOrFastInt x y = word2Int# (or# (int2Word# x) (int2Word# y))
83 eqFastChar a b = eqChar# a b
85 --note that the type-parameter doesn't provide any safety
86 --when it's a synonym, but as long as we keep it compiling
87 --with and without __GLASGOW_HASKELL__ defined, it's fine.
88 type FastPtr a = Addr#
93 #else /* ! __GLASGOW_HASKELL__ */
95 import Data.Char (ord, chr)
98 import Data.Word (Word) --is it a good idea to assume this exists too?
99 --does anyone need shiftRLFastInt? (apparently yes.)
111 --quotRemFastInt = quotRem
112 negateFastInt = negate
119 shiftLFastInt = shiftL
120 shiftR_FastInt = shiftR
121 shiftRAFastInt = shiftR
122 shiftRLFastInt n p = fromIntegral (shiftR (fromIntegral n :: Word) p)
123 --shiftLFastInt n p = n * (2 ^ p)
124 --assuming quot-Int is faster and the
125 --same for nonnegative arguments than div-Int
126 --shiftR_FastInt n p = n `quot` (2 ^ p)
127 --shiftRAFastInt n p = n `div` (2 ^ p)
128 --I couldn't figure out how to implement without Word nor Bits
129 --shiftRLFastInt n p = fromIntegral ((fromIntegral n :: Word) `quot` (2 ^ (fromIntegral p :: Word)))
131 bitAndFastInt = (.&.)
137 -- make sure these are as strict as the unboxed version,
138 -- so that the performance characteristics match
139 fastOr False False = False
141 fastAnd True True = True
149 fastChr = chr --or unsafeChr if there was a standard location for it
152 type FastPtr a = Ptr a
155 castFastPtr = castPtr
157 --These are among the type-signatures necessary for !ghc to compile
158 -- but break ghc (can't give a signature for an import...)
159 --Note that the comparisons actually do return Bools not FastBools.
160 (+#), (-#), (*#) :: FastInt -> FastInt -> FastInt
161 (==#), (/=#), (<#), (<=#), (>=#), (>#) :: FastInt -> FastInt -> Bool
163 #endif /* ! __GLASGOW_HASKELL__ */
165 minFastInt, maxFastInt :: FastInt -> FastInt -> FastInt
166 minFastInt x y = if x <# y then x else y
167 maxFastInt x y = if x <# y then y else x
169 -- type-signatures will improve the non-ghc-specific versions
170 -- and keep things accurate (and ABLE to compile!)
171 _ILIT :: Int -> FastInt
172 iBox :: FastInt -> Int
173 iUnbox :: Int -> FastInt
175 quotFastInt :: FastInt -> FastInt -> FastInt
176 negateFastInt :: FastInt -> FastInt
177 shiftLFastInt, shiftR_FastInt, shiftRAFastInt, shiftRLFastInt
178 :: FastInt -> FastInt -> FastInt
179 bitAndFastInt, bitOrFastInt :: FastInt -> FastInt -> FastInt
181 _CLIT :: Char -> FastChar
182 cBox :: FastChar -> Char
183 cUnbox :: Char -> FastChar
184 fastOrd :: FastChar -> FastInt
185 fastChr :: FastInt -> FastChar
186 eqFastChar :: FastChar -> FastChar -> Bool
188 pBox :: FastPtr a -> Ptr a
189 pUnbox :: Ptr a -> FastPtr a
190 castFastPtr :: FastPtr a -> FastPtr b