diff options
author | Sylvain Henry <sylvain@haskus.fr> | 2021-10-20 11:39:16 +0200 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2021-11-06 07:53:42 -0400 |
commit | 20956e5784fe43781d156dd7ab02f0bff4ab41fb (patch) | |
tree | de4776b5223cc3e6c983bd4eec28cbef4f973a8f /libraries | |
parent | 646c3e21dd30a2eaae46aafb8678d29f8e06054d (diff) | |
download | haskell-20956e5784fe43781d156dd7ab02f0bff4ab41fb.tar.gz |
Remove target dependent CPP for Word64/Int64 (#11470)
Primops types were dependent on the target word-size at *compiler*
compilation time. It's an issue for multi-target as GHC may not have the
correct primops types for the target.
This patch fixes some primops types: if they take or return fixed 64-bit
values they now always use `Int64#/Word64#`, even on 64-bit
architectures (where they used `Int#/Word#` before). Users of these
primops may now need to convert from Int64#/Word64# to Int#/Word# (a
no-op at runtime).
This is a stripped down version of !3658 which goes the all way of
changing the underlying primitive types of Word64/Int64. This is left
for future work.
T12545 allocations increase ~4% on some CI platforms and decrease ~3% on
AArch64.
Metric Increase:
T12545
Metric Decrease:
T12545
Diffstat (limited to 'libraries')
-rw-r--r-- | libraries/base/GHC/Conc/Sync.hs | 6 | ||||
-rw-r--r-- | libraries/base/GHC/Int.hs | 10 | ||||
-rw-r--r-- | libraries/base/GHC/Storable.hs | 17 | ||||
-rw-r--r-- | libraries/base/GHC/Word.hs | 22 | ||||
-rw-r--r-- | libraries/ghc-bignum/src/GHC/Num/BigNat.hs | 10 | ||||
-rw-r--r-- | libraries/ghc-bignum/src/GHC/Num/Integer.hs | 24 |
6 files changed, 53 insertions, 36 deletions
diff --git a/libraries/base/GHC/Conc/Sync.hs b/libraries/base/GHC/Conc/Sync.hs index d5fb4868df..38ce56ccbf 100644 --- a/libraries/base/GHC/Conc/Sync.hs +++ b/libraries/base/GHC/Conc/Sync.hs @@ -92,6 +92,8 @@ module GHC.Conc.Sync , sharedCAF ) where +#include "MachDeps.h" + import Foreign import Foreign.C @@ -192,7 +194,11 @@ instance Ord ThreadId where -- @since 4.8.0.0 setAllocationCounter :: Int64 -> IO () setAllocationCounter (I64# i) = IO $ \s -> +#if WORD_SIZE_IN_BITS < 64 case setThreadAllocationCounter# i s of s' -> (# s', () #) +#else + case setThreadAllocationCounter# (intToInt64# i) s of s' -> (# s', () #) +#endif -- | Return the current value of the allocation counter for the -- current thread. diff --git a/libraries/base/GHC/Int.hs b/libraries/base/GHC/Int.hs index df25e1cbe4..45bb3f70ca 100644 --- a/libraries/base/GHC/Int.hs +++ b/libraries/base/GHC/Int.hs @@ -1048,7 +1048,11 @@ instance Bits Int64 where bitSizeMaybe i = Just (finiteBitSize i) bitSize i = finiteBitSize i isSigned _ = True - popCount (I64# x#) = I# (word2Int# (popCnt64# (int2Word# x#))) +#if WORD_SIZE_IN_BITS < 64 + popCount (I64# x#) = I# (word2Int# (popCnt64# (int64ToWord64# x#))) +#else + popCount (I64# x#) = I# (word2Int# (popCnt# (int2Word# x#))) +#endif bit = bitDefault testBit = testBitDefault @@ -1098,8 +1102,8 @@ instance FiniteBits Int64 where countLeadingZeros (I64# x#) = I# (word2Int# (clz64# (int64ToWord64# x#))) countTrailingZeros (I64# x#) = I# (word2Int# (ctz64# (int64ToWord64# x#))) #else - countLeadingZeros (I64# x#) = I# (word2Int# (clz64# (int2Word# x#))) - countTrailingZeros (I64# x#) = I# (word2Int# (ctz64# (int2Word# x#))) + countLeadingZeros (I64# x#) = I# (word2Int# (clz# (int2Word# x#))) + countTrailingZeros (I64# x#) = I# (word2Int# (ctz# (int2Word# x#))) #endif -- | @since 2.01 diff --git a/libraries/base/GHC/Storable.hs b/libraries/base/GHC/Storable.hs index d9b9382211..548430eb59 100644 --- a/libraries/base/GHC/Storable.hs +++ b/libraries/base/GHC/Storable.hs @@ -1,3 +1,4 @@ +{-# LANGUAGE CPP #-} {-# LANGUAGE Trustworthy #-} {-# LANGUAGE NoImplicitPrelude, MagicHash, UnboxedTuples #-} {-# OPTIONS_HADDOCK not-home #-} @@ -51,6 +52,8 @@ module GHC.Storable , writeWord64OffPtr ) where +#include "MachDeps.h" + import GHC.Stable ( StablePtr(..) ) import GHC.Int import GHC.Word @@ -102,10 +105,17 @@ readInt32OffPtr (Ptr a) (I# i) = IO $ \s -> case readInt32OffAddr# a i s of (# s2, x #) -> (# s2, I32# x #) readWord32OffPtr (Ptr a) (I# i) = IO $ \s -> case readWord32OffAddr# a i s of (# s2, x #) -> (# s2, W32# x #) +#if WORD_SIZE_IN_BITS < 64 readInt64OffPtr (Ptr a) (I# i) = IO $ \s -> case readInt64OffAddr# a i s of (# s2, x #) -> (# s2, I64# x #) readWord64OffPtr (Ptr a) (I# i) = IO $ \s -> case readWord64OffAddr# a i s of (# s2, x #) -> (# s2, W64# x #) +#else +readInt64OffPtr (Ptr a) (I# i) + = IO $ \s -> case readInt64OffAddr# a i s of (# s2, x #) -> (# s2, I64# (int64ToInt# x) #) +readWord64OffPtr (Ptr a) (I# i) + = IO $ \s -> case readWord64OffAddr# a i s of (# s2, x #) -> (# s2, W64# (word64ToWord# x) #) +#endif writeWideCharOffPtr :: Ptr Char -> Int -> Char -> IO () writeIntOffPtr :: Ptr Int -> Int -> Int -> IO () @@ -152,7 +162,14 @@ writeInt32OffPtr (Ptr a) (I# i) (I32# x) = IO $ \s -> case writeInt32OffAddr# a i x s of s2 -> (# s2, () #) writeWord32OffPtr (Ptr a) (I# i) (W32# x) = IO $ \s -> case writeWord32OffAddr# a i x s of s2 -> (# s2, () #) +#if WORD_SIZE_IN_BITS < 64 writeInt64OffPtr (Ptr a) (I# i) (I64# x) = IO $ \s -> case writeInt64OffAddr# a i x s of s2 -> (# s2, () #) writeWord64OffPtr (Ptr a) (I# i) (W64# x) = IO $ \s -> case writeWord64OffAddr# a i x s of s2 -> (# s2, () #) +#else +writeInt64OffPtr (Ptr a) (I# i) (I64# x) + = IO $ \s -> case writeInt64OffAddr# a i (intToInt64# x) s of s2 -> (# s2, () #) +writeWord64OffPtr (Ptr a) (I# i) (W64# x) + = IO $ \s -> case writeWord64OffAddr# a i (wordToWord64# x) s of s2 -> (# s2, () #) +#endif diff --git a/libraries/base/GHC/Word.hs b/libraries/base/GHC/Word.hs index be44bfd541..43b6e4b311 100644 --- a/libraries/base/GHC/Word.hs +++ b/libraries/base/GHC/Word.hs @@ -888,20 +888,6 @@ instance Enum Word64 where = I# (word2Int# x#) | otherwise = fromEnumError "Word64" x -#if WORD_SIZE_IN_BITS < 64 - -- See Note [Stable Unfolding for list producers] in GHC.Enum - {-# INLINE enumFrom #-} - enumFrom = integralEnumFrom - -- See Note [Stable Unfolding for list producers] in GHC.Enum - {-# INLINE enumFromThen #-} - enumFromThen = integralEnumFromThen - -- See Note [Stable Unfolding for list producers] in GHC.Enum - {-# INLINE enumFromTo #-} - enumFromTo = integralEnumFromTo - -- See Note [Stable Unfolding for list producers] in GHC.Enum - {-# INLINE enumFromThenTo #-} - enumFromThenTo = integralEnumFromThenTo -#else -- See Note [Stable Unfolding for list producers] in GHC.Enum {-# INLINABLE enumFrom #-} enumFrom w @@ -931,7 +917,6 @@ word64ToWord (W64# w#) = (W# w#) wordToWord64 :: Word -> Word64 wordToWord64 (W# w#) = (W64# w#) -#endif -- | @since 2.01 @@ -992,7 +977,7 @@ instance Bits Word64 where bitSizeMaybe i = Just (finiteBitSize i) bitSize i = finiteBitSize i isSigned _ = False - popCount (W64# x#) = I# (word2Int# (popCnt64# x#)) + popCount (W64# x#) = I# (word2Int# (popCnt# x#)) bit = bitDefault testBit = testBitDefault @@ -1009,8 +994,13 @@ instance FiniteBits Word64 where {-# INLINE countLeadingZeros #-} {-# INLINE countTrailingZeros #-} finiteBitSize _ = 64 +#if WORD_SIZE_IN_BITS < 64 countLeadingZeros (W64# x#) = I# (word2Int# (clz64# x#)) countTrailingZeros (W64# x#) = I# (word2Int# (ctz64# x#)) +#else + countLeadingZeros (W64# x#) = I# (word2Int# (clz# x#)) + countTrailingZeros (W64# x#) = I# (word2Int# (ctz# x#)) +#endif -- | @since 2.01 instance Show Word64 where diff --git a/libraries/ghc-bignum/src/GHC/Num/BigNat.hs b/libraries/ghc-bignum/src/GHC/Num/BigNat.hs index fa8b84eccd..5fa81b7e5b 100644 --- a/libraries/ghc-bignum/src/GHC/Num/BigNat.hs +++ b/libraries/ghc-bignum/src/GHC/Num/BigNat.hs @@ -263,6 +263,16 @@ bigNatToWord64# b in uncheckedShiftL64# wh 32# `or64#` wl else wl +#else + +-- | Convert a Word64# into a BigNat on 64-bit architectures +bigNatFromWord64# :: Word64# -> BigNat# +bigNatFromWord64# w64 = bigNatFromWord# (word64ToWord# w64) + +-- | Convert a BigNat into a Word64# on 64-bit architectures +bigNatToWord64# :: BigNat# -> Word64# +bigNatToWord64# b = wordToWord64# (bigNatToWord# b) + #endif -- | Encode (# BigNat mantissa, Int# exponent #) into a Double# diff --git a/libraries/ghc-bignum/src/GHC/Num/Integer.hs b/libraries/ghc-bignum/src/GHC/Num/Integer.hs index e2a020619e..d85148fc05 100644 --- a/libraries/ghc-bignum/src/GHC/Num/Integer.hs +++ b/libraries/ghc-bignum/src/GHC/Num/Integer.hs @@ -998,14 +998,12 @@ integerIsPowerOf2# (IS i) integerIsPowerOf2# (IN _) = (# (# #) | #) integerIsPowerOf2# (IP w) = bigNatIsPowerOf2# w -#if WORD_SIZE_IN_BITS == 32 - --- | Convert an Int64# into an Integer on 32-bit architectures +-- | Convert an Int64# into an Integer integerFromInt64# :: Int64# -> Integer {-# NOINLINE integerFromInt64# #-} integerFromInt64# !i - | isTrue# ((i `leInt64#` intToInt64# 0x7FFFFFFF#) - &&# (i `geInt64#` intToInt64# -0x80000000#)) + | isTrue# ((i `leInt64#` intToInt64# INT_MAXBOUND#) + &&# (i `geInt64#` intToInt64# INT_MINBOUND#)) = IS (int64ToInt# i) | isTrue# (i `geInt64#` intToInt64# 0#) @@ -1014,37 +1012,29 @@ integerFromInt64# !i | True = IN (bigNatFromWord64# (int64ToWord64# (negateInt64# i))) --- | Convert a Word64# into an Integer on 32-bit architectures +-- | Convert a Word64# into an Integer integerFromWord64# :: Word64# -> Integer {-# NOINLINE integerFromWord64# #-} integerFromWord64# !w - | isTrue# (w `leWord64#` wordToWord64# 0x7FFFFFFF##) + | isTrue# (w `leWord64#` wordToWord64# INT_MAXBOUND##) = IS (int64ToInt# (word64ToInt64# w)) | True = IP (bigNatFromWord64# w) --- | Convert an Integer into an Int64# on 32-bit architectures +-- | Convert an Integer into an Int64# integerToInt64# :: Integer -> Int64# {-# NOINLINE integerToInt64# #-} integerToInt64# (IS i) = intToInt64# i integerToInt64# (IP b) = word64ToInt64# (bigNatToWord64# b) integerToInt64# (IN b) = negateInt64# (word64ToInt64# (bigNatToWord64# b)) --- | Convert an Integer into a Word64# on 32-bit architectures +-- | Convert an Integer into a Word64# integerToWord64# :: Integer -> Word64# {-# NOINLINE integerToWord64# #-} integerToWord64# (IS i) = int64ToWord64# (intToInt64# i) integerToWord64# (IP b) = bigNatToWord64# b integerToWord64# (IN b) = int64ToWord64# (negateInt64# (word64ToInt64# (bigNatToWord64# b))) -#else - --- | Convert an Int64# into an Integer on 64-bit architectures -integerFromInt64# :: Int# -> Integer -integerFromInt64# !x = IS x - -#endif - ---------------------------------------------------------------------------- -- Conversions to/from floating point ---------------------------------------------------------------------------- |