diff options
author | Sylvain Henry <sylvain@haskus.fr> | 2021-01-15 12:33:40 +0100 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2021-01-23 15:31:20 -0500 |
commit | 773e2828fde4d8f640082b6bded9945e7b9584e3 (patch) | |
tree | 735cc36bc1ce14820890f8734e68280521a6e2ce /libraries/base/GHC | |
parent | 97208613414106e493a586d295ca05393e136ba4 (diff) | |
download | haskell-773e2828fde4d8f640082b6bded9945e7b9584e3.tar.gz |
Bignum: add Natural constant folding rules (#15821)
* Implement constant folding rules for Natural (similar to Integer ones)
* Add mkCoreUbxSum helper in GHC.Core.Make
* Remove naturalTo/FromInt
We now only provide `naturalTo/FromWord` as
the semantics is clear (truncate/zero-extend). For Int we have to deal
with negative numbers (throw an exception? convert to Word
beforehand?) so we leave the decision about what to do to the caller.
Moreover, now that we have sized types (Int8#, Int16#, ..., Word8#,
etc.) there is no reason to bless `Int#` more than `Int8#` or `Word8#`
(for example).
* Replaced a few `()` with `(# #)`
Diffstat (limited to 'libraries/base/GHC')
-rw-r--r-- | libraries/base/GHC/Enum.hs | 4 | ||||
-rw-r--r-- | libraries/base/GHC/Float.hs | 6 | ||||
-rw-r--r-- | libraries/base/GHC/Int.hs | 16 | ||||
-rw-r--r-- | libraries/base/GHC/Natural.hs | 20 | ||||
-rw-r--r-- | libraries/base/GHC/Num.hs | 12 | ||||
-rw-r--r-- | libraries/base/GHC/Real.hs | 2 |
6 files changed, 26 insertions, 34 deletions
diff --git a/libraries/base/GHC/Enum.hs b/libraries/base/GHC/Enum.hs index 54d6c6b34a..d107c1eb12 100644 --- a/libraries/base/GHC/Enum.hs +++ b/libraries/base/GHC/Enum.hs @@ -963,8 +963,8 @@ dn_list x0 delta lim = go (x0 :: Integer) instance Enum Natural where succ n = n + 1 pred n = n - 1 - toEnum i - | i >= 0 = naturalFromIntUnsafe i + toEnum i@(I# i#) + | i >= 0 = naturalFromWord# (int2Word# i#) | otherwise = errorWithoutStackTrace "toEnum: unexpected negative Int" fromEnum (NS w) diff --git a/libraries/base/GHC/Float.hs b/libraries/base/GHC/Float.hs index eae6edb253..cb1ef6044c 100644 --- a/libraries/base/GHC/Float.hs +++ b/libraries/base/GHC/Float.hs @@ -1099,9 +1099,9 @@ fromRat'' minEx@(I# me#) mantDigs@(I# md#) n d = | isTrue# (ld'# ># (ln# +# 1#)) -> encodeFloat 0 0 -- result of shift < 0.5 | otherwise -> -- first bit of n shifted to 0.5 place case integerIsPowerOf2# n of - (# | _ #) -> encodeFloat 0 0 -- round to even - (# () | #) -> encodeFloat 1 (minEx - mantDigs) - (# () | #) -> + (# | _ #) -> encodeFloat 0 0 -- round to even + (# (# #) | #) -> encodeFloat 1 (minEx - mantDigs) + (# (# #) | #) -> let ln = I# (word2Int# (integerLog2# n)) ld = I# (word2Int# (integerLog2# d)) -- 2^(ln-ld-1) < n/d < 2^(ln-ld+1) diff --git a/libraries/base/GHC/Int.hs b/libraries/base/GHC/Int.hs index 08827e92c4..2af0856bb7 100644 --- a/libraries/base/GHC/Int.hs +++ b/libraries/base/GHC/Int.hs @@ -1124,29 +1124,29 @@ instance Ix Int64 where {-# RULES "fromIntegral/Natural->Int8" - fromIntegral = (fromIntegral :: Int -> Int8) . naturalToInt + fromIntegral = (fromIntegral :: Int -> Int8) . fromIntegral . naturalToWord "fromIntegral/Natural->Int16" - fromIntegral = (fromIntegral :: Int -> Int16) . naturalToInt + fromIntegral = (fromIntegral :: Int -> Int16) . fromIntegral . naturalToWord "fromIntegral/Natural->Int32" - fromIntegral = (fromIntegral :: Int -> Int32) . naturalToInt + fromIntegral = (fromIntegral :: Int -> Int32) . fromIntegral . naturalToWord #-} {-# RULES "fromIntegral/Int8->Natural" - fromIntegral = naturalFromIntUnsafe . (fromIntegral :: Int8 -> Int) + fromIntegral = naturalFromWord . fromIntegral . (fromIntegral :: Int8 -> Int) "fromIntegral/Int16->Natural" - fromIntegral = naturalFromIntUnsafe . (fromIntegral :: Int16 -> Int) + fromIntegral = naturalFromWord . fromIntegral . (fromIntegral :: Int16 -> Int) "fromIntegral/Int32->Natural" - fromIntegral = naturalFromIntUnsafe . (fromIntegral :: Int32 -> Int) + fromIntegral = naturalFromWord . fromIntegral . (fromIntegral :: Int32 -> Int) #-} #if WORD_SIZE_IN_BITS == 64 -- these RULES are valid for Word==Word64 & Int==Int64 {-# RULES "fromIntegral/Natural->Int64" - fromIntegral = (fromIntegral :: Int -> Int64) . naturalToInt + fromIntegral = (fromIntegral :: Int -> Int64) . fromIntegral . naturalToWord "fromIntegral/Int64->Natural" - fromIntegral = naturalFromIntUnsafe . (fromIntegral :: Int64 -> Int) + fromIntegral = naturalFromWord . fromIntegral . (fromIntegral :: Int64 -> Int) #-} #endif diff --git a/libraries/base/GHC/Natural.hs b/libraries/base/GHC/Natural.hs index 29c3a4b55e..424b2e6eef 100644 --- a/libraries/base/GHC/Natural.hs +++ b/libraries/base/GHC/Natural.hs @@ -37,12 +37,10 @@ module GHC.Natural -- * Conversions , naturalToInteger , naturalToWord - , naturalToInt - , naturalFromInteger - , wordToNatural - , intToNatural , naturalToWordMaybe + , wordToNatural , wordToNatural# + , naturalFromInteger -- * Modular arithmetic , powModNatural ) @@ -100,8 +98,8 @@ minusNatural = N.naturalSubThrow -- @since 4.8.0.0 minusNaturalMaybe :: Natural -> Natural -> Maybe Natural minusNaturalMaybe x y = case N.naturalSub x y of - (# () | #) -> Nothing - (# | n #) -> Just n + (# (# #) | #) -> Nothing + (# | n #) -> Just n -- | 'Natural' multiplication timesNatural :: Natural -> Natural -> Natural @@ -161,9 +159,6 @@ naturalToInteger = I.integerFromNatural naturalToWord :: Natural -> Word naturalToWord = N.naturalToWord -naturalToInt :: Natural -> Int -naturalToInt = N.naturalToInt - -- | @since 4.10.0.0 naturalFromInteger :: Integer -> Natural naturalFromInteger = I.integerToNatural @@ -174,17 +169,14 @@ naturalFromInteger = I.integerToNatural wordToNatural :: Word -> Natural wordToNatural = N.naturalFromWord -intToNatural :: Int -> Natural -intToNatural = N.naturalFromIntThrow - -- | Try downcasting 'Natural' to 'Word' value. -- Returns 'Nothing' if value doesn't fit in 'Word'. -- -- @since 4.8.0.0 naturalToWordMaybe :: Natural -> Maybe Word naturalToWordMaybe n = case N.naturalToWordMaybe# n of - (# w | #) -> Just (W# w) - (# | () #) -> Nothing + (# | w #) -> Just (W# w) + (# (# #) | #) -> Nothing wordToNatural# :: Word -> Natural wordToNatural# = N.naturalFromWord diff --git a/libraries/base/GHC/Num.hs b/libraries/base/GHC/Num.hs index df0c66b7bd..3d26d35a0d 100644 --- a/libraries/base/GHC/Num.hs +++ b/libraries/base/GHC/Num.hs @@ -138,13 +138,13 @@ instance Num Integer where -- -- @since 4.8.0.0 instance Num Natural where - (+) = naturalAdd - (-) = naturalSubThrow - (*) = naturalMul - negate = naturalNegate + (+) = naturalAdd + (-) = naturalSubThrow + (*) = naturalMul + negate = naturalNegate fromInteger = integerToNaturalThrow - abs = id - signum = naturalSignum + abs = id + signum = naturalSignum {-# DEPRECATED quotRemInteger "Use integerQuotRem# instead" #-} quotRemInteger :: Integer -> Integer -> (# Integer, Integer #) diff --git a/libraries/base/GHC/Real.hs b/libraries/base/GHC/Real.hs index 4d0b05a5f9..ee61e34e70 100644 --- a/libraries/base/GHC/Real.hs +++ b/libraries/base/GHC/Real.hs @@ -587,7 +587,7 @@ fromIntegral = fromInteger . toInteger {-# RULES "fromIntegral/Word->Natural" fromIntegral = naturalFromWord -"fromIntegral/Int->Natural" fromIntegral = naturalFromInt +"fromIntegral/Int->Natural" fromIntegral = naturalFromWord . fromIntegral #-} -- | general coercion to fractional types |