Inline Data.Bits.rotate@Int, enables rotate to be constant folded
authorDon Stewart <dons@galois.com>
Thu, 1 May 2008 23:01:52 +0000 (23:01 +0000)
committerDon Stewart <dons@galois.com>
Thu, 1 May 2008 23:01:52 +0000 (23:01 +0000)
All other Bits instances seem to inline well enough on their own
to enable constant folding, e.g.

    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
        }

With this patch, rotate gets inlined and folded too,

    sumU . mapU (`rotate` 3) . replicateU 10000000 $ (7 :: Int)

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 it was left as a call to $wrotate before.

Data/Bits.hs

index 8f6776f..c0b5290 100644 (file)
@@ -202,16 +202,23 @@ 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#)
+
+    -- Important for constant folding (May 2008):
+    {-# INLINE 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 (??) -}