add -fsimpleopt-before-flatten
[ghc-hetmet.git] / compiler / utils / FastTypes.lhs
index dc43574..ace46e6 100644 (file)
@@ -1,22 +1,63 @@
 %
 % (c) The University of Glasgow, 2000-2006
 %
-\section{Fast integers and booleans}
+\section{Fast integers, etc... booleans moved to FastBool for using panic}
 
 \begin{code}
-{-# OPTIONS -w #-}
--- The above warning supression flag is a temporary kludge.
--- While working on this module you are encouraged to remove it and fix
--- any warnings in the module. See
---     http://hackage.haskell.org/trac/ghc/wiki/CodingStyle#Warnings
--- for details
 
+--Even if the optimizer could handle boxed arithmetic equally well,
+--this helps automatically check the sources to make sure that
+--it's only used in an appropriate pattern of efficiency.
+--(it also makes `let`s and `case`s stricter...)
+
+-- | Fast integers, characters and pointer types for use in many parts of GHC
 module FastTypes (
-    FastInt, _ILIT, iBox, iUnbox,
+    -- * FastInt
+    FastInt,
+    
+    -- ** Getting in and out of FastInt
+    _ILIT, iBox, iUnbox,
+    
+    -- ** Arithmetic on FastInt
     (+#), (-#), (*#), quotFastInt, negateFastInt,
-    (==#), (<#), (<=#), (>=#), (>#),
-
-    FastBool, fastBool, isFastTrue, fastOr, fastAnd
+    --quotRemFastInt is difficult because unboxed values can't
+    --be tupled, but unboxed tuples aren't portable.  Just use
+    -- nuisance boxed quotRem and rely on optimization.
+    (==#), (/=#), (<#), (<=#), (>=#), (>#),
+    minFastInt, maxFastInt,
+    --prefer to distinguish operations, not types, between
+    --signed and unsigned.
+    --left-shift is the same for 'signed' and 'unsigned' numbers
+    shiftLFastInt,
+    --right-shift isn't the same for negative numbers (ones with
+    --the highest-order bit '1').  If you don't care because the
+    --number you're shifting is always nonnegative, use the '_' version
+    --which should just be the fastest one.
+    shiftR_FastInt,
+    --"L' = logical or unsigned shift; 'A' = arithmetic or signed shift
+    shiftRLFastInt, shiftRAFastInt,
+    bitAndFastInt, bitOrFastInt,
+    --add more operations to this file as you need them
+
+    -- * FastChar
+    FastChar,
+
+    -- ** Getting in and out of FastChar
+    _CLIT, cBox, cUnbox,
+
+    -- ** Operations on FastChar
+    fastOrd, fastChr, eqFastChar,
+    --note, fastChr is "unsafe"Chr: it doesn't check for
+    --character values above the range of Unicode
+
+    -- * FastPtr
+    FastPtr, 
+    
+    -- ** Getting in and out of FastPtr
+    pBox, pUnbox,
+    
+    -- ** Casting FastPtrs
+    castFastPtr
   ) where
 
 #include "HsVersions.h"
@@ -25,31 +66,60 @@ module FastTypes (
 
 -- Import the beggars
 import GHC.Exts
-       ( Int(..), Int#, (+#), (-#), (*#), 
-         quotInt#, negateInt#, (==#), (<#), (<=#), (>=#), (>#)
-       )
 
 type FastInt = Int#
-_ILIT (I# x) = x
+
+--in case it's a macro, don't lexically feed an argument!
+--e.g. #define _ILIT(x) (x#) , #define _ILIT(x) (x :: FastInt)
+_ILIT = \(I# x) -> x
+--perhaps for accomodating caseless-leading-underscore treatment,
+--something like _iLIT or iLIT would be better?
+
 iBox x = I# x
 iUnbox (I# x) = x
 quotFastInt   = quotInt#
 negateFastInt = negateInt#
 
-type FastBool = Int#
-fastBool True  = 1#
-fastBool False = 0#
-isFastTrue x = x ==# 1#
+--I think uncheckedIShiftL# and uncheckedIShiftRL# are the same
+--as uncheckedShiftL# and uncheckedShiftRL# ...
+--should they be used? How new are they?
+--They existed as far back as GHC 6.0 at least...
+shiftLFastInt x y = uncheckedIShiftL# x y
+shiftR_FastInt x y = uncheckedIShiftRL# x y
+shiftRLFastInt x y = uncheckedIShiftRL# x y
+shiftRAFastInt x y = uncheckedIShiftRA# x y
+--{-# INLINE shiftLNonnegativeFastInt #-}
+--{-# INLINE shiftRNonnegativeFastInt #-}
+--shiftLNonnegativeFastInt n p = word2Int#((int2Word# n) `uncheckedShiftL#` p)
+--shiftRNonnegativeFastInt n p = word2Int#((int2Word# n) `uncheckedShiftRL#` p)
+bitAndFastInt x y = word2Int# (and# (int2Word# x) (int2Word# y))
+bitOrFastInt x y = word2Int# (or# (int2Word# x) (int2Word# y))
+
+type FastChar = Char#
+_CLIT = \(C# c) -> c
+cBox c = C# c
+cUnbox (C# c) = c
+fastOrd c = ord# c
+fastChr x = chr# x
+eqFastChar a b = eqChar# a b
+
+--note that the type-parameter doesn't provide any safety
+--when it's a synonym, but as long as we keep it compiling
+--with and without __GLASGOW_HASKELL__ defined, it's fine.
+type FastPtr a = Addr#
+pBox p = Ptr p
+pUnbox (Ptr p) = p
+castFastPtr p = p
 
--- note that fastOr and fastAnd are strict in both arguments
--- since they are unboxed
-fastOr 1# _ = 1#
-fastOr 0# x = x
+#else /* ! __GLASGOW_HASKELL__ */
 
-fastAnd 0# x = 0#
-fastAnd 1# x = x
+import Data.Char (ord, chr)
 
-#else /* ! __GLASGOW_HASKELL__ */
+import Data.Bits
+import Data.Word (Word) --is it a good idea to assume this exists too?
+--does anyone need shiftRLFastInt? (apparently yes.)
+
+import Foreign.Ptr
 
 type FastInt = Int
 _ILIT x = x
@@ -59,12 +129,28 @@ iUnbox x = x
 (-#) = (-)
 (*#) = (*)
 quotFastInt   = quot
+--quotRemFastInt = quotRem
 negateFastInt = negate
 (==#) = (==)
+(/=#) = (/=)
 (<#)  = (<)
 (<=#) = (<=)
 (>=#) = (>=)
 (>#)  = (>)
+shiftLFastInt = shiftL
+shiftR_FastInt = shiftR
+shiftRAFastInt = shiftR
+shiftRLFastInt n p = fromIntegral (shiftR (fromIntegral n :: Word) p)
+--shiftLFastInt n p = n * (2 ^ p)
+--assuming quot-Int is faster and the
+--same for nonnegative arguments than div-Int
+--shiftR_FastInt n p = n `quot` (2 ^ p)
+--shiftRAFastInt n p = n `div` (2 ^ p)
+--I couldn't figure out how to implement without Word nor Bits
+--shiftRLFastInt n p = fromIntegral ((fromIntegral n :: Word) `quot` (2 ^ (fromIntegral p :: Word)))
+
+bitAndFastInt = (.&.)
+bitOrFastInt = (.|.)
 
 type FastBool = Bool
 fastBool x = x
@@ -76,20 +162,31 @@ fastOr _ _ = True
 fastAnd True True = True
 fastAnd _ _ = False
 
+type FastChar = Char
+_CLIT c = c
+cBox c = c
+cUnbox c = c
+fastOrd = ord
+fastChr = chr  --or unsafeChr if there was a standard location for it
+eqFastChar = (==)
+
+type FastPtr a = Ptr a
+pBox p = p
+pUnbox p = p
+castFastPtr = castPtr
+
 --These are among the type-signatures necessary for !ghc to compile
 -- but break ghc (can't give a signature for an import...)
 --Note that the comparisons actually do return Bools not FastBools.
-(+#) :: FastInt -> FastInt -> FastInt
-(-#) :: FastInt -> FastInt -> FastInt
-(*#) :: FastInt -> FastInt -> FastInt
-(==#) :: FastInt -> FastInt -> Bool
-(<#) :: FastInt -> FastInt -> Bool
-(<=#) :: FastInt -> FastInt -> Bool
-(>=#) :: FastInt -> FastInt -> Bool
-(>#) :: FastInt -> FastInt -> Bool
+(+#), (-#), (*#) :: FastInt -> FastInt -> FastInt
+(==#), (/=#), (<#), (<=#), (>=#), (>#) :: FastInt -> FastInt -> Bool
 
 #endif /* ! __GLASGOW_HASKELL__ */
 
+minFastInt, maxFastInt :: FastInt -> FastInt -> FastInt
+minFastInt x y = if x <# y then x else y
+maxFastInt x y = if x <# y then y else x
+
 -- type-signatures will improve the non-ghc-specific versions
 -- and keep things accurate (and ABLE to compile!)
 _ILIT :: Int -> FastInt
@@ -98,10 +195,19 @@ iUnbox :: Int -> FastInt
 
 quotFastInt :: FastInt -> FastInt -> FastInt
 negateFastInt :: FastInt -> FastInt
-
-fastBool :: Bool -> FastBool
-isFastTrue :: FastBool -> Bool
-fastOr :: FastBool -> FastBool -> FastBool
-fastAnd :: FastBool -> FastBool -> FastBool
+shiftLFastInt, shiftR_FastInt, shiftRAFastInt, shiftRLFastInt
+   :: FastInt -> FastInt -> FastInt
+bitAndFastInt, bitOrFastInt :: FastInt -> FastInt -> FastInt
+
+_CLIT :: Char -> FastChar
+cBox :: FastChar -> Char
+cUnbox :: Char -> FastChar
+fastOrd :: FastChar -> FastInt
+fastChr :: FastInt -> FastChar
+eqFastChar :: FastChar -> FastChar -> Bool
+
+pBox :: FastPtr a -> Ptr a
+pUnbox :: Ptr a -> FastPtr a
+castFastPtr :: FastPtr a -> FastPtr b
 
 \end{code}