diff options
author | Alec Theriault <alec.theriault@gmail.com> | 2019-01-08 10:41:50 -0800 |
---|---|---|
committer | Ben Gamari <ben@smart-cactus.org> | 2019-01-16 14:17:11 -0500 |
commit | f7def747cf0da103237cd17af5c8bfdbdf5823b2 (patch) | |
tree | ea30ac28f46abdcbeeea441373ac3e3443fbac80 | |
parent | 6e320c279ddfde1e16da204590c1c66a511d9b52 (diff) | |
download | haskell-f7def747cf0da103237cd17af5c8bfdbdf5823b2.tar.gz |
Remove from `base` obsolete CPP for `integer-gmp`
* `GHC.Natural` now exports the same functions (regardless of integer backend)
* remove unnecessary CPP around instances
* remove the 'OPTIMISE_INTEGER_GCD_LCM' flag - almost all of those optimizations
now work regardless of which integer backend is used
Note that some CPP still remains for situations where there are backend-specific
optimization hacks (like a more efficient GMP-only `gcd` for `Int#` and `Word#`).
-rw-r--r-- | libraries/base/Data/Bits.hs | 54 | ||||
-rw-r--r-- | libraries/base/GHC/Enum.hs | 28 | ||||
-rw-r--r-- | libraries/base/GHC/Natural.hs | 20 | ||||
-rw-r--r-- | libraries/base/GHC/Num.hs | 26 | ||||
-rw-r--r-- | libraries/base/GHC/Read.hs | 7 | ||||
-rw-r--r-- | libraries/base/GHC/Real.hs | 52 | ||||
-rw-r--r-- | libraries/base/base.cabal | 1 |
7 files changed, 26 insertions, 162 deletions
diff --git a/libraries/base/Data/Bits.hs b/libraries/base/Data/Bits.hs index 18110b55a8..4226f8e967 100644 --- a/libraries/base/Data/Bits.hs +++ b/libraries/base/Data/Bits.hs @@ -63,10 +63,6 @@ import GHC.Num import GHC.Base import GHC.Real -#if defined(MIN_VERSION_integer_gmp) -import GHC.Integer.GMP.Internals (bitInteger, popCountInteger) -#endif - infixl 8 `shift`, `rotate`, `shiftL`, `shiftR`, `rotateL`, `rotateR` infixl 7 .&. infixl 6 `xor` @@ -526,13 +522,8 @@ instance Bits Integer where testBit x (I# i) = testBitInteger x i zeroBits = 0 -#if defined(MIN_VERSION_integer_gmp) bit (I# i#) = bitInteger i# popCount x = I# (popCountInteger x) -#else - bit = bitDefault - popCount = popCountDefault -#endif rotate x i = shift x i -- since an Integer never wraps around @@ -540,7 +531,6 @@ instance Bits Integer where bitSize _ = errorWithoutStackTrace "Data.Bits.bitSize(Integer)" isSigned _ = True -#if defined(MIN_VERSION_integer_gmp) -- | @since 4.8.0 instance Bits Natural where (.&.) = andNatural @@ -563,50 +553,6 @@ instance Bits Natural where bitSizeMaybe _ = Nothing bitSize _ = errorWithoutStackTrace "Data.Bits.bitSize(Natural)" isSigned _ = False -#else --- | @since 4.8.0.0 -instance Bits Natural where - Natural n .&. Natural m = Natural (n .&. m) - {-# INLINE (.&.) #-} - Natural n .|. Natural m = Natural (n .|. m) - {-# INLINE (.|.) #-} - xor (Natural n) (Natural m) = Natural (xor n m) - {-# INLINE xor #-} - complement _ = errorWithoutStackTrace "Bits.complement: Natural complement undefined" - {-# INLINE complement #-} - shift (Natural n) = Natural . shift n - {-# INLINE shift #-} - rotate (Natural n) = Natural . rotate n - {-# INLINE rotate #-} - bit = Natural . bit - {-# INLINE bit #-} - setBit (Natural n) = Natural . setBit n - {-# INLINE setBit #-} - clearBit (Natural n) = Natural . clearBit n - {-# INLINE clearBit #-} - complementBit (Natural n) = Natural . complementBit n - {-# INLINE complementBit #-} - testBit (Natural n) = testBit n - {-# INLINE testBit #-} - bitSizeMaybe _ = Nothing - {-# INLINE bitSizeMaybe #-} - bitSize = errorWithoutStackTrace "Natural: bitSize" - {-# INLINE bitSize #-} - isSigned _ = False - {-# INLINE isSigned #-} - shiftL (Natural n) = Natural . shiftL n - {-# INLINE shiftL #-} - shiftR (Natural n) = Natural . shiftR n - {-# INLINE shiftR #-} - rotateL (Natural n) = Natural . rotateL n - {-# INLINE rotateL #-} - rotateR (Natural n) = Natural . rotateR n - {-# INLINE rotateR #-} - popCount (Natural n) = popCount n - {-# INLINE popCount #-} - zeroBits = Natural 0 - -#endif ----------------------------------------------------------------------------- diff --git a/libraries/base/GHC/Enum.hs b/libraries/base/GHC/Enum.hs index 18850acd7d..bf85ca0bbb 100644 --- a/libraries/base/GHC/Enum.hs +++ b/libraries/base/GHC/Enum.hs @@ -919,7 +919,6 @@ dn_list x0 delta lim = go (x0 :: Integer) -- Natural ------------------------------------------------------------------------ -#if defined(MIN_VERSION_integer_gmp) -- | @since 4.8.0.0 instance Enum Natural where succ n = n `plusNatural` wordToNaturalBase 1## @@ -927,11 +926,13 @@ instance Enum Natural where toEnum = intToNatural +#if defined(MIN_VERSION_integer_gmp) fromEnum (NatS# w) | i >= 0 = i | otherwise = errorWithoutStackTrace "fromEnum: out of Int range" where i = I# (word2Int# w) +#endif fromEnum n = fromEnum (naturalToInteger n) enumFrom x = enumDeltaNatural x (wordToNaturalBase 1##) @@ -962,31 +963,6 @@ enumNegDeltaToNatural x0 ndelta lim = go x0 | x >= ndelta = x : go (x-ndelta) | otherwise = [x] -#else - --- | @since 4.8.0.0 -instance Enum Natural where - pred (Natural 0) = errorWithoutStackTrace "Natural.pred: 0" - pred (Natural n) = Natural (pred n) - {-# INLINE pred #-} - succ (Natural n) = Natural (succ n) - {-# INLINE succ #-} - fromEnum (Natural n) = fromEnum n - {-# INLINE fromEnum #-} - toEnum n | n < 0 = errorWithoutStackTrace "Natural.toEnum: negative" - | otherwise = Natural (toEnum n) - {-# INLINE toEnum #-} - - enumFrom = coerce (enumFrom :: Integer -> [Integer]) - enumFromThen x y - | x <= y = coerce (enumFromThen :: Integer -> Integer -> [Integer]) x y - | otherwise = enumFromThenTo x y (wordToNaturalBase 0##) - - enumFromTo = coerce (enumFromTo :: Integer -> Integer -> [Integer]) - enumFromThenTo - = coerce (enumFromThenTo :: Integer -> Integer -> Integer -> [Integer]) - -#endif -- Instances from GHC.Types diff --git a/libraries/base/GHC/Natural.hs b/libraries/base/GHC/Natural.hs index 2cc255e807..fef76df43b 100644 --- a/libraries/base/GHC/Natural.hs +++ b/libraries/base/GHC/Natural.hs @@ -42,19 +42,15 @@ module GHC.Natural , quotRemNatural , quotNatural , remNatural -#if defined(MIN_VERSION_integer_gmp) , gcdNatural , lcmNatural -#endif -- * Bits , andNatural , orNatural , xorNatural , bitNatural , testBitNatural -#if defined(MIN_VERSION_integer_gmp) , popCountNatural -#endif , shiftLNatural , shiftRNatural -- * Conversions @@ -439,6 +435,15 @@ naturalFromInteger n | True = underflowError {-# INLINE naturalFromInteger #-} + +-- | Compute greatest common divisor. +gcdNatural :: Natural -> Natural -> Natural +gcdNatural (Natural n) (Natural m) = Natural (n `gcdInteger` m) + +-- | Compute lowest common multiple. +lcmNatural :: Natural -> Natural -> Natural +lcmNatural (Natural n) (Natural m) = Natural (n `lcmInteger` m) + -- | 'Natural' subtraction. Returns 'Nothing's for non-positive results. -- -- @since 4.8.0.0 @@ -460,7 +465,9 @@ plusNatural (Natural x) (Natural y) = Natural (x `plusInteger` y) {-# CONSTANT_FOLDED plusNatural #-} minusNatural :: Natural -> Natural -> Natural -minusNatural (Natural x) (Natural y) = Natural (x `minusInteger` y) +minusNatural (Natural x) (Natural y) + = if z `ltInteger` wordToInteger 0## then underflowError else Natural z + where z = x `minusInteger` y {-# CONSTANT_FOLDED minusNatural #-} timesNatural :: Natural -> Natural -> Natural @@ -493,6 +500,9 @@ testBitNatural :: Natural -> Int -> Bool testBitNatural (Natural n) (I# i) = testBitInteger n i -- {-# CONSTANT_FOLDED testBitNatural #-} +popCountNatural :: Natural -> Int +popCountNatural (Natural n) = I# (popCountInteger n) + bitNatural :: Int# -> Natural bitNatural i# | isTrue# (i# <# WORD_SIZE_IN_BITS#) = wordToNaturalBase (1## `uncheckedShiftL#` i#) diff --git a/libraries/base/GHC/Num.hs b/libraries/base/GHC/Num.hs index 1bf16811e0..023ccb3075 100644 --- a/libraries/base/GHC/Num.hs +++ b/libraries/base/GHC/Num.hs @@ -24,9 +24,6 @@ module GHC.Num (module GHC.Num, module GHC.Integer, module GHC.Natural) where import GHC.Base import GHC.Integer import GHC.Natural -#if !defined(MIN_VERSION_integer_gmp) -import {-# SOURCE #-} GHC.Exception.Type (underflowException) -#endif infixl 7 * infixl 6 +, - @@ -125,7 +122,6 @@ instance Num Integer where abs = absInteger signum = signumInteger -#if defined(MIN_VERSION_integer_gmp) -- | Note that `Natural`'s 'Num' instance isn't a ring: no element but 0 has an -- additive inverse. It is a semiring though. -- @@ -140,25 +136,3 @@ instance Num Natural where abs = id signum = signumNatural -#else --- | Note that `Natural`'s 'Num' instance isn't a ring: no element but 0 has an --- additive inverse. It is a semiring though. --- --- @since 4.8.0.0 -instance Num Natural where - Natural n + Natural m = Natural (n + m) - {-# INLINE (+) #-} - Natural n * Natural m = Natural (n * m) - {-# INLINE (*) #-} - Natural n - Natural m - | m > n = raise# underflowException - | otherwise = Natural (n - m) - {-# INLINE (-) #-} - abs (Natural n) = Natural n - {-# INLINE abs #-} - signum (Natural n) = Natural (signum n) - {-# INLINE signum #-} - fromInteger = naturalFromInteger - {-# INLINE fromInteger #-} - -#endif diff --git a/libraries/base/GHC/Read.hs b/libraries/base/GHC/Read.hs index 26dca6ab65..2283942a8f 100644 --- a/libraries/base/GHC/Read.hs +++ b/libraries/base/GHC/Read.hs @@ -618,17 +618,10 @@ instance Read Integer where readList = readListDefault -#if defined(MIN_VERSION_integer_gmp) -- | @since 4.8.0.0 instance Read Natural where readsPrec d = map (\(n, s) -> (fromInteger n, s)) . filter ((>= 0) . (\(x,_)->x)) . readsPrec d -#else --- | @since 4.8.0.0 -instance Read Natural where - readsPrec d = map (\(n, s) -> (Natural n, s)) - . filter ((>= 0) . (\(x,_)->x)) . readsPrec d -#endif -- | @since 2.01 instance Read Float where diff --git a/libraries/base/GHC/Real.hs b/libraries/base/GHC/Real.hs index cb6e9e973e..2a9494f5b1 100644 --- a/libraries/base/GHC/Real.hs +++ b/libraries/base/GHC/Real.hs @@ -31,12 +31,8 @@ import {-# SOURCE #-} GHC.Exception( divZeroException, overflowException , underflowException , ratioZeroDenomException ) -#if defined(OPTIMISE_INTEGER_GCD_LCM) -# if defined(MIN_VERSION_integer_gmp) +#if defined(MIN_VERSION_integer_gmp) import GHC.Integer.GMP.Internals -# else -# error unsupported OPTIMISE_INTEGER_GCD_LCM configuration -# endif #endif infixr 8 ^, ^^ @@ -412,17 +408,9 @@ instance Integral Word where instance Real Integer where toRational x = x :% 1 -#if defined(MIN_VERSION_integer_gmp) --- | @since 4.8.0.0 -instance Real Natural where - toRational (NatS# w) = toRational (W# w) - toRational (NatJ# bn) = toRational (Jp# bn) -#else -- | @since 4.8.0.0 instance Real Natural where - toRational (Natural a) = toRational a - {-# INLINE toRational #-} -#endif + toRational n = naturalToInteger n :% 1 -- Note [Integer division constant folding] -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -466,7 +454,6 @@ instance Integral Integer where n `quotRem` d = case n `quotRemInteger` d of (# q, r #) -> (q, r) -#if defined(MIN_VERSION_integer_gmp) -- | @since 4.8.0.0 instance Integral Natural where toInteger = naturalToInteger @@ -478,30 +465,6 @@ instance Integral Natural where quotRem = quotRemNatural quot = quotNatural rem = remNatural -#else --- | @since 4.8.0.0 -instance Integral Natural where - {-# INLINE toInteger #-} - toInteger (Natural a) = a - - {-# INLINE quot #-} - Natural a `quot` Natural b = Natural (a `quot` b) - - {-# INLINE rem #-} - Natural a `rem` Natural b = Natural (a `rem` b) - - {-# INLINE div #-} - Natural a `div` Natural b = Natural (a `div` b) - - {-# INLINE mod #-} - Natural a `mod` Natural b = Natural (a `mod` b) - - {-# INLINE divMod #-} - Natural a `divMod` Natural b = coerce (a `divMod` b) - - {-# INLINE quotRem #-} - Natural a `quotRem` Natural b = coerce (a `quotRem` b) -#endif -------------------------------------------------------------- -- Instances for @Ratio@ @@ -789,24 +752,27 @@ lcm _ 0 = 0 lcm 0 _ = 0 lcm x y = abs ((x `quot` (gcd x y)) * y) -#if defined(OPTIMISE_INTEGER_GCD_LCM) {-# RULES -"gcd/Int->Int->Int" gcd = gcdInt' "gcd/Integer->Integer->Integer" gcd = gcdInteger "lcm/Integer->Integer->Integer" lcm = lcmInteger "gcd/Natural->Natural->Natural" gcd = gcdNatural "lcm/Natural->Natural->Natural" lcm = lcmNatural #-} +#if defined(MIN_VERSION_integer_gmp) +-- GMP defines a more efficient Int# and Word# GCD + gcdInt' :: Int -> Int -> Int gcdInt' (I# x) (I# y) = I# (gcdInt x y) +gcdWord' :: Word -> Word -> Word +gcdWord' (W# x) (W# y) = W# (gcdWord x y) + {-# RULES +"gcd/Int->Int->Int" gcd = gcdInt' "gcd/Word->Word->Word" gcd = gcdWord' #-} -gcdWord' :: Word -> Word -> Word -gcdWord' (W# x) (W# y) = W# (gcdWord x y) #endif integralEnumFrom :: (Integral a, Bounded a) => a -> [a] diff --git a/libraries/base/base.cabal b/libraries/base/base.cabal index f02ff0827c..4e809e70c7 100644 --- a/libraries/base/base.cabal +++ b/libraries/base/base.cabal @@ -106,7 +106,6 @@ Library if flag(integer-gmp) build-depends: integer-gmp ^>= 1.0.1 - cpp-options: -DOPTIMISE_INTEGER_GCD_LCM exposed-modules: Control.Applicative |