X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=Data%2FBits.hs;h=8eaec9c63f900959b1552483dbda5cb0db5a71a6;hb=e0d697e559faf32d4b9f034c0968c1a299dd74c5;hp=8f6776f37dc7e83421508bd06350dbc04f50c0d9;hpb=72e4fe7801d2d8ab5b243cbb430272b45010f59d;p=ghc-base.git diff --git a/Data/Bits.hs b/Data/Bits.hs index 8f6776f..8eaec9c 100644 --- a/Data/Bits.hs +++ b/Data/Bits.hs @@ -1,4 +1,4 @@ -{-# OPTIONS_GHC -fno-implicit-prelude #-} +{-# OPTIONS_GHC -XNoImplicitPrelude #-} ----------------------------------------------------------------------------- -- | -- Module : Data.Bits @@ -202,20 +202,30 @@ instance Bits Int where #ifdef __GLASGOW_HASKELL__ (I# x#) .&. (I# y#) = I# (word2Int# (int2Word# x# `and#` int2Word# y#)) + (I# x#) .|. (I# y#) = I# (word2Int# (int2Word# x# `or#` int2Word# y#)) + (I# x#) `xor` (I# y#) = I# (word2Int# (int2Word# x# `xor#` int2Word# y#)) + complement (I# x#) = I# (word2Int# (int2Word# x# `xor#` int2Word# (-1#))) + (I# x#) `shift` (I# i#) | i# >=# 0# = I# (x# `iShiftL#` i#) | otherwise = I# (x# `iShiftRA#` negateInt# i#) + + {-# INLINE rotate #-} -- See Note [Constant folding for rotate] (I# x#) `rotate` (I# i#) = I# (word2Int# ((x'# `uncheckedShiftL#` i'#) `or#` (x'# `uncheckedShiftRL#` (wsib -# i'#)))) - where + where x'# = int2Word# x# i'# = word2Int# (int2Word# i# `and#` int2Word# (wsib -# 1#)) wsib = WORD_SIZE_IN_BITS# {- work around preprocessor problem (??) -} bitSize _ = WORD_SIZE_IN_BITS + + {-# INLINE shiftR #-} + -- same as the default definition, but we want it inlined (#2376) + x `shiftR` i = x `shift` (-i) #else /* !__GLASGOW_HASKELL__ */ #ifdef __HUGS__ @@ -321,3 +331,30 @@ fromInts = foldr catInt 0 numInts = toInteger (maxBound::Int) - toInteger (minBound::Int) + 1 #endif /* !__GLASGOW_HASKELL__ */ + +{- Note [Constant folding for rotate] + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +The INLINE on the Int instance of rotate enables it to be constant +folded. For example: + sumU . mapU (`rotate` 3) . replicateU 10000000 $ (7 :: Int) +goes to: + Main.$wfold = + \ (ww_sO7 :: Int#) (ww1_sOb :: Int#) -> + case ww1_sOb of wild_XM { + __DEFAULT -> Main.$wfold (+# ww_sO7 56) (+# wild_XM 1); + 10000000 -> ww_sO7 +whereas before it was left as a call to $wrotate. + +All other Bits instances seem to inline well enough on their +own to enable constant folding; for example 'shift': + sumU . mapU (`shift` 3) . replicateU 10000000 $ (7 :: Int) + goes to: + Main.$wfold = + \ (ww_sOb :: Int#) (ww1_sOf :: Int#) -> + case ww1_sOf of wild_XM { + __DEFAULT -> Main.$wfold (+# ww_sOb 56) (+# wild_XM 1); + 10000000 -> ww_sOb + } +-} + +