X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=blobdiff_plain;f=compiler%2Futils%2FFastTypes.lhs;h=ace46e6e1b344830f4c8536cfc83de296f6d2f0b;hp=bcea61de7805b27d891b74771568923ea714c334;hb=de2d10e18ce23e5df7fa4f3433b85c95d6092b58;hpb=da72bd5d852ac0e01a00f5d54030a958fbcf72dc diff --git a/compiler/utils/FastTypes.lhs b/compiler/utils/FastTypes.lhs index bcea61d..ace46e6 100644 --- a/compiler/utils/FastTypes.lhs +++ b/compiler/utils/FastTypes.lhs @@ -1,15 +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} + +--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" @@ -18,29 +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 -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 @@ -50,44 +129,63 @@ 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 isFastTrue x = x -fastOr = (||) -fastAnd = (&&) +-- make sure these are as strict as the unboxed version, +-- so that the performance characteristics match +fastOr False False = False +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...) -(+#) :: FastInt -> FastInt -> FastInt -(-#) :: FastInt -> FastInt -> FastInt -(*#) :: FastInt -> FastInt -> FastInt -(==#) :: FastInt -> FastInt -> Bool -(<#) :: FastInt -> FastInt -> Bool -(<=#) :: FastInt -> FastInt -> Bool -(>=#) :: FastInt -> FastInt -> Bool -(>#) :: FastInt -> FastInt -> Bool +--Note that the comparisons actually do return Bools not FastBools. +(+#), (-#), (*#) :: FastInt -> FastInt -> FastInt +(==#), (/=#), (<#), (<=#), (>=#), (>#) :: FastInt -> FastInt -> Bool #endif /* ! __GLASGOW_HASKELL__ */ --- however it's still possible to check that these are --- valid signatures nonetheless (e.g., ==# returns Bool --- not FastBool/Int# !) -_signatures = - ( (+#) :: FastInt -> FastInt -> FastInt - , (-#) :: FastInt -> FastInt -> FastInt - , (*#) :: FastInt -> FastInt -> FastInt - , (==#) :: FastInt -> FastInt -> Bool - , (<#) :: FastInt -> FastInt -> Bool - , (<=#) :: FastInt -> FastInt -> Bool - , (>=#) :: FastInt -> FastInt -> Bool - , (>#) :: FastInt -> FastInt -> Bool - ) + +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!) @@ -97,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}