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/ghc-bignum | |
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/ghc-bignum')
-rw-r--r-- | libraries/ghc-bignum/src/GHC/Num/BigNat.hs | 64 | ||||
-rw-r--r-- | libraries/ghc-bignum/src/GHC/Num/Integer.hs | 14 | ||||
-rw-r--r-- | libraries/ghc-bignum/src/GHC/Num/Natural.hs | 162 | ||||
-rw-r--r-- | libraries/ghc-bignum/src/GHC/Num/Primitives.hs | 4 | ||||
-rw-r--r-- | libraries/ghc-bignum/src/GHC/Num/WordArray.hs | 4 |
5 files changed, 157 insertions, 91 deletions
diff --git a/libraries/ghc-bignum/src/GHC/Num/BigNat.hs b/libraries/ghc-bignum/src/GHC/Num/BigNat.hs index b0408bcfa6..bd3137a116 100644 --- a/libraries/ghc-bignum/src/GHC/Num/BigNat.hs +++ b/libraries/ghc-bignum/src/GHC/Num/BigNat.hs @@ -136,13 +136,13 @@ bigNatIsTwo# ba = &&# indexWordArray# ba 0# `eqWord#` 2## -- | Indicate if the value is a power of two and which one -bigNatIsPowerOf2# :: BigNat# -> (# () | Word# #) +bigNatIsPowerOf2# :: BigNat# -> (# (# #) | Word# #) bigNatIsPowerOf2# a - | bigNatIsZero a = (# () | #) + | bigNatIsZero a = (# (# #) | #) | True = case wordIsPowerOf2# msw of - (# () | #) -> (# () | #) + (# (# #) | #) -> (# (# #) | #) (# | c #) -> case checkAllZeroes (imax -# 1#) of - 0# -> (# () | #) + 0# -> (# (# #) | #) _ -> (# | c `plusWord#` (int2Word# imax `uncheckedShiftL#` WORD_SIZE_BITS_SHIFT#) #) where @@ -227,11 +227,11 @@ bigNatToWord# a | True = bigNatIndex# a 0# -- | Convert a BigNat into a Word# if it fits -bigNatToWordMaybe# :: BigNat# -> (# Word# | () #) +bigNatToWordMaybe# :: BigNat# -> (# (# #) | Word# #) bigNatToWordMaybe# a - | bigNatIsZero a = (# 0## | #) - | isTrue# (bigNatSize# a ># 1#) = (# | () #) - | True = (# bigNatIndex# a 0# | #) + | bigNatIsZero a = (# | 0## #) + | isTrue# (bigNatSize# a ># 1#) = (# (# #) | #) + | True = (# | bigNatIndex# a 0# #) -- | Convert a BigNat into a Word bigNatToWord :: BigNat# -> Word @@ -359,8 +359,44 @@ bigNatCompare a b = -- | Predicate: a < b +bigNatLt# :: BigNat# -> BigNat# -> Bool# +bigNatLt# a b + | LT <- bigNatCompare a b = 1# + | True = 0# + +-- | Predicate: a < b bigNatLt :: BigNat# -> BigNat# -> Bool -bigNatLt a b = bigNatCompare a b == LT +bigNatLt a b = isTrue# (bigNatLt# a b) + +-- | Predicate: a <= b +bigNatLe# :: BigNat# -> BigNat# -> Bool# +bigNatLe# a b + | GT <- bigNatCompare a b = 0# + | True = 1# + +-- | Predicate: a <= b +bigNatLe :: BigNat# -> BigNat# -> Bool +bigNatLe a b = isTrue# (bigNatLe# a b) + +-- | Predicate: a > b +bigNatGt# :: BigNat# -> BigNat# -> Bool# +bigNatGt# a b + | GT <- bigNatCompare a b = 1# + | True = 0# + +-- | Predicate: a > b +bigNatGt :: BigNat# -> BigNat# -> Bool +bigNatGt a b = isTrue# (bigNatGt# a b) + +-- | Predicate: a >= b +bigNatGe# :: BigNat# -> BigNat# -> Bool# +bigNatGe# a b + | LT <- bigNatCompare a b = 0# + | True = 1# + +-- | Predicate: a >= b +bigNatGe :: BigNat# -> BigNat# -> Bool +bigNatGe a b = isTrue# (bigNatGe# a b) ------------------------------------------------- -- Addition @@ -474,10 +510,10 @@ bigNatSubWordUnsafe :: BigNat# -> Word -> BigNat# bigNatSubWordUnsafe x (W# y) = bigNatSubWordUnsafe# x y -- | Subtract a Word# from a BigNat -bigNatSubWord# :: BigNat# -> Word# -> (# () | BigNat# #) +bigNatSubWord# :: BigNat# -> Word# -> (# (# #) | BigNat# #) bigNatSubWord# a b | 0## <- b = (# | a #) - | bigNatIsZero a = (# () | #) + | bigNatIsZero a = (# (# #) | #) | True = withNewWordArrayTrimedMaybe# (bigNatSize# a) \mwa s -> inline bignat_sub_word mwa a b s @@ -498,11 +534,11 @@ bigNatSubUnsafe a b -- GHC.Num.Primitives -- | Subtract two BigNat -bigNatSub :: BigNat# -> BigNat# -> (# () | BigNat# #) +bigNatSub :: BigNat# -> BigNat# -> (# (# #) | BigNat# #) bigNatSub a b | bigNatIsZero b = (# | a #) | isTrue# (bigNatSize# a <# bigNatSize# b) - = (# () | #) + = (# (# #) | #) | True = withNewWordArrayTrimedMaybe# (bigNatSize# a) \mwa s -> @@ -1136,7 +1172,7 @@ bigNatPowModWord# b e m -- exponent @/e/@ modulo @/m/@. bigNatPowMod :: BigNat# -> BigNat# -> BigNat# -> BigNat# bigNatPowMod !b !e !m - | (# m' | #) <- bigNatToWordMaybe# m + | (# | m' #) <- bigNatToWordMaybe# m = bigNatFromWord# (bigNatPowModWord# b e m') | bigNatIsZero m = raiseDivZero_BigNat (# #) | bigNatIsOne m = bigNatFromWord# 0## diff --git a/libraries/ghc-bignum/src/GHC/Num/Integer.hs b/libraries/ghc-bignum/src/GHC/Num/Integer.hs index 2e0327127d..35afa5d15a 100644 --- a/libraries/ghc-bignum/src/GHC/Num/Integer.hs +++ b/libraries/ghc-bignum/src/GHC/Num/Integer.hs @@ -205,7 +205,7 @@ integerFromWordList :: Bool -> [Word] -> Integer integerFromWordList True ws = integerFromBigNatNeg# (bigNatFromWordList ws) integerFromWordList False ws = integerFromBigNat# (bigNatFromWordList ws) --- | Convert a Integer into a Natural +-- | Convert an Integer into a Natural -- -- Return 0 for negative Integers. integerToNaturalClamp :: Integer -> Natural @@ -216,7 +216,7 @@ integerToNaturalClamp (IS x) integerToNaturalClamp (IP x) = naturalFromBigNat# x integerToNaturalClamp (IN _) = naturalZero --- | Convert a Integer into a Natural +-- | Convert an Integer into a Natural -- -- Return absolute value integerToNatural :: Integer -> Natural @@ -225,9 +225,9 @@ integerToNatural (IS x) = naturalFromWord# (wordFromAbsInt# x) integerToNatural (IP x) = naturalFromBigNat# x integerToNatural (IN x) = naturalFromBigNat# x --- | Convert a Integer into a Natural +-- | Convert an Integer into a Natural -- --- Throw on underflow +-- Throw an Underflow exception if input is negative. integerToNaturalThrow :: Integer -> Natural {-# NOINLINE integerToNaturalThrow #-} integerToNaturalThrow (IS x) @@ -1007,11 +1007,11 @@ integerLogBase :: Integer -> Integer -> Word integerLogBase !base !i = W# (integerLogBase# base i) -- | Indicate if the value is a power of two and which one -integerIsPowerOf2# :: Integer -> (# () | Word# #) +integerIsPowerOf2# :: Integer -> (# (# #) | Word# #) integerIsPowerOf2# (IS i) - | isTrue# (i <=# 0#) = (# () | #) + | isTrue# (i <=# 0#) = (# (# #) | #) | True = wordIsPowerOf2# (int2Word# i) -integerIsPowerOf2# (IN _) = (# () | #) +integerIsPowerOf2# (IN _) = (# (# #) | #) integerIsPowerOf2# (IP w) = bigNatIsPowerOf2# w #if WORD_SIZE_IN_BITS == 32 diff --git a/libraries/ghc-bignum/src/GHC/Num/Natural.hs b/libraries/ghc-bignum/src/GHC/Num/Natural.hs index d10a76165d..55aee2d2f7 100644 --- a/libraries/ghc-bignum/src/GHC/Num/Natural.hs +++ b/libraries/ghc-bignum/src/GHC/Num/Natural.hs @@ -32,6 +32,10 @@ instance Eq Natural where instance Ord Natural where compare = naturalCompare + (>) = naturalGt + (>=) = naturalGe + (<) = naturalLt + (<=) = naturalLe -- | Check Natural invariants @@ -62,7 +66,7 @@ naturalIsOne (NS 1##) = True naturalIsOne _ = False -- | Indicate if the value is a power of two and which one -naturalIsPowerOf2# :: Natural -> (# () | Word# #) +naturalIsPowerOf2# :: Natural -> (# (# #) | Word# #) naturalIsPowerOf2# (NS w) = wordIsPowerOf2# w naturalIsPowerOf2# (NB w) = bigNatIsPowerOf2# w @@ -80,7 +84,6 @@ naturalToBigNat# (NB bn) = bn -- | Create a Natural from a Word# naturalFromWord# :: Word# -> Natural -{-# NOINLINE naturalFromWord# #-} naturalFromWord# x = NS x -- | Convert two Word# (most-significant first) into a Natural @@ -109,6 +112,7 @@ naturalToWord !n = W# (naturalToWord# n) -- | Convert a Natural into a Word# clamping to (maxBound :: Word#). naturalToWordClamp# :: Natural -> Word# +{-# NOINLINE naturalToWordClamp #-} naturalToWordClamp# (NS x) = x naturalToWordClamp# (NB _) = WORD_MAXBOUND## @@ -117,58 +121,10 @@ naturalToWordClamp :: Natural -> Word naturalToWordClamp !n = W# (naturalToWordClamp# n) -- | Try downcasting 'Natural' to 'Word' value. --- Returns '()' if value doesn't fit in 'Word'. -naturalToWordMaybe# :: Natural -> (# Word# | () #) -naturalToWordMaybe# (NS w) = (# w | #) -naturalToWordMaybe# _ = (# | () #) - --- | Create a Natural from an Int# (unsafe: silently converts negative values --- into positive ones) -naturalFromIntUnsafe# :: Int# -> Natural -naturalFromIntUnsafe# !i = NS (int2Word# i) - --- | Create a Natural from an Int (unsafe: silently converts negative values --- into positive ones) -naturalFromIntUnsafe :: Int -> Natural -naturalFromIntUnsafe (I# i) = naturalFromIntUnsafe# i - --- | Create a Natural from an Int# --- --- Throws 'Control.Exception.Underflow' when passed a negative 'Int'. -naturalFromIntThrow# :: Int# -> Natural -naturalFromIntThrow# i - | isTrue# (i <# 0#) = raiseUnderflow - | True = naturalFromIntUnsafe# i - --- | Create a Natural from an Int --- --- Throws 'Control.Exception.Underflow' when passed a negative 'Int'. -naturalFromIntThrow :: Int -> Natural -naturalFromIntThrow (I# i) = naturalFromIntThrow# i - --- | Create an Int# from a Natural (can overflow the int and give a negative --- number) -naturalToInt# :: Natural -> Int# -naturalToInt# !n = word2Int# (naturalToWord# n) - --- | Create an Int# from a Natural (can overflow the int and give a negative --- number) -naturalToInt :: Natural -> Int -naturalToInt !n = I# (naturalToInt# n) - --- | Create a Natural from an Int# --- --- Underflow exception if Int# is negative -naturalFromInt# :: Int# -> Natural -naturalFromInt# !i - | isTrue# (i >=# 0#) = NS (int2Word# i) - | True = raiseUnderflow - --- | Create a Natural from an Int --- --- Underflow exception if Int# is negative -naturalFromInt :: Int -> Natural -naturalFromInt (I# i) = naturalFromInt# i +-- Returns '(##)' if value doesn't fit in 'Word'. +naturalToWordMaybe# :: Natural -> (# (# #) | Word# #) +naturalToWordMaybe# (NS w) = (# | w #) +naturalToWordMaybe# _ = (# (# #) | #) -- | Encode (# Natural mantissa, Int# exponent #) into a Double# naturalEncodeDouble# :: Natural -> Int# -> Double# @@ -180,7 +136,7 @@ naturalEncodeDouble# (NB b) e = bigNatEncodeDouble# b e naturalToDouble# :: Natural -> Double# naturalToDouble# !n = naturalEncodeDouble# n 0# --- | Encode an Natural (mantissa) into a Float# +-- | Encode a Natural (mantissa) into a Float# naturalToFloat# :: Natural -> Float# naturalToFloat# !i = naturalEncodeFloat# i 0# @@ -193,6 +149,7 @@ naturalEncodeFloat# !m e = double2Float# (naturalEncodeDouble# m e) -- | Equality test for Natural naturalEq# :: Natural -> Natural -> Bool# +{-# NOINLINE naturalEq# #-} naturalEq# (NS x) (NS y) = x `eqWord#` y naturalEq# (NB x) (NB y) = bigNatEq# x y naturalEq# _ _ = 0# @@ -203,6 +160,7 @@ naturalEq !x !y = isTrue# (naturalEq# x y) -- | Inequality test for Natural naturalNe# :: Natural -> Natural -> Bool# +{-# NOINLINE naturalNe# #-} naturalNe# (NS x) (NS y) = x `neWord#` y naturalNe# (NB x) (NB y) = bigNatNe# x y naturalNe# _ _ = 1# @@ -211,15 +169,66 @@ naturalNe# _ _ = 1# naturalNe :: Natural -> Natural -> Bool naturalNe !x !y = isTrue# (naturalNe# x y) +-- | Greater or equal test for Natural +naturalGe# :: Natural -> Natural -> Bool# +{-# NOINLINE naturalGe# #-} +naturalGe# (NS x) (NS y) = x `geWord#` y +naturalGe# (NS _) (NB _) = 0# +naturalGe# (NB _) (NS _) = 1# +naturalGe# (NB x) (NB y) = bigNatGe# x y + +-- | Greater or equal test for Natural +naturalGe :: Natural -> Natural -> Bool +naturalGe !x !y = isTrue# (naturalGe# x y) + +-- | Lower or equal test for Natural +naturalLe# :: Natural -> Natural -> Bool# +{-# NOINLINE naturalLe# #-} +naturalLe# (NS x) (NS y) = x `leWord#` y +naturalLe# (NS _) (NB _) = 1# +naturalLe# (NB _) (NS _) = 0# +naturalLe# (NB x) (NB y) = bigNatLe# x y + +-- | Lower or equal test for Natural +naturalLe :: Natural -> Natural -> Bool +naturalLe !x !y = isTrue# (naturalLe# x y) + + +-- | Greater test for Natural +naturalGt# :: Natural -> Natural -> Bool# +{-# NOINLINE naturalGt# #-} +naturalGt# (NS x) (NS y) = x `gtWord#` y +naturalGt# (NS _) (NB _) = 0# +naturalGt# (NB _) (NS _) = 1# +naturalGt# (NB x) (NB y) = bigNatGt# x y + +-- | Greater test for Natural +naturalGt :: Natural -> Natural -> Bool +naturalGt !x !y = isTrue# (naturalGt# x y) + +-- | Lower test for Natural +naturalLt# :: Natural -> Natural -> Bool# +{-# NOINLINE naturalLt# #-} +naturalLt# (NS x) (NS y) = x `ltWord#` y +naturalLt# (NS _) (NB _) = 1# +naturalLt# (NB _) (NS _) = 0# +naturalLt# (NB x) (NB y) = bigNatLt# x y + +-- | Lower test for Natural +naturalLt :: Natural -> Natural -> Bool +naturalLt !x !y = isTrue# (naturalLt# x y) + -- | Compare two Natural naturalCompare :: Natural -> Natural -> Ordering -naturalCompare (NS x) (NS y) = compare (W# x) (W# y) +{-# NOINLINE naturalCompare #-} +naturalCompare (NS x) (NS y) = cmpW# x y naturalCompare (NB x) (NB y) = bigNatCompare x y naturalCompare (NS _) (NB _) = LT naturalCompare (NB _) (NS _) = GT -- | PopCount for Natural naturalPopCount# :: Natural -> Word# +{-# NOINLINE naturalPopCount# #-} naturalPopCount# (NS x) = popCnt# x naturalPopCount# (NB x) = bigNatPopCount# x @@ -230,6 +239,7 @@ naturalPopCount (NB x) = bigNatPopCount x -- | Right shift for Natural naturalShiftR# :: Natural -> Word# -> Natural +{-# NOINLINE naturalShiftR# #-} naturalShiftR# (NS x) n = NS (x `shiftRW#` n) naturalShiftR# (NB x) n = naturalFromBigNat# (x `bigNatShiftR#` n) @@ -239,6 +249,7 @@ naturalShiftR x (W# n) = naturalShiftR# x n -- | Left shift naturalShiftL# :: Natural -> Word# -> Natural +{-# NOINLINE naturalShiftL# #-} naturalShiftL# v@(NS x) n | 0## <- x = v | isTrue# (clz# x `geWord#` n) = NS (x `uncheckedShiftL#` word2Int# n) @@ -261,23 +272,24 @@ naturalAdd (NS x) (NS y) = (# l,c #) -> NB (bigNatFromWord2# (int2Word# c) l) -- | Sub two naturals -naturalSub :: Natural -> Natural -> (# () | Natural #) +naturalSub :: Natural -> Natural -> (# (# #) | Natural #) {-# NOINLINE naturalSub #-} -naturalSub (NS _) (NB _) = (# () | #) +naturalSub (NS _) (NB _) = (# (# #) | #) naturalSub (NB x) (NS y) = (# | naturalFromBigNat# (bigNatSubWordUnsafe# x y) #) naturalSub (NS x) (NS y) = case subWordC# x y of - (# l,0# #) -> (# | NS l #) - (# _,_ #) -> (# () | #) + (# l,0# #) -> (# | NS l #) + (# _,_ #) -> (# (# #) | #) naturalSub (NB x) (NB y) = case bigNatSub x y of - (# () | #) -> (# () | #) - (# | z #) -> (# | naturalFromBigNat# z #) + (# (# #) | #) -> (# (# #) | #) + (# | z #) -> (# | naturalFromBigNat# z #) -- | Sub two naturals -- -- Throw an Underflow exception if x < y naturalSubThrow :: Natural -> Natural -> Natural +{-# NOINLINE naturalSubThrow #-} naturalSubThrow (NS _) (NB _) = raiseUnderflow naturalSubThrow (NB x) (NS y) = naturalFromBigNat# (bigNatSubWordUnsafe# x y) naturalSubThrow (NS x) (NS y) = @@ -286,8 +298,8 @@ naturalSubThrow (NS x) (NS y) = (# _,_ #) -> raiseUnderflow naturalSubThrow (NB x) (NB y) = case bigNatSub x y of - (# () | #) -> raiseUnderflow - (# | z #) -> naturalFromBigNat# z + (# (# #) | #) -> raiseUnderflow + (# | z #) -> naturalFromBigNat# z -- | Sub two naturals -- @@ -300,8 +312,8 @@ naturalSubUnsafe (NS _) (NB _) = naturalZero naturalSubUnsafe (NB x) (NS y) = naturalFromBigNat# (bigNatSubWordUnsafe# x y) naturalSubUnsafe (NB x) (NB y) = case bigNatSub x y of - (# () | #) -> naturalZero - (# | z #) -> naturalFromBigNat# z + (# (# #) | #) -> naturalZero + (# | z #) -> naturalFromBigNat# z -- | Multiplication naturalMul :: Natural -> Natural -> Natural @@ -327,6 +339,7 @@ naturalSqr !a = naturalMul a a -- | Signum for Natural naturalSignum :: Natural -> Natural +{-# NOINLINE naturalSignum #-} naturalSignum (NS 0##) = NS 0## naturalSignum _ = NS 1## @@ -380,30 +393,35 @@ naturalRem (NB n) (NB d) = case bigNatRem n d of r -> naturalFromBigNat# r naturalAnd :: Natural -> Natural -> Natural +{-# NOINLINE naturalAnd #-} naturalAnd (NS n) (NS m) = NS (n `and#` m) naturalAnd (NS n) (NB m) = NS (n `and#` bigNatToWord# m) naturalAnd (NB n) (NS m) = NS (bigNatToWord# n `and#` m) naturalAnd (NB n) (NB m) = naturalFromBigNat# (bigNatAnd n m) naturalAndNot :: Natural -> Natural -> Natural +{-# NOINLINE naturalAndNot #-} naturalAndNot (NS n) (NS m) = NS (n `and#` not# m) naturalAndNot (NS n) (NB m) = NS (n `and#` not# (bigNatToWord# m)) naturalAndNot (NB n) (NS m) = NS (bigNatToWord# n `and#` not# m) naturalAndNot (NB n) (NB m) = naturalFromBigNat# (bigNatAndNot n m) naturalOr :: Natural -> Natural -> Natural +{-# NOINLINE naturalOr #-} naturalOr (NS n) (NS m) = NS (n `or#` m) naturalOr (NS n) (NB m) = NB (bigNatOrWord# m n) naturalOr (NB n) (NS m) = NB (bigNatOrWord# n m) naturalOr (NB n) (NB m) = NB (bigNatOr n m) naturalXor :: Natural -> Natural -> Natural +{-# NOINLINE naturalXor #-} naturalXor (NS n) (NS m) = NS (n `xor#` m) naturalXor (NS n) (NB m) = NB (bigNatXorWord# m n) naturalXor (NB n) (NS m) = NB (bigNatXorWord# n m) naturalXor (NB n) (NB m) = naturalFromBigNat# (bigNatXor n m) naturalTestBit# :: Natural -> Word# -> Bool# +{-# NOINLINE naturalTestBit# #-} naturalTestBit# (NS w) i = (i `ltWord#` WORD_SIZE_IN_BITS##) &&# ((w `and#` (1## `uncheckedShiftL#` word2Int# i)) `neWord#` 0##) naturalTestBit# (NB bn) i = bigNatTestBit# bn i @@ -412,6 +430,7 @@ naturalTestBit :: Natural -> Word -> Bool naturalTestBit !n (W# i) = isTrue# (naturalTestBit# n i) naturalBit# :: Word# -> Natural +{-# NOINLINE naturalBit# #-} naturalBit# i | isTrue# (i `ltWord#` WORD_SIZE_IN_BITS##) = NS (1## `uncheckedShiftL#` word2Int# i) | True = NB (bigNatBit# i) @@ -421,6 +440,7 @@ naturalBit (W# i) = naturalBit# i -- | Compute greatest common divisor. naturalGcd :: Natural -> Natural -> Natural +{-# NOINLINE naturalGcd #-} naturalGcd (NS 0##) !y = y naturalGcd x (NS 0##) = x naturalGcd (NS 1##) _ = NS 1## @@ -432,6 +452,7 @@ naturalGcd (NS x) (NS y) = NS (gcdWord# x y) -- | Compute least common multiple. naturalLcm :: Natural -> Natural -> Natural +{-# NOINLINE naturalLcm #-} naturalLcm (NS 0##) !_ = NS 0## naturalLcm _ (NS 0##) = NS 0## naturalLcm (NS 1##) y = y @@ -443,6 +464,7 @@ naturalLcm (NB a ) (NB b ) = naturalFromBigNat# (bigNatLcm a b) -- | Base 2 logarithm naturalLog2# :: Natural -> Word# +{-# NOINLINE naturalLog2# #-} naturalLog2# (NS w) = wordLog2# w naturalLog2# (NB b) = bigNatLog2# b @@ -452,6 +474,7 @@ naturalLog2 !n = W# (naturalLog2# n) -- | Logarithm for an arbitrary base naturalLogBaseWord# :: Word# -> Natural -> Word# +{-# NOINLINE naturalLogBaseWord# #-} naturalLogBaseWord# base (NS a) = wordLogBase# base a naturalLogBaseWord# base (NB a) = bigNatLogBaseWord# base a @@ -461,6 +484,7 @@ naturalLogBaseWord (W# base) !a = W# (naturalLogBaseWord# base a) -- | Logarithm for an arbitrary base naturalLogBase# :: Natural -> Natural -> Word# +{-# NOINLINE naturalLogBase# #-} naturalLogBase# (NS base) !a = naturalLogBaseWord# base a naturalLogBase# (NB _ ) (NS _) = 0## naturalLogBase# (NB base) (NB a) = bigNatLogBase# base a @@ -472,6 +496,7 @@ naturalLogBase !base !a = W# (naturalLogBase# base a) -- | \"@'naturalPowMod' /b/ /e/ /m/@\" computes base @/b/@ raised to -- exponent @/e/@ modulo @/m/@. naturalPowMod :: Natural -> Natural -> Natural -> Natural +{-# NOINLINE naturalPowMod #-} naturalPowMod !_ !_ (NS 0##) = raiseDivZero naturalPowMod _ _ (NS 1##) = NS 0## naturalPowMod _ (NS 0##) _ = NS 1## @@ -491,6 +516,7 @@ naturalPowMod b e (NB m) = naturalFromBigNat# -- -- `base` must be > 1 naturalSizeInBase# :: Word# -> Natural -> Word# +{-# NOINLINE naturalSizeInBase# #-} naturalSizeInBase# base (NS w) = wordSizeInBase# base w naturalSizeInBase# base (NB n) = bigNatSizeInBase# base n @@ -501,6 +527,7 @@ naturalSizeInBase# base (NB n) = bigNatSizeInBase# base n -- byte first (big-endian) if @1#@ or least significant byte first -- (little-endian) if @0#@. naturalToAddr# :: Natural -> Addr# -> Bool# -> State# s -> (# State# s, Word# #) +{-# NOINLINE naturalToAddr# #-} naturalToAddr# (NS i) = wordToAddr# i naturalToAddr# (NB n) = bigNatToAddr# n @@ -525,6 +552,7 @@ naturalToAddr a addr e = IO \s -> case naturalToAddr# a addr e s of -- -- Null higher limbs are automatically trimed. naturalFromAddr# :: Word# -> Addr# -> Bool# -> State# s -> (# State# s, Natural #) +{-# NOINLINE naturalFromAddr# #-} naturalFromAddr# sz addr e s = case bigNatFromAddr# sz addr e s of (# s', n #) -> (# s', naturalFromBigNat# n #) @@ -549,6 +577,7 @@ naturalFromAddr sz addr e = IO (naturalFromAddr# sz addr e) -- byte first (big-endian) if @1#@ or least significant byte first -- (little-endian) if @0#@. naturalToMutableByteArray# :: Natural -> MutableByteArray# s -> Word# -> Bool# -> State# s -> (# State# s, Word# #) +{-# NOINLINE naturalToMutableByteArray# #-} naturalToMutableByteArray# (NS w) = wordToMutableByteArray# w naturalToMutableByteArray# (NB a) = bigNatToMutableByteArray# a @@ -562,5 +591,6 @@ naturalToMutableByteArray# (NB a) = bigNatToMutableByteArray# a -- -- Null higher limbs are automatically trimed. naturalFromByteArray# :: Word# -> ByteArray# -> Word# -> Bool# -> State# s -> (# State# s, Natural #) +{-# NOINLINE naturalFromByteArray# #-} naturalFromByteArray# sz ba off e s = case bigNatFromByteArray# sz ba off e s of (# s', a #) -> (# s', naturalFromBigNat# a #) diff --git a/libraries/ghc-bignum/src/GHC/Num/Primitives.hs b/libraries/ghc-bignum/src/GHC/Num/Primitives.hs index 033262b229..589600e047 100644 --- a/libraries/ghc-bignum/src/GHC/Num/Primitives.hs +++ b/libraries/ghc-bignum/src/GHC/Num/Primitives.hs @@ -271,9 +271,9 @@ wordSizeInBase# _ 0## = 0## wordSizeInBase# base w = 1## `plusWord#` wordLogBase# base w -- | Indicate if the value is a power of two and which one -wordIsPowerOf2# :: Word# -> (# () | Word# #) +wordIsPowerOf2# :: Word# -> (# (# #) | Word# #) wordIsPowerOf2# w - | isTrue# (popCnt# w `neWord#` 1##) = (# () | #) + | isTrue# (popCnt# w `neWord#` 1##) = (# (# #) | #) | True = (# | ctz# w #) -- | Reverse bytes in a Word# diff --git a/libraries/ghc-bignum/src/GHC/Num/WordArray.hs b/libraries/ghc-bignum/src/GHC/Num/WordArray.hs index dffb7e5797..d4ada9bb3b 100644 --- a/libraries/ghc-bignum/src/GHC/Num/WordArray.hs +++ b/libraries/ghc-bignum/src/GHC/Num/WordArray.hs @@ -108,13 +108,13 @@ withNewWordArray2Trimed# sz1 sz2 act = withNewWordArray2# sz1 sz2 \mwa1 mwa2 s - withNewWordArrayTrimedMaybe# :: Int# -- ^ Size in Word -> (MutableWordArray# RealWorld -> State# RealWorld -> (# State# RealWorld, Bool# #)) - -> (# () | WordArray# #) + -> (# (# #) | WordArray# #) withNewWordArrayTrimedMaybe# sz act = case runRW# io of (# _, a #) -> a where io s = case newWordArray# sz s of (# s, mwa #) -> case act mwa s of - (# s, 0# #) -> (# s, (# () | #) #) + (# s, 0# #) -> (# s, (# (# #) | #) #) (# s, _ #) -> case mwaTrimZeroes# mwa s of s -> case unsafeFreezeByteArray# mwa s of (# s, ba #) -> (# s, (# | ba #) #) |